1cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber/* 2cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * Copyright (C) 2011 The Android Open Source Project 3cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * 4cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * you may not use this file except in compliance with the License. 6cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * You may obtain a copy of the License at 7cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * 8cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * 10cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * Unless required by applicable law or agreed to in writing, software 11cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * See the License for the specific language governing permissions and 14cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber * limitations under the License. 15cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber */ 16cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 17cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber//#define LOG_NDEBUG 0 18cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#define LOG_TAG "AVIExtractor" 19cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <utils/Log.h> 20cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 213001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber#include "include/avc_utils.h" 22cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include "include/AVIExtractor.h" 23cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 24cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <binder/ProcessState.h> 25cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <media/stagefright/foundation/hexdump.h> 26cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 27cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <media/stagefright/foundation/ADebug.h> 28cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <media/stagefright/DataSource.h> 29cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <media/stagefright/MediaBuffer.h> 30cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <media/stagefright/MediaBufferGroup.h> 31cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <media/stagefright/MediaDefs.h> 32cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <media/stagefright/MediaErrors.h> 33cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <media/stagefright/MetaData.h> 34cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber#include <media/stagefright/Utils.h> 35cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 36cabb7da7125a80c55233bd23959327424e9646ccAndreas Hubernamespace android { 37cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 38cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstruct AVIExtractor::AVISource : public MediaSource { 39cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber AVISource(const sp<AVIExtractor> &extractor, size_t trackIndex); 40cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 41cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber virtual status_t start(MetaData *params); 42cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber virtual status_t stop(); 43cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 44cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber virtual sp<MetaData> getFormat(); 45cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 46cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber virtual status_t read( 47cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber MediaBuffer **buffer, const ReadOptions *options); 48cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 49cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberprotected: 50cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber virtual ~AVISource(); 51cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 52cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberprivate: 53cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber sp<AVIExtractor> mExtractor; 54cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t mTrackIndex; 55cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const AVIExtractor::Track &mTrack; 56cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber MediaBufferGroup *mBufferGroup; 57cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t mSampleIndex; 58cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 59bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber sp<MP3Splitter> mSplitter; 60bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 61cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(AVISource); 62cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber}; 63cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 64cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber//////////////////////////////////////////////////////////////////////////////// 65cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 66bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huberstruct AVIExtractor::MP3Splitter : public RefBase { 67bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber MP3Splitter(); 68bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 69bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber void clear(); 70bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber void append(MediaBuffer *buffer); 71bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber status_t read(MediaBuffer **buffer); 72bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 73bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huberprotected: 74bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber virtual ~MP3Splitter(); 75bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 76bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huberprivate: 77bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber bool mFindSync; 78bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber int64_t mBaseTimeUs; 79bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber int64_t mNumSamplesRead; 80bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber sp<ABuffer> mBuffer; 81bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 82bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber bool resync(); 83bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 84bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(MP3Splitter); 85bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber}; 86bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 87bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber//////////////////////////////////////////////////////////////////////////////// 88bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 89cabb7da7125a80c55233bd23959327424e9646ccAndreas HuberAVIExtractor::AVISource::AVISource( 90cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const sp<AVIExtractor> &extractor, size_t trackIndex) 91cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber : mExtractor(extractor), 92cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mTrackIndex(trackIndex), 93cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mTrack(mExtractor->mTracks.itemAt(trackIndex)), 94cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mBufferGroup(NULL) { 95cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 96cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 97cabb7da7125a80c55233bd23959327424e9646ccAndreas HuberAVIExtractor::AVISource::~AVISource() { 98cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (mBufferGroup) { 99cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber stop(); 100cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 101cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 102cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 103cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatus_t AVIExtractor::AVISource::start(MetaData *params) { 104cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber CHECK(!mBufferGroup); 105cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 106cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mBufferGroup = new MediaBufferGroup; 107cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 108cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize)); 109cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize)); 110cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mSampleIndex = 0; 111cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 112bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber const char *mime; 113bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber CHECK(mTrack.mMeta->findCString(kKeyMIMEType, &mime)); 114bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 115bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 116bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mSplitter = new MP3Splitter; 117bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } else { 118bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mSplitter.clear(); 119bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 120bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 121cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 122cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 123cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 124cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatus_t AVIExtractor::AVISource::stop() { 125cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber CHECK(mBufferGroup); 126cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 127cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber delete mBufferGroup; 128cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mBufferGroup = NULL; 129cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 130bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mSplitter.clear(); 131bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 132cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 133cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 134cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 135cabb7da7125a80c55233bd23959327424e9646ccAndreas Hubersp<MetaData> AVIExtractor::AVISource::getFormat() { 136cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return mTrack.mMeta; 137cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 138cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 139cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatus_t AVIExtractor::AVISource::read( 140cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber MediaBuffer **buffer, const ReadOptions *options) { 141cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber CHECK(mBufferGroup); 142cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 143cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *buffer = NULL; 144cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 145cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber int64_t seekTimeUs; 146cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ReadOptions::SeekMode seekMode; 147cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &seekMode)) { 148cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber status_t err = 149cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mExtractor->getSampleIndexAtTime( 150cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mTrackIndex, seekTimeUs, seekMode, &mSampleIndex); 151cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 152cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (err != OK) { 153cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_END_OF_STREAM; 154cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 155bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 156bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mSplitter != NULL) { 157bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mSplitter->clear(); 158bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 159cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 160cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 161bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber for (;;) { 162bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mSplitter != NULL) { 163bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber status_t err = mSplitter->read(buffer); 164cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 165bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (err == OK) { 166bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber break; 167bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } else if (err != -EAGAIN) { 168bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber return err; 169bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 170bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 171cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 172bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber off64_t offset; 173bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t size; 174bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber bool isKey; 175bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber int64_t timeUs; 176bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber status_t err = mExtractor->getSampleInfo( 177bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs); 178bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 179bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber ++mSampleIndex; 180bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 181bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (err != OK) { 182bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber return ERROR_END_OF_STREAM; 183bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 184bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 185bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber MediaBuffer *out; 186bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber CHECK_EQ(mBufferGroup->acquire_buffer(&out), (status_t)OK); 187bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 188bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber ssize_t n = mExtractor->mDataSource->readAt(offset, out->data(), size); 189bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 190bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (n < (ssize_t)size) { 191bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED; 192bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 193bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 194bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber out->set_range(0, size); 195bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 196bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber out->meta_data()->setInt64(kKeyTime, timeUs); 197bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 198bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (isKey) { 199bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber out->meta_data()->setInt32(kKeyIsSyncFrame, 1); 200bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 201bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 202bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mSplitter == NULL) { 203bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber *buffer = out; 204bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber break; 205bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 206bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 207bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mSplitter->append(out); 208bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber out->release(); 209bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber out = NULL; 210cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 211cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 212bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber return OK; 213bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber} 214cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 215bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber//////////////////////////////////////////////////////////////////////////////// 216cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 217bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas HuberAVIExtractor::MP3Splitter::MP3Splitter() 218bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber : mFindSync(true), 219bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mBaseTimeUs(-1ll), 220bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mNumSamplesRead(0) { 221bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber} 222bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 223bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas HuberAVIExtractor::MP3Splitter::~MP3Splitter() { 224bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber} 225bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 226bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Hubervoid AVIExtractor::MP3Splitter::clear() { 227bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mFindSync = true; 228bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mBaseTimeUs = -1ll; 229bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mNumSamplesRead = 0; 230bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 231bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mBuffer != NULL) { 232bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mBuffer->setRange(0, 0); 233cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 234bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber} 235cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 236bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Hubervoid AVIExtractor::MP3Splitter::append(MediaBuffer *buffer) { 237bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t prevCapacity = (mBuffer != NULL) ? mBuffer->capacity() : 0; 238cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 239bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mBaseTimeUs < 0) { 240bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber CHECK(mBuffer == NULL || mBuffer->size() == 0); 241bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, &mBaseTimeUs)); 242bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mNumSamplesRead = 0; 243bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 244cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 245bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mBuffer != NULL && mBuffer->offset() > 0) { 246bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber memmove(mBuffer->base(), mBuffer->data(), mBuffer->size()); 247bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mBuffer->setRange(0, mBuffer->size()); 248cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 249cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 250bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mBuffer == NULL 251bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber || mBuffer->size() + buffer->range_length() > prevCapacity) { 252bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t newCapacity = 253bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber (prevCapacity + buffer->range_length() + 1023) & ~1023; 254bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 255bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber sp<ABuffer> newBuffer = new ABuffer(newCapacity); 256bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mBuffer != NULL) { 257bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size()); 258bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber newBuffer->setRange(0, mBuffer->size()); 259bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } else { 260bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber newBuffer->setRange(0, 0); 261bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 262bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mBuffer = newBuffer; 263bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 264bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 265bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber memcpy(mBuffer->data() + mBuffer->size(), 266bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(), 267bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber buffer->range_length()); 268bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 269bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mBuffer->setRange(0, mBuffer->size() + buffer->range_length()); 270bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber} 271bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 272bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huberbool AVIExtractor::MP3Splitter::resync() { 273bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mBuffer == NULL) { 274bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber return false; 275bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 276bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 277bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber bool foundSync = false; 278bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber for (size_t offset = 0; offset + 3 < mBuffer->size(); ++offset) { 279bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber uint32_t firstHeader = U32_AT(mBuffer->data() + offset); 280bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 281bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t frameSize; 282bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (!GetMPEGAudioFrameSize(firstHeader, &frameSize)) { 283bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber continue; 284bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 285bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 286bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t subsequentOffset = offset + frameSize; 287bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t i = 3; 288bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber while (i > 0) { 289bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (subsequentOffset + 3 >= mBuffer->size()) { 290bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber break; 291bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 292bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 293bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber static const uint32_t kMask = 0xfffe0c00; 294bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 295bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber uint32_t header = U32_AT(mBuffer->data() + subsequentOffset); 296bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if ((header & kMask) != (firstHeader & kMask)) { 297bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber break; 298bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 299bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 300bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (!GetMPEGAudioFrameSize(header, &frameSize)) { 301bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber break; 302bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 303bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 304bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber subsequentOffset += frameSize; 305bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber --i; 306bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 307bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 308bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (i == 0) { 309bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber foundSync = true; 310bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber memmove(mBuffer->data(), 311bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mBuffer->data() + offset, 312bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mBuffer->size() - offset); 313bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 314bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mBuffer->setRange(0, mBuffer->size() - offset); 315bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber break; 316bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 317bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 318bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 319bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber return foundSync; 320bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber} 321bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 322bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huberstatus_t AVIExtractor::MP3Splitter::read(MediaBuffer **out) { 323bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber *out = NULL; 324bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 325bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mFindSync) { 326bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (!resync()) { 327bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber return -EAGAIN; 328bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 329bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 330bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mFindSync = false; 331bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 332bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 333bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mBuffer->size() < 4) { 334bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber return -EAGAIN; 335bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 336bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 337bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber uint32_t header = U32_AT(mBuffer->data()); 338bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t frameSize; 339bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber int sampleRate; 340bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber int numSamples; 341bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (!GetMPEGAudioFrameSize( 342bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber header, &frameSize, &sampleRate, NULL, NULL, &numSamples)) { 343bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber return ERROR_MALFORMED; 344bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 345bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 346bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (mBuffer->size() < frameSize) { 347bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber return -EAGAIN; 348bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 349bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 350bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber MediaBuffer *mbuf = new MediaBuffer(frameSize); 351bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber memcpy(mbuf->data(), mBuffer->data(), frameSize); 352bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 353bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber int64_t timeUs = mBaseTimeUs + (mNumSamplesRead * 1000000ll) / sampleRate; 354bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mNumSamplesRead += numSamples; 355bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 356bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mbuf->meta_data()->setInt64(kKeyTime, timeUs); 357bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 358bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mBuffer->setRange( 359bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber mBuffer->offset() + frameSize, mBuffer->size() - frameSize); 360bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 361bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber *out = mbuf; 362cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 363cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 364cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 365cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 366cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber//////////////////////////////////////////////////////////////////////////////// 367cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 368cabb7da7125a80c55233bd23959327424e9646ccAndreas HuberAVIExtractor::AVIExtractor(const sp<DataSource> &dataSource) 369cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber : mDataSource(dataSource) { 370cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mInitCheck = parseHeaders(); 371cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 372cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (mInitCheck != OK) { 373cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mTracks.clear(); 374cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 375cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 376cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 377cabb7da7125a80c55233bd23959327424e9646ccAndreas HuberAVIExtractor::~AVIExtractor() { 378cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 379cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 380cabb7da7125a80c55233bd23959327424e9646ccAndreas Hubersize_t AVIExtractor::countTracks() { 381cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return mTracks.size(); 382cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 383cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 384cabb7da7125a80c55233bd23959327424e9646ccAndreas Hubersp<MediaSource> AVIExtractor::getTrack(size_t index) { 385cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return index < mTracks.size() ? new AVISource(this, index) : NULL; 386cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 387cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 388cabb7da7125a80c55233bd23959327424e9646ccAndreas Hubersp<MetaData> AVIExtractor::getTrackMetaData( 389cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t index, uint32_t flags) { 390cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return index < mTracks.size() ? mTracks.editItemAt(index).mMeta : NULL; 391cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 392cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 393cabb7da7125a80c55233bd23959327424e9646ccAndreas Hubersp<MetaData> AVIExtractor::getMetaData() { 394cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber sp<MetaData> meta = new MetaData; 395cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 396cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (mInitCheck == OK) { 397cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_AVI); 398cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 399cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 400cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return meta; 401cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 402cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 403cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatus_t AVIExtractor::parseHeaders() { 404cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mTracks.clear(); 405cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mMovieOffset = 0; 406cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mFoundIndex = false; 407cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mOffsetsAreAbsolute = false; 408cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 409cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t res = parseChunk(0ll, -1ll); 410cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 411cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (res < 0) { 412cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return (status_t)res; 413cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 414cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 415cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (mMovieOffset == 0ll || !mFoundIndex) { 416cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 417cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 418cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 419cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 420cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 421cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 422cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberssize_t AVIExtractor::parseChunk(off64_t offset, off64_t size, int depth) { 423cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (size >= 0 && size < 8) { 424cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 425cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 426cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 427cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint8_t tmp[12]; 428cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t n = mDataSource->readAt(offset, tmp, 8); 429cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 430cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (n < 8) { 431cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return (n < 0) ? n : (ssize_t)ERROR_MALFORMED; 432cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 433cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 434cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t fourcc = U32_AT(tmp); 435cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t chunkSize = U32LE_AT(&tmp[4]); 436cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 437cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (size >= 0 && chunkSize + 8 > size) { 438cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 439cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 440cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 441cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber static const char kPrefix[] = " "; 442cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const char *prefix = &kPrefix[strlen(kPrefix) - 2 * depth]; 443cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 444cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (fourcc == FOURCC('L', 'I', 'S', 'T') 445cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber || fourcc == FOURCC('R', 'I', 'F', 'F')) { 446cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber // It's a list of chunks 447cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 448cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (size >= 0 && size < 12) { 449cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 450cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 451cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 452cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber n = mDataSource->readAt(offset + 8, &tmp[8], 4); 453cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 454cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (n < 4) { 455cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return (n < 0) ? n : (ssize_t)ERROR_MALFORMED; 456cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 457cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 458cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t subFourcc = U32_AT(&tmp[8]); 459cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 460cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber LOGV("%s offset 0x%08llx LIST of '%c%c%c%c', size %d", 461cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber prefix, 462cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber offset, 463cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber (char)(subFourcc >> 24), 464cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber (char)((subFourcc >> 16) & 0xff), 465cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber (char)((subFourcc >> 8) & 0xff), 466cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber (char)(subFourcc & 0xff), 467cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber chunkSize - 4); 468cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 469cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (subFourcc == FOURCC('m', 'o', 'v', 'i')) { 470cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber // We're not going to parse this, but will take note of the 471cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber // offset. 472cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 473cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mMovieOffset = offset; 474cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } else { 475cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber off64_t subOffset = offset + 12; 476cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber off64_t subOffsetLimit = subOffset + chunkSize - 4; 477cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber while (subOffset < subOffsetLimit) { 478cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t res = 479cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber parseChunk(subOffset, subOffsetLimit - subOffset, depth + 1); 480cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 481cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (res < 0) { 482cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return res; 483cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 484cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 485cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber subOffset += res; 486cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 487cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 488cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } else { 489cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber LOGV("%s offset 0x%08llx CHUNK '%c%c%c%c'", 490cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber prefix, 491cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber offset, 492cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber (char)(fourcc >> 24), 493cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber (char)((fourcc >> 16) & 0xff), 494cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber (char)((fourcc >> 8) & 0xff), 495cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber (char)(fourcc & 0xff)); 496cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 497cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber status_t err = OK; 498cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 499cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber switch (fourcc) { 500cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('s', 't', 'r', 'h'): 501cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber { 502cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber err = parseStreamHeader(offset + 8, chunkSize); 503cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber break; 504cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 505cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 506cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('s', 't', 'r', 'f'): 507cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber { 508cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber err = parseStreamFormat(offset + 8, chunkSize); 509cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber break; 510cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 511cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 512cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('i', 'd', 'x', '1'): 513cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber { 514cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber err = parseIndex(offset + 8, chunkSize); 515cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber break; 516cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 517cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 518cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber default: 519cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber break; 520cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 521cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 522cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (err != OK) { 523cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return err; 524cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 525cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 526cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 527cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (chunkSize & 1) { 528cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ++chunkSize; 529cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 530cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 531cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return chunkSize + 8; 532cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 533cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 534cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatic const char *GetMIMETypeForHandler(uint32_t handler) { 535cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber switch (handler) { 536cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber // Wow... shamelessly copied from 537cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber // http://wiki.multimedia.cx/index.php?title=ISO_MPEG-4 538cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 539cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('3', 'I', 'V', '2'): 540cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('3', 'i', 'v', '2'): 541cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('B', 'L', 'Z', '0'): 542cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('D', 'I', 'G', 'I'): 543cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('D', 'I', 'V', '1'): 544cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('d', 'i', 'v', '1'): 545cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('D', 'I', 'V', 'X'): 546cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('d', 'i', 'v', 'x'): 547cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('D', 'X', '5', '0'): 548cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('d', 'x', '5', '0'): 549cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('D', 'X', 'G', 'M'): 550cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('E', 'M', '4', 'A'): 551cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('E', 'P', 'H', 'V'): 552cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('F', 'M', 'P', '4'): 553cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('f', 'm', 'p', '4'): 554cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('F', 'V', 'F', 'W'): 555cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('H', 'D', 'X', '4'): 556cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('h', 'd', 'x', '4'): 557cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('M', '4', 'C', 'C'): 558cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('M', '4', 'S', '2'): 559cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('m', '4', 's', '2'): 560cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('M', 'P', '4', 'S'): 561cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('m', 'p', '4', 's'): 562cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('M', 'P', '4', 'V'): 563cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('m', 'p', '4', 'v'): 564cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('M', 'V', 'X', 'M'): 565cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('R', 'M', 'P', '4'): 566cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('S', 'E', 'D', 'G'): 567cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('S', 'M', 'P', '4'): 568cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('U', 'M', 'P', '4'): 569cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('W', 'V', '1', 'F'): 570cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('X', 'V', 'I', 'D'): 571cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('X', 'v', 'i', 'D'): 572cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('x', 'v', 'i', 'd'): 573cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case FOURCC('X', 'V', 'I', 'X'): 574cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 575cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 5763001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber // from http://wiki.multimedia.cx/index.php?title=H264 5773001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber case FOURCC('a', 'v', 'c', '1'): 5783001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber case FOURCC('d', 'a', 'v', 'c'): 5793001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber case FOURCC('x', '2', '6', '4'): 5803001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber case FOURCC('v', 's', 's', 'h'): 5813001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 5823001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 583cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber default: 584cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return NULL; 585cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 586cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 587cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 588cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatus_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) { 589cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (size != 56) { 590cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 591cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 592cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 593cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (mTracks.size() > 99) { 594cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return -ERANGE; 595cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 596cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 597cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber sp<ABuffer> buffer = new ABuffer(size); 598cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 599cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 600cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (n < (ssize_t)size) { 601cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 602cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 603cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 604cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const uint8_t *data = buffer->data(); 605cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 606cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t type = U32_AT(data); 607cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t handler = U32_AT(&data[4]); 608cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t flags = U32LE_AT(&data[8]); 609cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 610cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber sp<MetaData> meta = new MetaData; 611cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 612cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t rate = U32LE_AT(&data[20]); 613cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t scale = U32LE_AT(&data[24]); 614cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 61563749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber uint32_t sampleSize = U32LE_AT(&data[44]); 61663749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber 617cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const char *mime = NULL; 618cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber Track::Kind kind = Track::OTHER; 619cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 620cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (type == FOURCC('v', 'i', 'd', 's')) { 621cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mime = GetMIMETypeForHandler(handler); 622cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 623cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (mime && strncasecmp(mime, "video/", 6)) { 624cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 625cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 626cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 6273001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber if (mime == NULL) { 6283001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber LOGW("Unsupported video format '%c%c%c%c'", 6293001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber (char)(handler >> 24), 6303001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber (char)((handler >> 16) & 0xff), 6313001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber (char)((handler >> 8) & 0xff), 6323001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber (char)(handler & 0xff)); 6333001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber } 6343001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 635cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber kind = Track::VIDEO; 636cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } else if (type == FOURCC('a', 'u', 'd', 's')) { 637cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (mime && strncasecmp(mime, "audio/", 6)) { 638cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 639cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 640cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 641cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber kind = Track::AUDIO; 642cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 643cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 644cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (!mime) { 645cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mime = "application/octet-stream"; 646cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 647cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 648cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber meta->setCString(kKeyMIMEType, mime); 649cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 650cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mTracks.push(); 651cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber Track *track = &mTracks.editItemAt(mTracks.size() - 1); 652cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 653cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mMeta = meta; 654cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mRate = rate; 655cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mScale = scale; 65663749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber track->mBytesPerSample = sampleSize; 657cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mKind = kind; 658cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mNumSyncSamples = 0; 659cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mThumbnailSampleSize = 0; 660cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mThumbnailSampleIndex = -1; 661cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mMaxSampleSize = 0; 662bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber track->mAvgChunkSize = 1.0; 663bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber track->mFirstChunkSize = 0; 664cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 665cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 666cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 667cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 668cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatus_t AVIExtractor::parseStreamFormat(off64_t offset, size_t size) { 669cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (mTracks.isEmpty()) { 670cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 671cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 672cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 673cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber Track *track = &mTracks.editItemAt(mTracks.size() - 1); 674cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 675cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (track->mKind == Track::OTHER) { 676cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber // We don't support this content, but that's not a parsing error. 677cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 678cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 679cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 680cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber bool isVideo = (track->mKind == Track::VIDEO); 681cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 682bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if ((isVideo && size < 40) || (!isVideo && size < 16)) { 683bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber // Expected a BITMAPINFO or WAVEFORMAT(EX) structure, respectively. 684cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 685cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 686cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 687cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber sp<ABuffer> buffer = new ABuffer(size); 688cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 689cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 690cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (n < (ssize_t)size) { 691cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 692cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 693cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 694cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const uint8_t *data = buffer->data(); 695cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 696cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (isVideo) { 697cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t width = U32LE_AT(&data[4]); 698cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t height = U32LE_AT(&data[8]); 699cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 700cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mMeta->setInt32(kKeyWidth, width); 701cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mMeta->setInt32(kKeyHeight, height); 702cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } else { 703cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t format = U16LE_AT(data); 7043001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 705cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (format == 0x55) { 706cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 7073001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber } else { 7083001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber LOGW("Unsupported audio format = 0x%04x", format); 709cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 710cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 711cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t numChannels = U16LE_AT(&data[2]); 712cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t sampleRate = U32LE_AT(&data[4]); 713cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 714cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mMeta->setInt32(kKeyChannelCount, numChannels); 715cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mMeta->setInt32(kKeySampleRate, sampleRate); 716cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 717cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 718cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 719cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 720cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 721cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber// static 722cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberbool AVIExtractor::IsCorrectChunkType( 723cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t trackIndex, Track::Kind kind, uint32_t chunkType) { 724cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t chunkBase = chunkType & 0xffff; 725cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 726cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber switch (kind) { 727cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case Track::VIDEO: 728cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber { 729cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (chunkBase != FOURCC(0, 0, 'd', 'c') 730cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber && chunkBase != FOURCC(0, 0, 'd', 'b')) { 731cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return false; 732cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 733cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber break; 734cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 735cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 736cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case Track::AUDIO: 737cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber { 738cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (chunkBase != FOURCC(0, 0, 'w', 'b')) { 739cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return false; 740cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 741cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber break; 742cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 743cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 744cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber default: 745cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber break; 746cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 747cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 748cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (trackIndex < 0) { 749cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return true; 750cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 751cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 752cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint8_t hi = chunkType >> 24; 753cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint8_t lo = (chunkType >> 16) & 0xff; 754cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 755cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (hi < '0' || hi > '9' || lo < '0' || lo > '9') { 756cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return false; 757cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 758cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 759cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (trackIndex != (10 * (hi - '0') + (lo - '0'))) { 760cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return false; 761cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 762cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 763cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return true; 764cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 765cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 766cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatus_t AVIExtractor::parseIndex(off64_t offset, size_t size) { 767cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if ((size % 16) != 0) { 768cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 769cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 770cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 771cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber sp<ABuffer> buffer = new ABuffer(size); 772cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 773cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 774cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (n < (ssize_t)size) { 775cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 776cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 777cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 778cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const uint8_t *data = buffer->data(); 779cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 780cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber while (size > 0) { 781cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t chunkType = U32_AT(data); 782cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 783cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint8_t hi = chunkType >> 24; 784cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint8_t lo = (chunkType >> 16) & 0xff; 785cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 786cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (hi < '0' || hi > '9' || lo < '0' || lo > '9') { 787cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 788cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 789cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 790cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t trackIndex = 10 * (hi - '0') + (lo - '0'); 791cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 792cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (trackIndex >= mTracks.size()) { 793cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 794cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 795cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 796cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber Track *track = &mTracks.editItemAt(trackIndex); 797cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 798cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (!IsCorrectChunkType(-1, track->mKind, chunkType)) { 799cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 800cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 801cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 802cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (track->mKind == Track::OTHER) { 803cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber data += 16; 804cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size -= 16; 805cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber continue; 806cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 807cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 808cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t flags = U32LE_AT(&data[4]); 809cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t offset = U32LE_AT(&data[8]); 810cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t chunkSize = U32LE_AT(&data[12]); 811cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 812cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (chunkSize > track->mMaxSampleSize) { 813cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mMaxSampleSize = chunkSize; 814cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 815cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 816cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mSamples.push(); 817cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 818cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber SampleInfo *info = 819cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber &track->mSamples.editItemAt(track->mSamples.size() - 1); 820cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 821cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber info->mOffset = offset; 822cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber info->mIsKey = (flags & 0x10) != 0; 823cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 824cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (info->mIsKey) { 825cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber static const size_t kMaxNumSyncSamplesToScan = 20; 826cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 827cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (track->mNumSyncSamples < kMaxNumSyncSamplesToScan) { 828cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (chunkSize > track->mThumbnailSampleSize) { 829cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mThumbnailSampleSize = chunkSize; 830cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 831cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mThumbnailSampleIndex = 832cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mSamples.size() - 1; 833cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 834cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 835cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 836cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ++track->mNumSyncSamples; 837cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 838cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 839cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber data += 16; 840cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size -= 16; 841cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 842cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 843cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (!mTracks.isEmpty()) { 844cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber off64_t offset; 845cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t size; 846cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber bool isKey; 84763749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber int64_t timeUs; 84863749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); 849cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 850cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (err != OK) { 851cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mOffsetsAreAbsolute = !mOffsetsAreAbsolute; 85263749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); 853cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 854cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (err != OK) { 855cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return err; 856cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 857cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 858cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 859cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber LOGV("Chunk offsets are %s", 860cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mOffsetsAreAbsolute ? "absolute" : "movie-chunk relative"); 861cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 862cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 863cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 864cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber Track *track = &mTracks.editItemAt(i); 865cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 866bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (track->mBytesPerSample > 0) { 867bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber // Assume all chunks are roughly the same size for now. 868bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 869bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber // Compute the avg. size of the first 128 chunks (if there are 870bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber // that many), but exclude the size of the first one, since 871bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber // it may be an outlier. 872bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t numSamplesToAverage = track->mSamples.size(); 873bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (numSamplesToAverage > 256) { 874bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber numSamplesToAverage = 256; 875bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 876bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 877bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber double avgChunkSize = 0; 878bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t j; 879bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber for (j = 0; j <= numSamplesToAverage; ++j) { 880bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber off64_t offset; 881bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t size; 882bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber bool isKey; 883bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber int64_t dummy; 884bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 885bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber status_t err = 886bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber getSampleInfo( 887bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber i, j, 888bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber &offset, &size, &isKey, &dummy); 889bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 890bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (err != OK) { 891bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber return err; 892bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 893bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 894bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (j == 0) { 895bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber track->mFirstChunkSize = size; 896bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber continue; 897bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 898bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 899bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber avgChunkSize += size; 900bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 901bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 902bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber avgChunkSize /= numSamplesToAverage; 903bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 904bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber track->mAvgChunkSize = avgChunkSize; 905bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 906bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 90763749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber int64_t durationUs; 90863749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber CHECK_EQ((status_t)OK, 90963749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber getSampleTime(i, track->mSamples.size() - 1, &durationUs)); 910cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 911cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber LOGV("track %d duration = %.2f secs", i, durationUs / 1E6); 912cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 913cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mMeta->setInt64(kKeyDuration, durationUs); 914cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mMeta->setInt32(kKeyMaxInputSize, track->mMaxSampleSize); 915cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 916cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const char *tmp; 917cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber CHECK(track->mMeta->findCString(kKeyMIMEType, &tmp)); 918cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 919cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber AString mime = tmp; 920cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 9213001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber if (!strncasecmp("video/", mime.c_str(), 6)) { 9223001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber if (track->mThumbnailSampleIndex >= 0) { 9233001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber int64_t thumbnailTimeUs; 9243001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber CHECK_EQ((status_t)OK, 9253001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber getSampleTime(i, track->mThumbnailSampleIndex, 9263001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber &thumbnailTimeUs)); 927cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 9283001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 9293001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber } 9303001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 9313001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber status_t err = OK; 932cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 933cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) { 9343001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber err = addMPEG4CodecSpecificData(i); 9353001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 9363001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber err = addH264CodecSpecificData(i); 9373001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber } 938cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 9393001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber if (err != OK) { 9403001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber return err; 941cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 942cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 943cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 944cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 945cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mFoundIndex = true; 946cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 947cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 948cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 949cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 950cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatic size_t GetSizeWidth(size_t x) { 951cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t n = 1; 952cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber while (x > 127) { 953cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ++n; 954cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber x >>= 7; 955cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 956cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return n; 957cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 958cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 959cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatic uint8_t *EncodeSize(uint8_t *dst, size_t x) { 960cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber while (x > 127) { 961cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *dst++ = (x & 0x7f) | 0x80; 962cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber x >>= 7; 963cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 964cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *dst++ = x; 965cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return dst; 966cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 967cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 968cabb7da7125a80c55233bd23959327424e9646ccAndreas Hubersp<ABuffer> MakeMPEG4VideoCodecSpecificData(const sp<ABuffer> &config) { 969cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t len1 = config->size() + GetSizeWidth(config->size()) + 1; 970cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13; 971cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3; 972cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 973cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber sp<ABuffer> csd = new ABuffer(len3); 974cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint8_t *dst = csd->data(); 975cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *dst++ = 0x03; 976cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber dst = EncodeSize(dst, len2 + 3); 977cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *dst++ = 0x00; // ES_ID 978cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *dst++ = 0x00; 979cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 980cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 981cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *dst++ = 0x04; 982cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber dst = EncodeSize(dst, len1 + 13); 983cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *dst++ = 0x01; // Video ISO/IEC 14496-2 Simple Profile 984cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber for (size_t i = 0; i < 12; ++i) { 985cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *dst++ = 0x00; 986cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 987cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 988cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *dst++ = 0x05; 989cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber dst = EncodeSize(dst, config->size()); 990cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber memcpy(dst, config->data(), config->size()); 991cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber dst += config->size(); 992cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 993cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber // hexdump(csd->data(), csd->size()); 994cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 995cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return csd; 996cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 997cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 998cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatus_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) { 999cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber Track *track = &mTracks.editItemAt(trackIndex); 1000cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1001cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber off64_t offset; 1002cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t size; 1003cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber bool isKey; 100463749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber int64_t timeUs; 100563749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber status_t err = 100663749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs); 1007cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1008cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (err != OK) { 1009cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return err; 1010cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1011cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1012cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber sp<ABuffer> buffer = new ABuffer(size); 1013cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 1014cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1015cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (n < (ssize_t)size) { 1016cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 1017cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1018cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1019cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber // Extract everything up to the first VOP start code from the first 1020cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber // frame's encoded data and use it to construct an ESDS with the 1021cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber // codec specific data. 1022cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1023cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t i = 0; 1024cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber bool found = false; 1025cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber while (i + 3 < buffer->size()) { 1026cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (!memcmp("\x00\x00\x01\xb6", &buffer->data()[i], 4)) { 1027cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber found = true; 1028cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber break; 1029cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1030cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1031cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ++i; 1032cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1033cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1034cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (!found) { 1035cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 1036cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1037cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1038cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber buffer->setRange(0, i); 1039cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1040cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber sp<ABuffer> csd = MakeMPEG4VideoCodecSpecificData(buffer); 1041cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track->mMeta->setData(kKeyESDS, kTypeESDS, csd->data(), csd->size()); 1042cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1043cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 1044cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 1045cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 10463001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huberstatus_t AVIExtractor::addH264CodecSpecificData(size_t trackIndex) { 10473001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber Track *track = &mTracks.editItemAt(trackIndex); 10483001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10493001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber off64_t offset; 10503001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber size_t size; 10513001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber bool isKey; 10523001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber int64_t timeUs; 10533001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10543001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber // Extract codec specific data from the first non-empty sample. 10553001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10563001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber size_t sampleIndex = 0; 10573001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber for (;;) { 10583001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber status_t err = 10593001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber getSampleInfo( 10603001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber trackIndex, sampleIndex, &offset, &size, &isKey, &timeUs); 10613001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10623001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber if (err != OK) { 10633001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber return err; 10643001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber } 10653001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10663001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber if (size > 0) { 10673001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber break; 10683001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber } 10693001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10703001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber ++sampleIndex; 10713001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber } 10723001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10733001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber sp<ABuffer> buffer = new ABuffer(size); 10743001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 10753001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10763001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber if (n < (ssize_t)size) { 10773001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber return n < 0 ? (status_t)n : ERROR_MALFORMED; 10783001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber } 10793001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10803001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber sp<MetaData> meta = MakeAVCCodecSpecificData(buffer); 10813001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10823001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber if (meta == NULL) { 10833001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber LOGE("Unable to extract AVC codec specific data"); 10843001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber return ERROR_MALFORMED; 10853001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber } 10863001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10873001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber int32_t width, height; 10883001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 10893001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 10903001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10913001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber uint32_t type; 10923001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber const void *csd; 10933001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber size_t csdSize; 10943001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber CHECK(meta->findData(kKeyAVCC, &type, &csd, &csdSize)); 10953001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 10963001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber track->mMeta->setInt32(kKeyWidth, width); 10971fc2e60d59abfe1c4d7f9611c685c894ad1a383fAndreas Huber track->mMeta->setInt32(kKeyHeight, height); 10983001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber track->mMeta->setData(kKeyAVCC, type, csd, csdSize); 10993001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 11003001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber return OK; 11013001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber} 11023001e4721237af2754fc2ac57100dd4ea00c67cbAndreas Huber 1103cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatus_t AVIExtractor::getSampleInfo( 1104cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t trackIndex, size_t sampleIndex, 110563749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber off64_t *offset, size_t *size, bool *isKey, 110663749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber int64_t *sampleTimeUs) { 1107cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (trackIndex >= mTracks.size()) { 1108cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return -ERANGE; 1109cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1110cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1111cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const Track &track = mTracks.itemAt(trackIndex); 1112cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1113cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (sampleIndex >= track.mSamples.size()) { 1114cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return -ERANGE; 1115cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1116cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1117cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const SampleInfo &info = track.mSamples.itemAt(sampleIndex); 1118cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1119cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (!mOffsetsAreAbsolute) { 1120cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *offset = info.mOffset + mMovieOffset + 8; 1121cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } else { 1122cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *offset = info.mOffset; 1123cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1124cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1125cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *size = 0; 1126cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1127cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint8_t tmp[8]; 1128cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t n = mDataSource->readAt(*offset, tmp, 8); 1129cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1130cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (n < 8) { 1131cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED; 1132cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1133cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1134cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber uint32_t chunkType = U32_AT(tmp); 1135cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1136cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (!IsCorrectChunkType(trackIndex, track.mKind, chunkType)) { 1137cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return ERROR_MALFORMED; 1138cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1139cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1140cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *offset += 8; 1141cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *size = U32LE_AT(&tmp[4]); 1142cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1143cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *isKey = info.mIsKey; 1144cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1145bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (track.mBytesPerSample > 0) { 1146bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t sampleStartInBytes; 1147bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (sampleIndex == 0) { 1148bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber sampleStartInBytes = 0; 1149bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } else { 1150bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber sampleStartInBytes = 1151bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber track.mFirstChunkSize + track.mAvgChunkSize * (sampleIndex - 1); 1152bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 1153bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 1154bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber sampleIndex = sampleStartInBytes / track.mBytesPerSample; 1155bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 1156bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 115763749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale; 115863749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber 1159cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 1160cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 1161cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 116263749954aa828b3f73b4738659eaea5eaeeca874Andreas Huberstatus_t AVIExtractor::getSampleTime( 116363749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) { 116463749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber off64_t offset; 116563749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber size_t size; 116663749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber bool isKey; 116763749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber return getSampleInfo( 116863749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs); 116963749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber} 117063749954aa828b3f73b4738659eaea5eaeeca874Andreas Huber 1171cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberstatus_t AVIExtractor::getSampleIndexAtTime( 1172cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t trackIndex, 1173cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber int64_t timeUs, MediaSource::ReadOptions::SeekMode mode, 1174cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t *sampleIndex) const { 1175cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (trackIndex >= mTracks.size()) { 1176cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return -ERANGE; 1177cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1178cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1179cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const Track &track = mTracks.itemAt(trackIndex); 1180cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1181bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber ssize_t closestSampleIndex; 1182bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 1183bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (track.mBytesPerSample > 0) { 1184bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber size_t closestByteOffset = 1185bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber (timeUs * track.mBytesPerSample) 1186bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber / track.mRate * track.mScale / 1000000ll; 1187bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber 1188bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber if (closestByteOffset <= track.mFirstChunkSize) { 1189bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber closestSampleIndex = 0; 1190bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } else { 1191bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber closestSampleIndex = 1192bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber (closestByteOffset - track.mFirstChunkSize) 1193bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber / track.mAvgChunkSize; 1194bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 1195bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } else { 1196bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber // Each chunk contains a single sample. 1197bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber closestSampleIndex = timeUs / track.mRate * track.mScale / 1000000ll; 1198bea34b942d1727934e4cd69c5e7b69679b4e8891Andreas Huber } 1199cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1200cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t numSamples = track.mSamples.size(); 1201cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1202cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (closestSampleIndex < 0) { 1203cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber closestSampleIndex = 0; 1204cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } else if (closestSampleIndex >= numSamples) { 1205cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber closestSampleIndex = numSamples - 1; 1206cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1207cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1208cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (mode == MediaSource::ReadOptions::SEEK_CLOSEST) { 1209cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *sampleIndex = closestSampleIndex; 1210cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1211cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 1212cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1213cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1214cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t prevSyncSampleIndex = closestSampleIndex; 1215cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber while (prevSyncSampleIndex >= 0) { 1216cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const SampleInfo &info = 1217cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track.mSamples.itemAt(prevSyncSampleIndex); 1218cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1219cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (info.mIsKey) { 1220cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber break; 1221cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1222cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1223cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber --prevSyncSampleIndex; 1224cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1225cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1226cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ssize_t nextSyncSampleIndex = closestSampleIndex; 1227cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber while (nextSyncSampleIndex < numSamples) { 1228cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const SampleInfo &info = 1229cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber track.mSamples.itemAt(nextSyncSampleIndex); 1230cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1231cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (info.mIsKey) { 1232cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber break; 1233cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1234cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1235cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber ++nextSyncSampleIndex; 1236cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1237cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1238cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber switch (mode) { 1239cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC: 1240cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber { 1241cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *sampleIndex = prevSyncSampleIndex; 1242cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1243cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return prevSyncSampleIndex >= 0 ? OK : UNKNOWN_ERROR; 1244cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1245cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1246cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case MediaSource::ReadOptions::SEEK_NEXT_SYNC: 1247cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber { 1248cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *sampleIndex = nextSyncSampleIndex; 1249cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1250cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return nextSyncSampleIndex < numSamples ? OK : UNKNOWN_ERROR; 1251cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1252cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1253cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber case MediaSource::ReadOptions::SEEK_CLOSEST_SYNC: 1254cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber { 1255cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (prevSyncSampleIndex < 0 && nextSyncSampleIndex >= numSamples) { 1256cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return UNKNOWN_ERROR; 1257cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1258cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1259cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (prevSyncSampleIndex < 0) { 1260cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *sampleIndex = nextSyncSampleIndex; 1261cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 1262cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1263cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1264cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (nextSyncSampleIndex >= numSamples) { 1265cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *sampleIndex = prevSyncSampleIndex; 1266cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 1267cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1268cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1269cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t dist1 = closestSampleIndex - prevSyncSampleIndex; 1270cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber size_t dist2 = nextSyncSampleIndex - closestSampleIndex; 1271cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1272cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber *sampleIndex = 1273cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber (dist1 < dist2) ? prevSyncSampleIndex : nextSyncSampleIndex; 1274cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1275cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return OK; 1276cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1277cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1278cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber default: 1279cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber TRESPASS(); 1280cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber break; 1281cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1282cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 1283cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1284cabb7da7125a80c55233bd23959327424e9646ccAndreas Huberbool SniffAVI( 1285cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 1286cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber sp<AMessage> *) { 1287cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber char tmp[12]; 1288cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (source->readAt(0, tmp, 12) < 12) { 1289cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return false; 1290cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1291cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1292cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber if (!memcmp(tmp, "RIFF", 4) && !memcmp(&tmp[8], "AVI ", 4)) { 1293cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_AVI); 1294f8c84b343488c29cc6ef224a7df751c94955e029Andreas Huber 1295f8c84b343488c29cc6ef224a7df751c94955e029Andreas Huber // Just a tad over the mp3 extractor's confidence, since 1296f8c84b343488c29cc6ef224a7df751c94955e029Andreas Huber // these .avi files may contain .mp3 content that otherwise would 1297f8c84b343488c29cc6ef224a7df751c94955e029Andreas Huber // mistakenly lead to us identifying the entire file as a .mp3 file. 1298f8c84b343488c29cc6ef224a7df751c94955e029Andreas Huber *confidence = 0.21; 1299cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1300cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return true; 1301cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber } 1302cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1303cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber return false; 1304cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} 1305cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber 1306cabb7da7125a80c55233bd23959327424e9646ccAndreas Huber} // namespace android 1307