MatroskaExtractor.cpp revision 792e33fd19e57e0d615d401a54ab567d04f16251
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(); 9674a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber void seek(int64_t seekTimeUs, bool seekToKeyFrame); 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; 14074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber bool mIsAudio; 1415279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator mBlockIter; 142b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber size_t mNALSizeLen; // for type AVC 143093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 14450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber List<MediaBuffer *> mPendingFrames; 14550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 146093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber status_t advance(); 147093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 14850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber status_t readBlock(); 14950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber void clearPendingFrames(); 15050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 151093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource(const MatroskaSource &); 152093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource &operator=(const MatroskaSource &); 153093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; 154093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 155093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaSource::MatroskaSource( 156093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MatroskaExtractor> &extractor, size_t index) 157093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mExtractor(extractor), 158093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTrackIndex(index), 159093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType(OTHER), 16074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber mIsAudio(false), 161d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockIter(mExtractor.get(), 162b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mExtractor->mTracks.itemAt(index).mTrackNum), 163b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mNALSizeLen(0) { 164b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta; 165b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 166093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *mime; 167b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 168093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 16974a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber mIsAudio = !strncasecmp("audio/", mime, 6); 17074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber 171093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 172093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AVC; 173b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 174b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber uint32_t dummy; 175b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber const uint8_t *avcc; 176b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber size_t avccSize; 177b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK(meta->findData( 178b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber kKeyAVCC, &dummy, (const void **)&avcc, &avccSize)); 179b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 180b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK_GE(avccSize, 5u); 181b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 182b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mNALSizeLen = 1 + (avcc[4] & 3); 183b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber LOGV("mNALSizeLen = %d", mNALSizeLen); 184093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 185093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AAC; 186093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 187093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 188093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 18950c8bea8fba2fcafb14696399028bdbc094dc995Andreas HuberMatroskaSource::~MatroskaSource() { 19050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 19150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 19250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 193093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::start(MetaData *params) { 1945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter.reset(); 195093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 196093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 197093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 198093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 199093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::stop() { 20050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 20150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 202093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 203093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 204093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 205093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaSource::getFormat() { 206093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mExtractor->mTracks.itemAt(mTrackIndex).mMeta; 207093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 208093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2095279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber//////////////////////////////////////////////////////////////////////////////// 2105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas HuberBlockIterator::BlockIterator( 212d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber MatroskaExtractor *extractor, unsigned long trackNum) 213d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber : mExtractor(extractor), 2145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mTrackNum(trackNum), 2155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster(NULL), 216d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntry(NULL), 217d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntryIndex(0) { 2185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber reset(); 2195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberbool BlockIterator::eos() const { 2225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mCluster == NULL || mCluster->EOS(); 2235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2245279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::advance() { 226d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 227d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber advance_l(); 228d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber} 229d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 230d42573cace9db2b5948e540c32beaef80f04153cAndreas Hubervoid BlockIterator::advance_l() { 231d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber for (;;) { 232d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry); 233d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber LOGV("GetEntry returned %ld", res); 234d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 235d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long long pos; 236d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long len; 237d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (res < 0) { 238d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber // Need to parse this cluster some more 239d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 240d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL); 241d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 242d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber res = mCluster->Parse(pos, len); 243d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber LOGV("Parse returned %ld", res); 244d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 245d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (res < 0) { 246d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber // I/O error 247d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 248d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber LOGE("Cluster::Parse returned result %ld", res); 2495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 250d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = NULL; 2515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 252093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2535279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 254d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber continue; 255d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } else if (res == 0) { 256d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber // We're done with this cluster 257d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 258d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber const mkvparser::Cluster *nextCluster; 259d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber res = mExtractor->mSegment->ParseNext( 260d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster, nextCluster, pos, len); 261d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber LOGV("ParseNext returned %ld", res); 262d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 263d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (res > 0) { 264d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber // EOF 265d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 266d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = NULL; 267d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber break; 268d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } 269d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 270d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_EQ(res, 0); 271d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(nextCluster != NULL); 272d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(!nextCluster->EOS()); 273d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 274d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = nextCluster; 275d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 276d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber res = mCluster->Parse(pos, len); 277d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber LOGV("Parse (2) returned %ld", res); 278d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_GE(res, 0); 279d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 280d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntryIndex = 0; 281d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber continue; 282093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 283093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 284d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(mBlockEntry != NULL); 285d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(mBlockEntry->GetBlock() != NULL); 286d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber ++mBlockEntryIndex; 287d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 288d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) { 2895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 290093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 2925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::reset() { 295d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 296093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 297d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = mExtractor->mSegment->GetFirst(); 2982ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber mBlockEntry = NULL; 299d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntryIndex = 0; 300d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 301d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber do { 302d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber advance_l(); 303d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } while (!eos() && block()->GetTrackNumber() != mTrackNum); 3045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 305093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 30674a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Hubervoid BlockIterator::seek(int64_t seekTimeUs, bool seekToKeyFrame) { 307d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 308d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 309d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll); 3102ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber mBlockEntry = NULL; 311d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntryIndex = 0; 3125279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3132ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber do { 314d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber advance_l(); 3155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 3162ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber while (!eos() && block()->GetTrackNumber() != mTrackNum); 3175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 31874a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber if (seekToKeyFrame) { 31974a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber while (!eos() && !mBlockEntry->GetBlock()->IsKey()) { 32074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber advance_l(); 32174a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber } 3225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 323093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 324093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 3255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberconst mkvparser::Block *BlockIterator::block() const { 3265279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber CHECK(!eos()); 3275279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3285279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mBlockEntry->GetBlock(); 3295279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 3305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3315279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberint64_t BlockIterator::blockTimeUs() const { 3325279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll; 3335279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 3345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3355279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber//////////////////////////////////////////////////////////////////////////////// 3365279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 337b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huberstatic unsigned U24_AT(const uint8_t *ptr) { 338b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; 339b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber} 340b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 34150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatic size_t clz(uint8_t x) { 34250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber size_t numLeadingZeroes = 0; 343093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 34450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber while (!(x & 0x80)) { 34550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber ++numLeadingZeroes; 34650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber x = x << 1; 347093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 348093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 34950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return numLeadingZeroes; 35050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 35150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 35250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Hubervoid MatroskaSource::clearPendingFrames() { 35350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber while (!mPendingFrames.empty()) { 35450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer *frame = *mPendingFrames.begin(); 35550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 35650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 35750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame->release(); 35850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame = NULL; 35950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 36050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 36150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 36250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::readBlock() { 36350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber CHECK(mPendingFrames.empty()); 36450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 3655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockIter.eos()) { 366093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return ERROR_END_OF_STREAM; 367093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 368093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 3695279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::Block *block = mBlockIter.block(); 37050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 3715279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t timeUs = mBlockIter.blockTimeUs(); 372093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 373d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber for (int i = 0; i < block->GetFrameCount(); ++i) { 374d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber const mkvparser::Block::Frame &frame = block->GetFrame(i); 375b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 376d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber MediaBuffer *mbuf = new MediaBuffer(frame.len); 377d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mbuf->meta_data()->setInt64(kKeyTime, timeUs); 378d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mbuf->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey()); 379093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 380d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long n = frame.Read(mExtractor->mReader, (unsigned char *)mbuf->data()); 381d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (n != 0) { 382d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mPendingFrames.clear(); 38350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 384d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockIter.advance(); 385d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber return ERROR_IO; 38650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 38750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 38850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.push_back(mbuf); 38950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 39050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 391d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockIter.advance(); 39250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 39350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return OK; 39450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 39550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 39650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::read( 39750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer **out, const ReadOptions *options) { 39850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = NULL; 39950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 40050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber int64_t seekTimeUs; 40150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber ReadOptions::SeekMode mode; 402d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode) 403d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber && !mExtractor->isLiveStreaming()) { 40450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 40574a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber 40674a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber // Apparently keyframe indication in audio tracks is unreliable, 40774a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber // fortunately in all our currently supported audio encodings every 40874a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber // frame is effectively a keyframe. 40974a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber mBlockIter.seek(seekTimeUs, !mIsAudio); 41050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 41150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 41250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberagain: 41350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber while (mPendingFrames.empty()) { 41450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber status_t err = readBlock(); 41550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 41650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (err != OK) { 41750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 41850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 41950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return err; 42050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 42150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 42250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 42350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber MediaBuffer *frame = *mPendingFrames.begin(); 42450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 42550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 42650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (mType != AVC) { 42750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = frame; 42850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 42950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return OK; 43050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 43150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 432792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // Each input frame contains one or more NAL fragments, each fragment 433792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // is prefixed by mNALSizeLen bytes giving the fragment length, 434792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // followed by a corresponding number of bytes containing the fragment. 435792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // We output all these fragments into a single large buffer separated 436792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // by startcodes (0x00 0x00 0x00 0x01). 437792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber 438792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber const uint8_t *srcPtr = 439792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber (const uint8_t *)frame->data() + frame->range_offset(); 440792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber 441792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber size_t srcSize = frame->range_length(); 442792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber 443792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber size_t dstSize = 0; 444792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber MediaBuffer *buffer = NULL; 445792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber uint8_t *dstPtr = NULL; 446792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber 447792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber for (int32_t pass = 0; pass < 2; ++pass) { 448792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber size_t srcOffset = 0; 449792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber size_t dstOffset = 0; 450792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber while (srcOffset + mNALSizeLen <= srcSize) { 451792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber size_t NALsize; 452792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber switch (mNALSizeLen) { 453792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber case 1: NALsize = srcPtr[srcOffset]; break; 454792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber case 2: NALsize = U16_AT(srcPtr + srcOffset); break; 455792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber case 3: NALsize = U24_AT(srcPtr + srcOffset); break; 456792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber case 4: NALsize = U32_AT(srcPtr + srcOffset); break; 457792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber default: 458792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber TRESPASS(); 459792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 46050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 461792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber if (srcOffset + mNALSizeLen + NALsize > srcSize) { 462792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber break; 463792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 46450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 465792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber if (pass == 1) { 466792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber memcpy(&dstPtr[dstOffset], "\x00\x00\x00\x01", 4); 46750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 468792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber memcpy(&dstPtr[dstOffset + 4], 469792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber &srcPtr[srcOffset + mNALSizeLen], 470792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber NALsize); 471792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 47250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 473792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber dstOffset += 4; // 0x00 00 00 01 474792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber dstOffset += NALsize; 47550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 476792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber srcOffset += mNALSizeLen + NALsize; 477792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 47850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 479792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber if (srcOffset < srcSize) { 480792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // There were trailing bytes or not enough data to complete 481792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // a fragment. 48250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 483792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber frame->release(); 484792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber frame = NULL; 48550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 486792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber return ERROR_MALFORMED; 487792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 48850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 489792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber if (pass == 0) { 490792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber dstSize = dstOffset; 49150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 492792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber buffer = new MediaBuffer(dstSize); 49350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 494792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber int64_t timeUs; 495792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs)); 496792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber int32_t isSync; 497792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)); 49850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 499792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber buffer->meta_data()->setInt64(kKeyTime, timeUs); 500792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 50150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 502792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber dstPtr = (uint8_t *)buffer->data(); 503792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 50450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 50550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 506792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber frame->release(); 507792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber frame = NULL; 50850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 50950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = buffer; 510093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 511093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 512093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 513093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 514093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 515093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 516093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source) 517093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mDataSource(source), 518093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mReader(new DataSourceReader(mDataSource)), 5195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mSegment(NULL), 5208c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber mExtractedThumbnails(false), 5218c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber mIsWebm(false) { 522d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber off64_t size; 523d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mIsLiveStreaming = 524d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber (mDataSource->flags() 525d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber & (DataSource::kWantsPrefetching 526d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber | DataSource::kIsCachingDataSource)) 527d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber && mDataSource->getSize(&size) != OK; 528d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 529093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 530093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 531093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(mReader, pos) < 0) { 532093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 533093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 534093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 5358c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber if (ebmlHeader.m_docType && !strcmp("webm", ebmlHeader.m_docType)) { 5368c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber mIsWebm = true; 5378c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber } 5388c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber 539093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long ret = 540093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::Segment::CreateInstance(mReader, pos, mSegment); 541093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 542093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret) { 543093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(mSegment == NULL); 544093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 545093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 546093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 547d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (isLiveStreaming()) { 548d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber ret = mSegment->ParseHeaders(); 549d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_EQ(ret, 0); 550d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 551d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long len; 552d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber ret = mSegment->LoadCluster(pos, len); 553d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_EQ(ret, 0); 554d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } else { 555d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber ret = mSegment->Load(); 556d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } 557093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 558093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret < 0) { 559093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 560093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 561093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 562093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 563093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 56474a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber#if 0 56574a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber const mkvparser::SegmentInfo *info = mSegment->GetInfo(); 56674a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber LOGI("muxing app: %s, writing app: %s", 56774a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber info->GetMuxingAppAsUTF8(), 56874a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber info->GetWritingAppAsUTF8()); 56974a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber#endif 57074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber 571093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addTracks(); 572093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 573093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 574093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::~MatroskaExtractor() { 575093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 576093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 577093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 578093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mReader; 579093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mReader = NULL; 580093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 581093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 582093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersize_t MatroskaExtractor::countTracks() { 583093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mTracks.size(); 584093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 585093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 586093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MediaSource> MatroskaExtractor::getTrack(size_t index) { 587093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 588093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return NULL; 589093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 590093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 591093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return new MatroskaSource(this, index); 592093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 593093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 594093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getTrackMetaData( 595093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t index, uint32_t flags) { 596093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 597093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return NULL; 598093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 599093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 600d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails 601d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber && !isLiveStreaming()) { 6025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber findThumbnails(); 6035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mExtractedThumbnails = true; 6045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 6055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 606093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mTracks.itemAt(index).mMeta; 607093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 608093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 609d42573cace9db2b5948e540c32beaef80f04153cAndreas Huberbool MatroskaExtractor::isLiveStreaming() const { 610d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber return mIsLiveStreaming; 611d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber} 612d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 613093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic void addESDSFromAudioSpecificInfo( 614093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MetaData> &meta, const void *asi, size_t asiSize) { 615093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static const uint8_t kStaticESDS[] = { 616093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x03, 22, 617093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, // ES_ID 618093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 619093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 620093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x04, 17, 621093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x40, // Audio ISO/IEC 14496-3 622093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 623093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 624093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 625093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 626093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x05, 627093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // AudioSpecificInfo (with size prefix) follows 628093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber }; 629093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 63082ac8bf2da940c4439786c346f739f4a496864adAndreas Huber // Make sure all sizes can be coded in a single byte. 63182ac8bf2da940c4439786c346f739f4a496864adAndreas Huber CHECK(asiSize + 22 - 2 < 128); 632093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1; 633093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *esds = new uint8_t[esdsSize]; 634093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber memcpy(esds, kStaticESDS, sizeof(kStaticESDS)); 635093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *ptr = esds + sizeof(kStaticESDS); 636093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *ptr++ = asiSize; 637093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber memcpy(ptr, asi, asiSize); 638093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 63982ac8bf2da940c4439786c346f739f4a496864adAndreas Huber // Increment by codecPrivateSize less 2 bytes that are accounted for 64082ac8bf2da940c4439786c346f739f4a496864adAndreas Huber // already in lengths of 22/17 64182ac8bf2da940c4439786c346f739f4a496864adAndreas Huber esds[1] += asiSize - 2; 64282ac8bf2da940c4439786c346f739f4a496864adAndreas Huber esds[6] += asiSize - 2; 64382ac8bf2da940c4439786c346f739f4a496864adAndreas Huber 644093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyESDS, 0, esds, esdsSize); 645093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 646093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete[] esds; 647093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber esds = NULL; 648093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 649093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 650093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid addVorbisCodecInfo( 651093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MetaData> &meta, 652093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const void *_codecPrivate, size_t codecPrivateSize) { 653093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // printf("vorbis private data follows:\n"); 654093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // hexdump(_codecPrivate, codecPrivateSize); 655093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 656093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize >= 3); 657093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 658093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate; 659093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[0] == 0x02); 660093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 661093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t len1 = codecPrivate[1]; 662093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t len2 = codecPrivate[2]; 663093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 664093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize > 3 + len1 + len2); 665093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 666093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[3] == 0x01); 667093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1); 668093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 669093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[len1 + 3] == 0x03); 670093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 671093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[len1 + len2 + 3] == 0x05); 672093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData( 673093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3], 674093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber codecPrivateSize - len1 - len2 - 3); 675093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 676093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 677093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid MatroskaExtractor::addTracks() { 678093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Tracks *tracks = mSegment->GetTracks(); 679093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 680093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber for (size_t index = 0; index < tracks->GetTracksCount(); ++index) { 681093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Track *track = tracks->GetTrackByIndex(index); 682093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 68330ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber if (track == NULL) { 68430ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber // Apparently this is currently valid (if unexpected) behaviour 68530ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber // of the mkv parser lib. 68630ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber continue; 68730ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber } 68830ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber 689093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *const codecID = track->GetCodecId(); 690093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber LOGV("codec id = %s", codecID); 691093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber LOGV("codec name = %s", track->GetCodecNameAsUTF8()); 692093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 693093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t codecPrivateSize; 694093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const unsigned char *codecPrivate = 695ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber track->GetCodecPrivate(codecPrivateSize); 696093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 697093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; 698093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 699093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MetaData> meta = new MetaData; 700093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 701093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber switch (track->GetType()) { 702093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case VIDEO_TRACK: 703093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 704093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::VideoTrack *vtrack = 705093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::VideoTrack *>(track); 706093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 707093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { 708093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 709093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); 710093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("V_VP8", codecID)) { 711093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX); 712093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 713093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 714093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 715093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 716093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyWidth, vtrack->GetWidth()); 717093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyHeight, vtrack->GetHeight()); 718093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 719093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 720093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 721093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case AUDIO_TRACK: 722093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 723093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::AudioTrack *atrack = 724093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::AudioTrack *>(track); 725093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 726093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcmp("A_AAC", codecID)) { 727093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 728093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize >= 2); 729093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 730093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addESDSFromAudioSpecificInfo( 731093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta, codecPrivate, codecPrivateSize); 732093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("A_VORBIS", codecID)) { 733093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); 734093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 735093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize); 736093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 737093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 738093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 739093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 740093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeySampleRate, atrack->GetSamplingRate()); 741093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyChannelCount, atrack->GetChannels()); 742093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 743093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 744093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 745093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber default: 746093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 747093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 748093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 749093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long durationNs = mSegment->GetDuration(); 750093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt64(kKeyDuration, (durationNs + 500) / 1000); 751093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 752093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTracks.push(); 753093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1); 754093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber trackInfo->mTrackNum = track->GetNumber(); 755093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber trackInfo->mMeta = meta; 756093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 757093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 758093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 7595279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid MatroskaExtractor::findThumbnails() { 7605279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 7615279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber TrackInfo *info = &mTracks.editItemAt(i); 7625279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 7635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const char *mime; 7645279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber CHECK(info->mMeta->findCString(kKeyMIMEType, &mime)); 7655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 7665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (strncasecmp(mime, "video/", 6)) { 7675279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber continue; 7685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 7695279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 770d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber BlockIterator iter(this, info->mTrackNum); 7715279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int32_t i = 0; 7725279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t thumbnailTimeUs = 0; 7735279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber size_t maxBlockSize = 0; 7745279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!iter.eos() && i < 20) { 7755279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (iter.block()->IsKey()) { 7765279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber ++i; 7775279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 778d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber size_t blockSize = 0; 779d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber for (int i = 0; i < iter.block()->GetFrameCount(); ++i) { 780d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber blockSize += iter.block()->GetFrame(i).len; 781d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } 782d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 7835279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (blockSize > maxBlockSize) { 7845279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber maxBlockSize = blockSize; 7855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber thumbnailTimeUs = iter.blockTimeUs(); 7865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 7875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 7885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber iter.advance(); 7895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 7905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 7915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 7925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 7935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 794093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getMetaData() { 795093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MetaData> meta = new MetaData; 7968c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber 7978c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber meta->setCString( 7988c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber kKeyMIMEType, 7998c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA); 800093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 801093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return meta; 802093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 803093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 804d42573cace9db2b5948e540c32beaef80f04153cAndreas Huberuint32_t MatroskaExtractor::flags() const { 805d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber uint32_t x = CAN_PAUSE; 806d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (!isLiveStreaming()) { 807d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK; 808d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } 809d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 810d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber return x; 811d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber} 812d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 813093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberbool SniffMatroska( 8145a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 8155a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 816093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader reader(source); 817093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 818093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 819093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(&reader, pos) < 0) { 820093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return false; 821093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 822093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 823093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA); 824093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *confidence = 0.6; 825093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 826093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return true; 827093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 828093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 829093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} // namespace android 830