MatroskaExtractor.cpp revision 2ba7ce928b0fa8917ee202836b0963ca58613453
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) { 63d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber *total = -1; 64d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber *available = (long long)((1ull << 63) - 1); 65d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 66d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber return 0; 67093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 68093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 69093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (total) { 70093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *total = size; 71093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 72093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 73093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (available) { 74093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *available = size; 75093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 76093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 77093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 78093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 79093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 80093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate: 81093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<DataSource> mSource; 82093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 83093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader(const DataSourceReader &); 84093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader &operator=(const DataSourceReader &); 85093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; 86093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 87093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 88093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberstruct BlockIterator { 90d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber BlockIterator(MatroskaExtractor *extractor, unsigned long trackNum); 915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber bool eos() const; 935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void advance(); 955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void reset(); 965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void seek(int64_t seekTimeUs); 975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::Block *block() const; 995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t blockTimeUs() const; 1005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberprivate: 102d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber MatroskaExtractor *mExtractor; 1035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber unsigned long mTrackNum; 1045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 105d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber const mkvparser::Cluster *mCluster; 1065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::BlockEntry *mBlockEntry; 107d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long mBlockEntryIndex; 108d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 109d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber void advance_l(); 1105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator(const BlockIterator &); 1125279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator &operator=(const BlockIterator &); 1135279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}; 1145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 115093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstruct MatroskaSource : public MediaSource { 116093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource( 117093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MatroskaExtractor> &extractor, size_t index); 118093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 119093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t start(MetaData *params); 120093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t stop(); 121093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 122093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual sp<MetaData> getFormat(); 123093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 124093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t read( 125093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MediaBuffer **buffer, const ReadOptions *options); 126093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 12750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberprotected: 12850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber virtual ~MatroskaSource(); 12950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 130093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate: 131093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber enum Type { 132093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber AVC, 133093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber AAC, 134093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber OTHER 135093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber }; 136093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 137093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MatroskaExtractor> mExtractor; 138093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t mTrackIndex; 139093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber Type mType; 1405279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator mBlockIter; 141b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber size_t mNALSizeLen; // for type AVC 142093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 14350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber List<MediaBuffer *> mPendingFrames; 14450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 145093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber status_t advance(); 146093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 14750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber status_t readBlock(); 14850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber void clearPendingFrames(); 14950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 150093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource(const MatroskaSource &); 151093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource &operator=(const MatroskaSource &); 152093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; 153093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 154093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaSource::MatroskaSource( 155093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MatroskaExtractor> &extractor, size_t index) 156093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mExtractor(extractor), 157093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTrackIndex(index), 158093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType(OTHER), 159d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockIter(mExtractor.get(), 160b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mExtractor->mTracks.itemAt(index).mTrackNum), 161b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mNALSizeLen(0) { 162b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta; 163b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 164093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *mime; 165b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 166093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 167093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 168093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AVC; 169b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 170b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber uint32_t dummy; 171b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber const uint8_t *avcc; 172b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber size_t avccSize; 173b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK(meta->findData( 174b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber kKeyAVCC, &dummy, (const void **)&avcc, &avccSize)); 175b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 176b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK_GE(avccSize, 5u); 177b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 178b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mNALSizeLen = 1 + (avcc[4] & 3); 179b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber LOGV("mNALSizeLen = %d", mNALSizeLen); 180093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 181093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AAC; 182093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 183093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 184093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 18550c8bea8fba2fcafb14696399028bdbc094dc995Andreas HuberMatroskaSource::~MatroskaSource() { 18650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 18750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 18850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 189093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::start(MetaData *params) { 1905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter.reset(); 191093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 192093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 193093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 194093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 195093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::stop() { 19650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 19750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 198093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 199093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 200093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 201093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaSource::getFormat() { 202093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mExtractor->mTracks.itemAt(mTrackIndex).mMeta; 203093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 204093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber//////////////////////////////////////////////////////////////////////////////// 2065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas HuberBlockIterator::BlockIterator( 208d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber MatroskaExtractor *extractor, unsigned long trackNum) 209d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber : mExtractor(extractor), 2105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mTrackNum(trackNum), 2115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster(NULL), 212d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntry(NULL), 213d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntryIndex(0) { 2145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber reset(); 2155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberbool BlockIterator::eos() const { 2185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mCluster == NULL || mCluster->EOS(); 2195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::advance() { 222d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 223d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber advance_l(); 224d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber} 225d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 226d42573cace9db2b5948e540c32beaef80f04153cAndreas Hubervoid BlockIterator::advance_l() { 227d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber for (;;) { 228d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry); 229d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber LOGV("GetEntry returned %ld", res); 230d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 231d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long long pos; 232d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long len; 233d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (res < 0) { 234d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber // Need to parse this cluster some more 235d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 236d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL); 237d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 238d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber res = mCluster->Parse(pos, len); 239d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber LOGV("Parse returned %ld", res); 240d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 241d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (res < 0) { 242d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber // I/O error 243d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 244d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber LOGE("Cluster::Parse returned result %ld", res); 2455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 246d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = NULL; 2475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 248093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 250d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber continue; 251d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } else if (res == 0) { 252d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber // We're done with this cluster 253d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 254d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber const mkvparser::Cluster *nextCluster; 255d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber res = mExtractor->mSegment->ParseNext( 256d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster, nextCluster, pos, len); 257d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber LOGV("ParseNext returned %ld", res); 258d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 259d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (res > 0) { 260d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber // EOF 261d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 262d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = NULL; 263d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber break; 264d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } 265d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 266d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_EQ(res, 0); 267d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(nextCluster != NULL); 268d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(!nextCluster->EOS()); 269d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 270d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = nextCluster; 271d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 272d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber res = mCluster->Parse(pos, len); 273d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber LOGV("Parse (2) returned %ld", res); 274d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_GE(res, 0); 275d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 276d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntryIndex = 0; 277d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber continue; 278093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 279093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 280d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(mBlockEntry != NULL); 281d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(mBlockEntry->GetBlock() != NULL); 282d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber ++mBlockEntryIndex; 283d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 284d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) { 2855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 286093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 2885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::reset() { 291d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 292093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 293d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = mExtractor->mSegment->GetFirst(); 2942ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber mBlockEntry = NULL; 295d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntryIndex = 0; 296d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 297d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber do { 298d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber advance_l(); 299d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } while (!eos() && block()->GetTrackNumber() != mTrackNum); 3005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 301093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 3025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::seek(int64_t seekTimeUs) { 303d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 304d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 305d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll); 3062ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber mBlockEntry = NULL; 307d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntryIndex = 0; 3085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3092ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber do { 310d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber advance_l(); 3115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 3122ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber while (!eos() && block()->GetTrackNumber() != mTrackNum); 3135279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos() && !mBlockEntry->GetBlock()->IsKey()) { 315d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber advance_l(); 3165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 317093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 318093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 3195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberconst mkvparser::Block *BlockIterator::block() const { 3205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber CHECK(!eos()); 3215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mBlockEntry->GetBlock(); 3235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 3245279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberint64_t BlockIterator::blockTimeUs() const { 3265279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll; 3275279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 3285279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3295279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber//////////////////////////////////////////////////////////////////////////////// 3305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 331b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huberstatic unsigned U24_AT(const uint8_t *ptr) { 332b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; 333b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber} 334b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 33550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatic size_t clz(uint8_t x) { 33650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t numLeadingZeroes = 0; 337093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 33850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber while (!(x & 0x80)) { 33950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber ++numLeadingZeroes; 34050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber x = x << 1; 341093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 342093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 34350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return numLeadingZeroes; 34450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 34550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 34650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Hubervoid MatroskaSource::clearPendingFrames() { 34750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber while (!mPendingFrames.empty()) { 34850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer *frame = *mPendingFrames.begin(); 34950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 35050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 35150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame->release(); 35250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame = NULL; 35350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 35450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 35550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 35650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::readBlock() { 35750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber CHECK(mPendingFrames.empty()); 35850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 3595279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockIter.eos()) { 360093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return ERROR_END_OF_STREAM; 361093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 362093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 3635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::Block *block = mBlockIter.block(); 36450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 3655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t timeUs = mBlockIter.blockTimeUs(); 366093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 367d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber for (int i = 0; i < block->GetFrameCount(); ++i) { 368d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber const mkvparser::Block::Frame &frame = block->GetFrame(i); 369b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 370d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber MediaBuffer *mbuf = new MediaBuffer(frame.len); 371d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mbuf->meta_data()->setInt64(kKeyTime, timeUs); 372d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mbuf->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey()); 373093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 374d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long n = frame.Read(mExtractor->mReader, (unsigned char *)mbuf->data()); 375d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (n != 0) { 376d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mPendingFrames.clear(); 37750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 378d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockIter.advance(); 379d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber return ERROR_IO; 38050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 38150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 38250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.push_back(mbuf); 38350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 38450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 385d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockIter.advance(); 38650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 38750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return OK; 38850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 38950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 39050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::read( 39150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer **out, const ReadOptions *options) { 39250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = NULL; 39350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 39450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber int64_t seekTimeUs; 39550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber ReadOptions::SeekMode mode; 396d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode) 397d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber && !mExtractor->isLiveStreaming()) { 39850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 39950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mBlockIter.seek(seekTimeUs); 40050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 40150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 40250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberagain: 40350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber while (mPendingFrames.empty()) { 40450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber status_t err = readBlock(); 40550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 40650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (err != OK) { 40750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 40850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 40950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return err; 41050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 41150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 41250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 41350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer *frame = *mPendingFrames.begin(); 41450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 41550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 41650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t size = frame->range_length(); 41750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 41850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (mType != AVC) { 41950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = frame; 42050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 42150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return OK; 42250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 42350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 42450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (size < mNALSizeLen) { 42550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame->release(); 42650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame = NULL; 42750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 42850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return ERROR_MALFORMED; 42950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 43050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 43150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // In the case of AVC content, each NAL unit is prefixed by 43250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // mNALSizeLen bytes of length. We want to prefix the data with 43350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // a four-byte 0x00000001 startcode instead of the length prefix. 43450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // mNALSizeLen ranges from 1 through 4 bytes, so add an extra 43550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // 3 bytes of padding to the buffer start. 43650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber static const size_t kPadding = 3; 43750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 43850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer *buffer = new MediaBuffer(size + kPadding); 43950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 44050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber int64_t timeUs; 44150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs)); 44250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber int32_t isSync; 44350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)); 44450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 44550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer->meta_data()->setInt64(kKeyTime, timeUs); 44650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 44750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 44850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber memcpy((uint8_t *)buffer->data() + kPadding, 44950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber (const uint8_t *)frame->data() + frame->range_offset(), 45050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size); 45150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 45250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer->set_range(kPadding, size); 45350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 45450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame->release(); 45550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame = NULL; 45650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 45750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber uint8_t *data = (uint8_t *)buffer->data(); 45850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 45950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t NALsize; 46050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber switch (mNALSizeLen) { 46150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber case 1: NALsize = data[kPadding]; break; 46250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber case 2: NALsize = U16_AT(&data[kPadding]); break; 46350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber case 3: NALsize = U24_AT(&data[kPadding]); break; 46450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber case 4: NALsize = U32_AT(&data[kPadding]); break; 46550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber default: 46650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber TRESPASS(); 46750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 46850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 46950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (size < NALsize + mNALSizeLen) { 47050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer->release(); 47150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer = NULL; 47250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 47350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return ERROR_MALFORMED; 47450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 47550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 47650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (size > NALsize + mNALSizeLen) { 47750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber LOGW("discarding %d bytes of data.", size - NALsize - mNALSizeLen); 47850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 47950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 48050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber // actual data starts at &data[kPadding + mNALSizeLen] 48150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 48250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber memcpy(&data[mNALSizeLen - 1], "\x00\x00\x00\x01", 4); 48350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber buffer->set_range(mNALSizeLen - 1, NALsize + 4); 48450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 48550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = buffer; 486093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 487093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 488093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 489093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 490093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 491093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 492093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source) 493093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mDataSource(source), 494093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mReader(new DataSourceReader(mDataSource)), 4955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mSegment(NULL), 4965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mExtractedThumbnails(false) { 497d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber off64_t size; 498d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mIsLiveStreaming = 499d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber (mDataSource->flags() 500d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber & (DataSource::kWantsPrefetching 501d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber | DataSource::kIsCachingDataSource)) 502d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber && mDataSource->getSize(&size) != OK; 503d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 504093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 505093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 506093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(mReader, pos) < 0) { 507093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 508093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 509093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 510093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long ret = 511093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::Segment::CreateInstance(mReader, pos, mSegment); 512093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 513093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret) { 514093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(mSegment == NULL); 515093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 516093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 517093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 518d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (isLiveStreaming()) { 519d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber ret = mSegment->ParseHeaders(); 520d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_EQ(ret, 0); 521d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 522d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long len; 523d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber ret = mSegment->LoadCluster(pos, len); 524d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_EQ(ret, 0); 525d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } else { 526d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber ret = mSegment->Load(); 527d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } 528093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 529093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret < 0) { 530093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 531093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 532093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 533093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 534093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 535093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addTracks(); 536093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 537093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 538093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::~MatroskaExtractor() { 539093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 540093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 541093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 542093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mReader; 543093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mReader = NULL; 544093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 545093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 546093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersize_t MatroskaExtractor::countTracks() { 547093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mTracks.size(); 548093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 549093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 550093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MediaSource> MatroskaExtractor::getTrack(size_t index) { 551093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 552093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return NULL; 553093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 554093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 555093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return new MatroskaSource(this, index); 556093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 557093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 558093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getTrackMetaData( 559093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t index, uint32_t flags) { 560093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 561093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return NULL; 562093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 563093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 564d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails 565d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber && !isLiveStreaming()) { 5665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber findThumbnails(); 5675279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mExtractedThumbnails = true; 5685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 5695279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 570093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mTracks.itemAt(index).mMeta; 571093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 572093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 573d42573cace9db2b5948e540c32beaef80f04153cAndreas Huberbool MatroskaExtractor::isLiveStreaming() const { 574d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber return mIsLiveStreaming; 575d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber} 576d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 577093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic void addESDSFromAudioSpecificInfo( 578093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MetaData> &meta, const void *asi, size_t asiSize) { 579093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static const uint8_t kStaticESDS[] = { 580093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x03, 22, 581093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, // ES_ID 582093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 583093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 584093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x04, 17, 585093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x40, // Audio ISO/IEC 14496-3 586093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 587093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 588093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 589093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 590093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x05, 591093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // AudioSpecificInfo (with size prefix) follows 592093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber }; 593093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 594093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(asiSize < 128); 595093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1; 596093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *esds = new uint8_t[esdsSize]; 597093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber memcpy(esds, kStaticESDS, sizeof(kStaticESDS)); 598093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *ptr = esds + sizeof(kStaticESDS); 599093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *ptr++ = asiSize; 600093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber memcpy(ptr, asi, asiSize); 601093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 602093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyESDS, 0, esds, esdsSize); 603093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 604093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete[] esds; 605093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber esds = NULL; 606093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 607093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 608093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid addVorbisCodecInfo( 609093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MetaData> &meta, 610093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const void *_codecPrivate, size_t codecPrivateSize) { 611093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // printf("vorbis private data follows:\n"); 612093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // hexdump(_codecPrivate, codecPrivateSize); 613093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 614093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize >= 3); 615093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 616093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate; 617093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[0] == 0x02); 618093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 619093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t len1 = codecPrivate[1]; 620093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t len2 = codecPrivate[2]; 621093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 622093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize > 3 + len1 + len2); 623093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 624093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[3] == 0x01); 625093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1); 626093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 627093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[len1 + 3] == 0x03); 628093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 629093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[len1 + len2 + 3] == 0x05); 630093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData( 631093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3], 632093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber codecPrivateSize - len1 - len2 - 3); 633093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 634093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 635093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid MatroskaExtractor::addTracks() { 636093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Tracks *tracks = mSegment->GetTracks(); 637093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 638093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber for (size_t index = 0; index < tracks->GetTracksCount(); ++index) { 639093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Track *track = tracks->GetTrackByIndex(index); 640093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 64130ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber if (track == NULL) { 64230ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber // Apparently this is currently valid (if unexpected) behaviour 64330ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber // of the mkv parser lib. 64430ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber continue; 64530ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber } 64630ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber 647093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *const codecID = track->GetCodecId(); 648093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber LOGV("codec id = %s", codecID); 649093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber LOGV("codec name = %s", track->GetCodecNameAsUTF8()); 650093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 651093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t codecPrivateSize; 652093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const unsigned char *codecPrivate = 653ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber track->GetCodecPrivate(codecPrivateSize); 654093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 655093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; 656093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 657093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MetaData> meta = new MetaData; 658093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 659093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber switch (track->GetType()) { 660093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case VIDEO_TRACK: 661093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 662093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::VideoTrack *vtrack = 663093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::VideoTrack *>(track); 664093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 665093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { 666093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 667093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); 668093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("V_VP8", codecID)) { 669093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX); 670093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 671093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 672093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 673093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 674093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyWidth, vtrack->GetWidth()); 675093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyHeight, vtrack->GetHeight()); 676093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 677093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 678093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 679093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case AUDIO_TRACK: 680093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 681093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::AudioTrack *atrack = 682093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::AudioTrack *>(track); 683093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 684093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcmp("A_AAC", codecID)) { 685093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 686093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize >= 2); 687093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 688093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addESDSFromAudioSpecificInfo( 689093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta, codecPrivate, codecPrivateSize); 690093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("A_VORBIS", codecID)) { 691093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); 692093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 693093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize); 694093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 695093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 696093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 697093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 698093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeySampleRate, atrack->GetSamplingRate()); 699093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyChannelCount, atrack->GetChannels()); 700093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 701093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 702093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 703093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber default: 704093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 705093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 706093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 707093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long durationNs = mSegment->GetDuration(); 708093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt64(kKeyDuration, (durationNs + 500) / 1000); 709093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 710093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTracks.push(); 711093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1); 712093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber trackInfo->mTrackNum = track->GetNumber(); 713093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber trackInfo->mMeta = meta; 714093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 715093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 716093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 7175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid MatroskaExtractor::findThumbnails() { 7185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 7195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber TrackInfo *info = &mTracks.editItemAt(i); 7205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 7215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const char *mime; 7225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber CHECK(info->mMeta->findCString(kKeyMIMEType, &mime)); 7235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 7245279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (strncasecmp(mime, "video/", 6)) { 7255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber continue; 7265279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 7275279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 728d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber BlockIterator iter(this, info->mTrackNum); 7295279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int32_t i = 0; 7305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t thumbnailTimeUs = 0; 7315279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber size_t maxBlockSize = 0; 7325279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!iter.eos() && i < 20) { 7335279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (iter.block()->IsKey()) { 7345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber ++i; 7355279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 736d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber size_t blockSize = 0; 737d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber for (int i = 0; i < iter.block()->GetFrameCount(); ++i) { 738d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber blockSize += iter.block()->GetFrame(i).len; 739d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } 740d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 7415279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (blockSize > maxBlockSize) { 7425279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber maxBlockSize = blockSize; 7435279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber thumbnailTimeUs = iter.blockTimeUs(); 7445279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 7455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 7465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber iter.advance(); 7475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 7485279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 7495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 7505279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 7515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 752093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getMetaData() { 753093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MetaData> meta = new MetaData; 754093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MATROSKA); 755093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 756093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return meta; 757093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 758093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 759d42573cace9db2b5948e540c32beaef80f04153cAndreas Huberuint32_t MatroskaExtractor::flags() const { 760d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber uint32_t x = CAN_PAUSE; 761d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (!isLiveStreaming()) { 762d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK; 763d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } 764d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 765d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber return x; 766d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber} 767d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 768093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberbool SniffMatroska( 7695a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 7705a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 771093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader reader(source); 772093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 773093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 774093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(&reader, pos) < 0) { 775093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return false; 776093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 777093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 778093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA); 779093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *confidence = 0.6; 780093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 781093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return true; 782093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 783093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 784093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} // namespace android 785