MatroskaExtractor.cpp revision 50c8bea8fba2fcafb14696399028bdbc094dc995
1093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber/* 2093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Copyright (C) 2010 The Android Open Source Project 3093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * 4093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * you may not use this file except in compliance with the License. 6093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * You may obtain a copy of the License at 7093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * 8093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * 10093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Unless required by applicable law or agreed to in writing, software 11093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * See the License for the specific language governing permissions and 14093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * limitations under the License. 15093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber */ 16093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 17093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//#define LOG_NDEBUG 0 18093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#define LOG_TAG "MatroskaExtractor" 19093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <utils/Log.h> 20093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 21093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "MatroskaExtractor.h" 22093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 23093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "mkvparser.hpp" 24093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 25b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include <media/stagefright/foundation/ADebug.h> 26b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include <media/stagefright/foundation/hexdump.h> 27093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/DataSource.h> 28093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaBuffer.h> 29093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaDefs.h> 30093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaErrors.h> 31093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaSource.h> 32093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MetaData.h> 33b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include <media/stagefright/Utils.h> 34093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <utils/String8.h> 35093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 36093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubernamespace android { 37093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 38093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstruct DataSourceReader : public mkvparser::IMkvReader { 39093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader(const sp<DataSource> &source) 40093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mSource(source) { 41093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 42093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 43093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual int Read(long long position, long length, unsigned char* buffer) { 44093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(position >= 0); 45093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(length >= 0); 46093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 47093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (length == 0) { 48093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 49093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 50093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 51093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber ssize_t n = mSource->readAt(position, buffer, length); 52093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 53093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (n <= 0) { 54093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return -1; 55093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 56093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 57093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 58093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 59093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 60093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual int Length(long long* total, long long* available) { 61c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t size; 62093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (mSource->getSize(&size) != OK) { 63093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return -1; 64093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 65093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 66093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (total) { 67093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *total = size; 68093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 69093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 70093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (available) { 71093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *available = size; 72093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 73093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 74093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 75093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 76093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 77093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate: 78093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<DataSource> mSource; 79093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 80093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader(const DataSourceReader &); 81093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader &operator=(const DataSourceReader &); 82093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; 83093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 84093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 85093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberstruct BlockIterator { 875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator(mkvparser::Segment *segment, unsigned long trackNum); 885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber bool eos() const; 905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void advance(); 925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void reset(); 935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void seek(int64_t seekTimeUs); 945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::Block *block() const; 965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t blockTimeUs() const; 975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberprivate: 995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mkvparser::Segment *mSegment; 1005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber unsigned long mTrackNum; 1015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mkvparser::Cluster *mCluster; 1035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::BlockEntry *mBlockEntry; 1045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator(const BlockIterator &); 1065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator &operator=(const BlockIterator &); 1075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}; 1085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 109093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstruct MatroskaSource : public MediaSource { 110093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource( 111093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MatroskaExtractor> &extractor, size_t index); 112093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 113093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t start(MetaData *params); 114093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t stop(); 115093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 116093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual sp<MetaData> getFormat(); 117093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 118093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t read( 119093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MediaBuffer **buffer, const ReadOptions *options); 120093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 12150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberprotected: 12250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber virtual ~MatroskaSource(); 12350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 124093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate: 125093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber enum Type { 126093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber AVC, 127093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber AAC, 128093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber OTHER 129093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber }; 130093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 131093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MatroskaExtractor> mExtractor; 132093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t mTrackIndex; 133093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber Type mType; 1345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator mBlockIter; 135b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber size_t mNALSizeLen; // for type AVC 136093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 13750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber List<MediaBuffer *> mPendingFrames; 13850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 139093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber status_t advance(); 140093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 14150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber status_t readBlock(); 14250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber void clearPendingFrames(); 14350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 144093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource(const MatroskaSource &); 145093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource &operator=(const MatroskaSource &); 146093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; 147093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 148093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaSource::MatroskaSource( 149093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MatroskaExtractor> &extractor, size_t index) 150093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mExtractor(extractor), 151093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTrackIndex(index), 152093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType(OTHER), 1535279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter(mExtractor->mSegment, 154b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mExtractor->mTracks.itemAt(index).mTrackNum), 155b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mNALSizeLen(0) { 156b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta; 157b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 158093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *mime; 159b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 160093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 161093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 162093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AVC; 163b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 164b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber uint32_t dummy; 165b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber const uint8_t *avcc; 166b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber size_t avccSize; 167b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK(meta->findData( 168b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber kKeyAVCC, &dummy, (const void **)&avcc, &avccSize)); 169b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 170b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK_GE(avccSize, 5u); 171b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 172b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mNALSizeLen = 1 + (avcc[4] & 3); 173b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber LOGV("mNALSizeLen = %d", mNALSizeLen); 174093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 175093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AAC; 176093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 177093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 178093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 17950c8bea8fba2fcafb14696399028bdbc094dc995Andreas HuberMatroskaSource::~MatroskaSource() { 18050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 18150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 18250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 183093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::start(MetaData *params) { 1845279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter.reset(); 185093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 186093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 187093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 188093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 189093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::stop() { 19050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 19150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 192093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 193093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 194093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 195093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaSource::getFormat() { 196093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mExtractor->mTracks.itemAt(mTrackIndex).mMeta; 197093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 198093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber//////////////////////////////////////////////////////////////////////////////// 2005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas HuberBlockIterator::BlockIterator( 2025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mkvparser::Segment *segment, unsigned long trackNum) 2035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber : mSegment(segment), 2045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mTrackNum(trackNum), 2055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster(NULL), 2065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry(NULL) { 2075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber reset(); 2085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2095279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberbool BlockIterator::eos() const { 2115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mCluster == NULL || mCluster->EOS(); 2125279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2135279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::advance() { 2155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos()) { 2165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockEntry != NULL) { 2175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry = mCluster->GetNext(mBlockEntry); 2185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } else if (mCluster != NULL) { 2195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster = mSegment->GetNext(mCluster); 2205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (eos()) { 2225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 223093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2245279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 225093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mBlockEntry = mCluster->GetFirst(); 226093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 227093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2285279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockEntry != NULL 2295279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber && mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) { 2305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 231093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2325279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 2335279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2355279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::reset() { 2365279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster = mSegment->GetFirst(); 2375279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry = mCluster->GetFirst(); 238093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2395279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos() && block()->GetTrackNumber() != mTrackNum) { 2405279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber advance(); 241093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2425279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 243093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2445279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::seek(int64_t seekTimeUs) { 245ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber mCluster = mSegment->FindCluster(seekTimeUs * 1000ll); 2465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry = mCluster != NULL ? mCluster->GetFirst() : NULL; 2475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2485279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos() && block()->GetTrackNumber() != mTrackNum) { 2495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber advance(); 2505279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 2515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2525279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos() && !mBlockEntry->GetBlock()->IsKey()) { 2535279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber advance(); 2545279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 255093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 256093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2575279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberconst mkvparser::Block *BlockIterator::block() const { 2585279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber CHECK(!eos()); 2595279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2605279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mBlockEntry->GetBlock(); 2615279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2625279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberint64_t BlockIterator::blockTimeUs() const { 2645279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll; 2655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2675279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber//////////////////////////////////////////////////////////////////////////////// 2685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 269b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huberstatic unsigned U24_AT(const uint8_t *ptr) { 270b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; 271b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber} 272b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 27350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatic size_t clz(uint8_t x) { 27450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t numLeadingZeroes = 0; 275093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 27650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber while (!(x & 0x80)) { 27750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber ++numLeadingZeroes; 27850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber x = x << 1; 279093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 280093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 28150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return numLeadingZeroes; 28250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 28350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 28450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Hubervoid MatroskaSource::clearPendingFrames() { 28550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber while (!mPendingFrames.empty()) { 28650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer *frame = *mPendingFrames.begin(); 28750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 28850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 28950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame->release(); 29050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame = NULL; 29150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 29250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 29350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 29450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber#define BAIL(err) \ 29550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber do { \ 29650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (bigbuf) { \ 29750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber bigbuf->release(); \ 29850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber bigbuf = NULL; \ 29950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } \ 30050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber \ 30150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return err; \ 30250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } while (0) 30350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 30450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::readBlock() { 30550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber CHECK(mPendingFrames.empty()); 30650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 3075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockIter.eos()) { 308093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return ERROR_END_OF_STREAM; 309093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 310093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 3115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::Block *block = mBlockIter.block(); 31250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 313093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t size = block->GetSize(); 3145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t timeUs = mBlockIter.blockTimeUs(); 31550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber int32_t isSync = block->IsKey(); 316093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 31750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer *bigbuf = new MediaBuffer(size); 318093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 319093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long res = block->Read( 32050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mExtractor->mReader, (unsigned char *)bigbuf->data()); 321093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 322093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (res != 0) { 32350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber bigbuf->release(); 32450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber bigbuf = NULL; 32550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 326093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return ERROR_END_OF_STREAM; 327093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 328093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 32950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mBlockIter.advance(); 33050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 33150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber bigbuf->meta_data()->setInt64(kKeyTime, timeUs); 33250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber bigbuf->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 33350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 33450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber unsigned lacing = (block->Flags() >> 1) & 3; 33550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 33650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (lacing == 0) { 33750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.push_back(bigbuf); 33850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return OK; 33950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 340093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 34150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber LOGV("lacing = %u, size = %d", lacing, size); 342093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 34350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber const uint8_t *data = (const uint8_t *)bigbuf->data(); 34450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // hexdump(data, size); 345093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 34650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (size == 0) { 34750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber BAIL(ERROR_MALFORMED); 34850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 34950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 35050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber unsigned numFrames = (unsigned)data[0] + 1; 35150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber ++data; 35250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber --size; 35350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 35450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber Vector<uint64_t> frameSizes; 35550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 35650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber switch (lacing) { 35750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber case 1: // Xiph 35850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber { 35950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber for (size_t i = 0; i < numFrames - 1; ++i) { 36050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t frameSize = 0; 36150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber uint8_t byte; 36250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber do { 36350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (size == 0) { 36450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber BAIL(ERROR_MALFORMED); 36550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 36650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber byte = data[0]; 36750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber ++data; 36850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber --size; 36950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 37050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frameSize += byte; 37150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } while (byte == 0xff); 37250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 37350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frameSizes.push(frameSize); 37450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 37550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 37650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber break; 377b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber } 378b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 37950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber case 2: // fixed-size 38050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber { 38150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if ((size % numFrames) != 0) { 38250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber BAIL(ERROR_MALFORMED); 38350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 38450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 38550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t frameSize = size / numFrames; 38650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber for (size_t i = 0; i < numFrames - 1; ++i) { 38750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frameSizes.push(frameSize); 38850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 38950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 39050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber break; 391b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber } 392b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 39350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber case 3: // EBML 39450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber { 39550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber uint64_t lastFrameSize = 0; 39650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber for (size_t i = 0; i < numFrames - 1; ++i) { 39750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber uint8_t byte; 398093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 39950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (size == 0) { 40050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber BAIL(ERROR_MALFORMED); 40150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 40250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber byte = data[0]; 40350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber ++data; 40450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber --size; 405093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 40650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t numLeadingZeroes = clz(byte); 407b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 40850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber uint64_t frameSize = byte & ~(0x80 >> numLeadingZeroes); 40950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber for (size_t j = 0; j < numLeadingZeroes; ++j) { 41050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (size == 0) { 41150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber BAIL(ERROR_MALFORMED); 41250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 413b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 41450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frameSize = frameSize << 8; 41550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frameSize |= data[0]; 41650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber ++data; 41750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber --size; 41850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 41950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 42050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (i == 0) { 42150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frameSizes.push(frameSize); 42250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } else { 42350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t shift = 42450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 7 - numLeadingZeroes + 8 * numLeadingZeroes; 425b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 42650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber int64_t delta = 42750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber (int64_t)frameSize - (1ll << (shift - 1)) + 1; 428b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 42950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frameSize = lastFrameSize + delta; 43050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 43150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frameSizes.push(frameSize); 43250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 43350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 43450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber lastFrameSize = frameSize; 43550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 43650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber break; 437b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber } 438b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 43950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber default: 44050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber TRESPASS(); 441093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 442093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 443093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#if 0 44450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber AString out; 44550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber for (size_t i = 0; i < frameSizes.size(); ++i) { 44650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (i > 0) { 44750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber out.append(", "); 44850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 44950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber out.append(StringPrintf("%llu", frameSizes.itemAt(i))); 45050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 45150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber LOGV("sizes = [%s]", out.c_str()); 452093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#endif 453093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 45450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber for (size_t i = 0; i < frameSizes.size(); ++i) { 45550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber uint64_t frameSize = frameSizes.itemAt(i); 45650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 45750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (size < frameSize) { 45850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber BAIL(ERROR_MALFORMED); 45950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 46050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 46150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer *mbuf = new MediaBuffer(frameSize); 46250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mbuf->meta_data()->setInt64(kKeyTime, timeUs); 46350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mbuf->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 46450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber memcpy(mbuf->data(), data, frameSize); 46550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.push_back(mbuf); 46650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 46750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber data += frameSize; 46850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size -= frameSize; 46950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 47050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 47150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t offset = bigbuf->range_length() - size; 47250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber bigbuf->set_range(offset, size); 47350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 47450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.push_back(bigbuf); 47550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 47650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return OK; 47750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 47850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 47950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber#undef BAIL 48050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 48150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::read( 48250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer **out, const ReadOptions *options) { 48350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = NULL; 48450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 48550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber int64_t seekTimeUs; 48650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber ReadOptions::SeekMode mode; 48750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 48850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 48950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mBlockIter.seek(seekTimeUs); 49050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 49150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 49250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberagain: 49350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber while (mPendingFrames.empty()) { 49450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber status_t err = readBlock(); 49550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 49650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (err != OK) { 49750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 49850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 49950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return err; 50050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 50150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 50250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 50350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer *frame = *mPendingFrames.begin(); 50450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 50550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 50650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t size = frame->range_length(); 50750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 50850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (mType != AVC) { 50950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = frame; 51050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 51150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return OK; 51250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 51350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 51450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (size < mNALSizeLen) { 51550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame->release(); 51650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame = NULL; 51750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 51850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return ERROR_MALFORMED; 51950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 52050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 52150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // In the case of AVC content, each NAL unit is prefixed by 52250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // mNALSizeLen bytes of length. We want to prefix the data with 52350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // a four-byte 0x00000001 startcode instead of the length prefix. 52450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // mNALSizeLen ranges from 1 through 4 bytes, so add an extra 52550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // 3 bytes of padding to the buffer start. 52650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber static const size_t kPadding = 3; 52750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 52850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer *buffer = new MediaBuffer(size + kPadding); 52950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 53050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber int64_t timeUs; 53150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs)); 53250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber int32_t isSync; 53350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)); 53450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 53550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer->meta_data()->setInt64(kKeyTime, timeUs); 53650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 53750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 53850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber memcpy((uint8_t *)buffer->data() + kPadding, 53950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber (const uint8_t *)frame->data() + frame->range_offset(), 54050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size); 54150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 54250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer->set_range(kPadding, size); 54350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 54450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame->release(); 54550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame = NULL; 54650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 54750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber uint8_t *data = (uint8_t *)buffer->data(); 54850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 54950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t NALsize; 55050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber switch (mNALSizeLen) { 55150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber case 1: NALsize = data[kPadding]; break; 55250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber case 2: NALsize = U16_AT(&data[kPadding]); break; 55350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber case 3: NALsize = U24_AT(&data[kPadding]); break; 55450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber case 4: NALsize = U32_AT(&data[kPadding]); break; 55550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber default: 55650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber TRESPASS(); 55750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 55850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 55950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (size < NALsize + mNALSizeLen) { 56050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer->release(); 56150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer = NULL; 56250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 56350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return ERROR_MALFORMED; 56450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 56550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 56650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (size > NALsize + mNALSizeLen) { 56750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber LOGW("discarding %d bytes of data.", size - NALsize - mNALSizeLen); 56850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 56950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 57050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // actual data starts at &data[kPadding + mNALSizeLen] 57150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 57250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber memcpy(&data[mNALSizeLen - 1], "\x00\x00\x00\x01", 4); 57350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer->set_range(mNALSizeLen - 1, NALsize + 4); 57450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 57550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = buffer; 576093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 577093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 578093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 579093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 580093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 581093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 582093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source) 583093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mDataSource(source), 584093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mReader(new DataSourceReader(mDataSource)), 5855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mSegment(NULL), 5865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mExtractedThumbnails(false) { 587093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 588093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 589093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(mReader, pos) < 0) { 590093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 591093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 592093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 593093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long ret = 594093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::Segment::CreateInstance(mReader, pos, mSegment); 595093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 596093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret) { 597093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(mSegment == NULL); 598093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 599093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 600093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 601093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber ret = mSegment->Load(); 602093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 603093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret < 0) { 604093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 605093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 606093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 607093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 608093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 609093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addTracks(); 610093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 611093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 612093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::~MatroskaExtractor() { 613093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 614093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 615093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 616093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mReader; 617093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mReader = NULL; 618093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 619093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 620093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersize_t MatroskaExtractor::countTracks() { 621093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mTracks.size(); 622093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 623093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 624093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MediaSource> MatroskaExtractor::getTrack(size_t index) { 625093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 626093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return NULL; 627093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 628093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 629093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return new MatroskaSource(this, index); 630093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 631093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 632093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getTrackMetaData( 633093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t index, uint32_t flags) { 634093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 635093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return NULL; 636093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 637093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 6385279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails) { 6395279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber findThumbnails(); 6405279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mExtractedThumbnails = true; 6415279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 6425279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 643093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mTracks.itemAt(index).mMeta; 644093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 645093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 646093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic void addESDSFromAudioSpecificInfo( 647093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MetaData> &meta, const void *asi, size_t asiSize) { 648093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static const uint8_t kStaticESDS[] = { 649093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x03, 22, 650093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, // ES_ID 651093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 652093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 653093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x04, 17, 654093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x40, // Audio ISO/IEC 14496-3 655093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 656093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 657093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 658093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 659093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x05, 660093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // AudioSpecificInfo (with size prefix) follows 661093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber }; 662093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 663093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(asiSize < 128); 664093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1; 665093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *esds = new uint8_t[esdsSize]; 666093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber memcpy(esds, kStaticESDS, sizeof(kStaticESDS)); 667093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *ptr = esds + sizeof(kStaticESDS); 668093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *ptr++ = asiSize; 669093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber memcpy(ptr, asi, asiSize); 670093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 671093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyESDS, 0, esds, esdsSize); 672093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 673093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete[] esds; 674093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber esds = NULL; 675093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 676093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 677093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid addVorbisCodecInfo( 678093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MetaData> &meta, 679093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const void *_codecPrivate, size_t codecPrivateSize) { 680093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // printf("vorbis private data follows:\n"); 681093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // hexdump(_codecPrivate, codecPrivateSize); 682093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 683093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize >= 3); 684093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 685093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate; 686093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[0] == 0x02); 687093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 688093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t len1 = codecPrivate[1]; 689093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t len2 = codecPrivate[2]; 690093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 691093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize > 3 + len1 + len2); 692093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 693093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[3] == 0x01); 694093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1); 695093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 696093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[len1 + 3] == 0x03); 697093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 698093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[len1 + len2 + 3] == 0x05); 699093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData( 700093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3], 701093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber codecPrivateSize - len1 - len2 - 3); 702093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 703093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 704093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid MatroskaExtractor::addTracks() { 705093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Tracks *tracks = mSegment->GetTracks(); 706093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 707093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber for (size_t index = 0; index < tracks->GetTracksCount(); ++index) { 708093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Track *track = tracks->GetTrackByIndex(index); 709093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 710093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *const codecID = track->GetCodecId(); 711093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber LOGV("codec id = %s", codecID); 712093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber LOGV("codec name = %s", track->GetCodecNameAsUTF8()); 713093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 714093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t codecPrivateSize; 715093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const unsigned char *codecPrivate = 716ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber track->GetCodecPrivate(codecPrivateSize); 717093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 718093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; 719093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 720093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MetaData> meta = new MetaData; 721093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 722093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber switch (track->GetType()) { 723093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case VIDEO_TRACK: 724093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 725093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::VideoTrack *vtrack = 726093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::VideoTrack *>(track); 727093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 728093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { 729093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 730093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); 731093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("V_VP8", codecID)) { 732093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX); 733093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 734093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 735093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 736093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 737093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyWidth, vtrack->GetWidth()); 738093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyHeight, vtrack->GetHeight()); 739093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 740093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 741093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 742093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case AUDIO_TRACK: 743093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 744093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::AudioTrack *atrack = 745093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::AudioTrack *>(track); 746093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 747093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcmp("A_AAC", codecID)) { 748093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 749093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize >= 2); 750093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 751093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addESDSFromAudioSpecificInfo( 752093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta, codecPrivate, codecPrivateSize); 753093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("A_VORBIS", codecID)) { 754093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); 755093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 756093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize); 757093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 758093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 759093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 760093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 761093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeySampleRate, atrack->GetSamplingRate()); 762093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyChannelCount, atrack->GetChannels()); 763093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 764093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 765093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 766093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber default: 767093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 768093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 769093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 770093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long durationNs = mSegment->GetDuration(); 771093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt64(kKeyDuration, (durationNs + 500) / 1000); 772093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 773093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTracks.push(); 774093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1); 775093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber trackInfo->mTrackNum = track->GetNumber(); 776093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber trackInfo->mMeta = meta; 777093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 778093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 779093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 7805279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid MatroskaExtractor::findThumbnails() { 7815279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 7825279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber TrackInfo *info = &mTracks.editItemAt(i); 7835279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 7845279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const char *mime; 7855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber CHECK(info->mMeta->findCString(kKeyMIMEType, &mime)); 7865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 7875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (strncasecmp(mime, "video/", 6)) { 7885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber continue; 7895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 7905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 7915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator iter(mSegment, info->mTrackNum); 7925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int32_t i = 0; 7935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t thumbnailTimeUs = 0; 7945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber size_t maxBlockSize = 0; 7955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!iter.eos() && i < 20) { 7965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (iter.block()->IsKey()) { 7975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber ++i; 7985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 7995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber size_t blockSize = iter.block()->GetSize(); 8005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (blockSize > maxBlockSize) { 8015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber maxBlockSize = blockSize; 8025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber thumbnailTimeUs = iter.blockTimeUs(); 8035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 8045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 8055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber iter.advance(); 8065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 8075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 8085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 8095279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 8105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 811093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getMetaData() { 812093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MetaData> meta = new MetaData; 813093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MATROSKA); 814093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 815093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return meta; 816093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 817093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 818093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberbool SniffMatroska( 8195a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 8205a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 821093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader reader(source); 822093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 823093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 824093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(&reader, pos) < 0) { 825093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return false; 826093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 827093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 828093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA); 829093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *confidence = 0.6; 830093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 831093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return true; 832093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 833093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 834093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} // namespace android 835