MatroskaExtractor.cpp revision 5279d1d8c19e5fdbb177805db0da8e8aadac3079
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 25093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/DataSource.h> 26093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaBuffer.h> 27093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaDebug.h> 28093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaDefs.h> 29093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaErrors.h> 30093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaSource.h> 31093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MetaData.h> 32093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <utils/String8.h> 33093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 34093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubernamespace android { 35093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 36093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstruct DataSourceReader : public mkvparser::IMkvReader { 37093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader(const sp<DataSource> &source) 38093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mSource(source) { 39093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 40093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 41093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual int Read(long long position, long length, unsigned char* buffer) { 42093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(position >= 0); 43093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(length >= 0); 44093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 45093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (length == 0) { 46093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 47093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 48093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 49093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber ssize_t n = mSource->readAt(position, buffer, length); 50093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 51093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (n <= 0) { 52093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return -1; 53093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 54093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 55093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 56093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 57093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 58093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual int Length(long long* total, long long* available) { 59093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber off_t size; 60093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (mSource->getSize(&size) != OK) { 61093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return -1; 62093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 63093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 64093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (total) { 65093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *total = size; 66093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 67093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 68093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (available) { 69093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *available = size; 70093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 71093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 72093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 73093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 74093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 75093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate: 76093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<DataSource> mSource; 77093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 78093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader(const DataSourceReader &); 79093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader &operator=(const DataSourceReader &); 80093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; 81093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 82093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 83093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 84093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <ctype.h> 85093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic void hexdump(const void *_data, size_t size) { 86093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const uint8_t *data = (const uint8_t *)_data; 87093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t offset = 0; 88093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber while (offset < size) { 89093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber printf("0x%04x ", offset); 90093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 91093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t n = size - offset; 92093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (n > 16) { 93093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber n = 16; 94093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 95093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 96093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber for (size_t i = 0; i < 16; ++i) { 97093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (i == 8) { 98093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber printf(" "); 99093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 100093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 101093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (offset + i < size) { 102093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber printf("%02x ", data[offset + i]); 103093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 104093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber printf(" "); 105093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 106093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 107093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 108093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber printf(" "); 109093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 110093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber for (size_t i = 0; i < n; ++i) { 111093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (isprint(data[offset + i])) { 112093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber printf("%c", data[offset + i]); 113093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 114093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber printf("."); 115093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 116093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 117093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 118093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber printf("\n"); 119093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 120093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber offset += 16; 121093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 122093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 123093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1245279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberstruct BlockIterator { 1255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator(mkvparser::Segment *segment, unsigned long trackNum); 1265279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1275279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber bool eos() const; 1285279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1295279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void advance(); 1305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void reset(); 1315279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void seek(int64_t seekTimeUs); 1325279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1335279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::Block *block() const; 1345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t blockTimeUs() const; 1355279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1365279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberprivate: 1375279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mkvparser::Segment *mSegment; 1385279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber unsigned long mTrackNum; 1395279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1405279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mkvparser::Cluster *mCluster; 1415279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::BlockEntry *mBlockEntry; 1425279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1435279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator(const BlockIterator &); 1445279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator &operator=(const BlockIterator &); 1455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}; 1465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 147093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstruct MatroskaSource : public MediaSource { 148093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource( 149093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MatroskaExtractor> &extractor, size_t index); 150093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 151093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t start(MetaData *params); 152093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t stop(); 153093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 154093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual sp<MetaData> getFormat(); 155093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 156093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t read( 157093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MediaBuffer **buffer, const ReadOptions *options); 158093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 159093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate: 160093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber enum Type { 161093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber AVC, 162093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber AAC, 163093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber OTHER 164093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber }; 165093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 166093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MatroskaExtractor> mExtractor; 167093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t mTrackIndex; 168093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber Type mType; 1695279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator mBlockIter; 170093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 171093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber status_t advance(); 172093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 173093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource(const MatroskaSource &); 174093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource &operator=(const MatroskaSource &); 175093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; 176093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 177093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaSource::MatroskaSource( 178093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MatroskaExtractor> &extractor, size_t index) 179093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mExtractor(extractor), 180093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTrackIndex(index), 181093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType(OTHER), 1825279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter(mExtractor->mSegment, 1835279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mExtractor->mTracks.itemAt(index).mTrackNum) { 184093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *mime; 185093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(mExtractor->mTracks.itemAt(index).mMeta-> 186093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber findCString(kKeyMIMEType, &mime)); 187093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 188093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 189093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AVC; 190093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 191093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AAC; 192093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 193093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 194093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 195093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::start(MetaData *params) { 1965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter.reset(); 197093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 198093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 199093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 200093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 201093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::stop() { 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( 2125279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mkvparser::Segment *segment, unsigned long trackNum) 2135279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber : mSegment(segment), 2145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mTrackNum(trackNum), 2155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster(NULL), 2165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry(NULL) { 2175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber reset(); 2185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberbool BlockIterator::eos() const { 2215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mCluster == NULL || mCluster->EOS(); 2225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2245279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::advance() { 2255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos()) { 2265279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockEntry != NULL) { 2275279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry = mCluster->GetNext(mBlockEntry); 2285279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } else if (mCluster != NULL) { 2295279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster = mSegment->GetNext(mCluster); 2305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2315279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (eos()) { 2325279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 233093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 235093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mBlockEntry = mCluster->GetFirst(); 236093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 237093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2385279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockEntry != NULL 2395279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber && mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) { 2405279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 241093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2425279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 2435279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2445279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::reset() { 2465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster = mSegment->GetFirst(); 2475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry = mCluster->GetFirst(); 248093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos() && block()->GetTrackNumber() != mTrackNum) { 2505279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber advance(); 251093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2525279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 253093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2545279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::seek(int64_t seekTimeUs) { 2555279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster = mSegment->GetCluster(seekTimeUs * 1000ll); 2565279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry = mCluster != NULL ? mCluster->GetFirst() : NULL; 2575279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2585279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos() && block()->GetTrackNumber() != mTrackNum) { 2595279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber advance(); 2605279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 2615279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2625279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos() && !mBlockEntry->GetBlock()->IsKey()) { 2635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber advance(); 2645279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 265093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 266093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2675279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberconst mkvparser::Block *BlockIterator::block() const { 2685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber CHECK(!eos()); 2695279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2705279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mBlockEntry->GetBlock(); 2715279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2725279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2735279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberint64_t BlockIterator::blockTimeUs() const { 2745279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll; 2755279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2765279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2775279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber//////////////////////////////////////////////////////////////////////////////// 2785279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 279093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::read( 280093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MediaBuffer **out, const ReadOptions *options) { 281093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *out = NULL; 282093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 283093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber int64_t seekTimeUs; 284093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (options && options->getSeekTo(&seekTimeUs)) { 2855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter.seek(seekTimeUs); 286093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 287093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockIter.eos()) { 289093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return ERROR_END_OF_STREAM; 290093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 291093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::Block *block = mBlockIter.block(); 293093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t size = block->GetSize(); 2945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t timeUs = mBlockIter.blockTimeUs(); 295093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 296093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MediaBuffer *buffer = new MediaBuffer(size + 2); 2975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber buffer->meta_data()->setInt64(kKeyTime, timeUs); 298093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 299093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long res = block->Read( 300093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mExtractor->mReader, (unsigned char *)buffer->data() + 2); 301093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 302093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (res != 0) { 303093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return ERROR_END_OF_STREAM; 304093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 305093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 306093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber buffer->set_range(2, size); 307093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 308093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (mType == AVC) { 309093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(size >= 2); 310093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 311093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *data = (uint8_t *)buffer->data(); 312093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 313093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber unsigned NALsize = data[2] << 8 | data[3]; 314093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK_EQ(size, NALsize + 2); 315093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 316093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber memcpy(data, "\x00\x00\x00\x01", 4); 317093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber buffer->set_range(0, size + 2); 318093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (mType == AAC) { 319093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // There's strange junk at the beginning... 320093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 321093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const uint8_t *data = (const uint8_t *)buffer->data() + 2; 322093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t offset = 0; 323093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber while (offset < size && data[offset] != 0x21) { 324093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber ++offset; 325093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 326093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber buffer->set_range(2 + offset, size - offset); 327093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 328093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 329093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *out = buffer; 330093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 331093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#if 0 332093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber hexdump((const uint8_t *)buffer->data() + buffer->range_offset(), 333093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber buffer->range_length()); 334093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#endif 335093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 3365279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter.advance(); 337093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 338093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 339093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 340093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 341093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 342093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 343093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source) 344093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mDataSource(source), 345093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mReader(new DataSourceReader(mDataSource)), 3465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mSegment(NULL), 3475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mExtractedThumbnails(false) { 348093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 349093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 350093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(mReader, pos) < 0) { 351093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 352093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 353093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 354093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long ret = 355093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::Segment::CreateInstance(mReader, pos, mSegment); 356093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 357093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret) { 358093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(mSegment == NULL); 359093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 360093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 361093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 362093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber ret = mSegment->Load(); 363093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 364093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret < 0) { 365093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 366093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 367093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 368093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 369093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 370093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addTracks(); 371093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 372093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 373093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::~MatroskaExtractor() { 374093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 375093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 376093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 377093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mReader; 378093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mReader = NULL; 379093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 380093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 381093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersize_t MatroskaExtractor::countTracks() { 382093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mTracks.size(); 383093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 384093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 385093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MediaSource> MatroskaExtractor::getTrack(size_t index) { 386093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 387093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return NULL; 388093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 389093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 390093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return new MatroskaSource(this, index); 391093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 392093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 393093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getTrackMetaData( 394093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t index, uint32_t flags) { 395093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 396093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return NULL; 397093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 398093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 3995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails) { 4005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber findThumbnails(); 4015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mExtractedThumbnails = true; 4025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 4035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 404093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mTracks.itemAt(index).mMeta; 405093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 406093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 407093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic void addESDSFromAudioSpecificInfo( 408093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MetaData> &meta, const void *asi, size_t asiSize) { 409093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static const uint8_t kStaticESDS[] = { 410093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x03, 22, 411093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, // ES_ID 412093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 413093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 414093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x04, 17, 415093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x40, // Audio ISO/IEC 14496-3 416093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 417093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 418093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 419093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 420093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x05, 421093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // AudioSpecificInfo (with size prefix) follows 422093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber }; 423093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 424093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(asiSize < 128); 425093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1; 426093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *esds = new uint8_t[esdsSize]; 427093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber memcpy(esds, kStaticESDS, sizeof(kStaticESDS)); 428093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *ptr = esds + sizeof(kStaticESDS); 429093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *ptr++ = asiSize; 430093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber memcpy(ptr, asi, asiSize); 431093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 432093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyESDS, 0, esds, esdsSize); 433093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 434093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete[] esds; 435093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber esds = NULL; 436093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 437093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 438093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid addVorbisCodecInfo( 439093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MetaData> &meta, 440093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const void *_codecPrivate, size_t codecPrivateSize) { 441093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // printf("vorbis private data follows:\n"); 442093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // hexdump(_codecPrivate, codecPrivateSize); 443093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 444093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize >= 3); 445093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 446093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate; 447093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[0] == 0x02); 448093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 449093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t len1 = codecPrivate[1]; 450093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t len2 = codecPrivate[2]; 451093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 452093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize > 3 + len1 + len2); 453093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 454093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[3] == 0x01); 455093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1); 456093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 457093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[len1 + 3] == 0x03); 458093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 459093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[len1 + len2 + 3] == 0x05); 460093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData( 461093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3], 462093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber codecPrivateSize - len1 - len2 - 3); 463093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 464093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 465093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid MatroskaExtractor::addTracks() { 466093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Tracks *tracks = mSegment->GetTracks(); 467093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 468093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber for (size_t index = 0; index < tracks->GetTracksCount(); ++index) { 469093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Track *track = tracks->GetTrackByIndex(index); 470093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 471093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *const codecID = track->GetCodecId(); 472093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber LOGV("codec id = %s", codecID); 473093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber LOGV("codec name = %s", track->GetCodecNameAsUTF8()); 474093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 475093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t codecPrivateSize; 476093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const unsigned char *codecPrivate = 477093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber track->GetCodecPrivate(&codecPrivateSize); 478093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 479093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; 480093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 481093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MetaData> meta = new MetaData; 482093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 483093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber switch (track->GetType()) { 484093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case VIDEO_TRACK: 485093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 486093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::VideoTrack *vtrack = 487093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::VideoTrack *>(track); 488093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 489093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { 490093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 491093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); 492093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("V_VP8", codecID)) { 493093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX); 494093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 495093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 496093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 497093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 498093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyWidth, vtrack->GetWidth()); 499093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyHeight, vtrack->GetHeight()); 500093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 501093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 502093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 503093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case AUDIO_TRACK: 504093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 505093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::AudioTrack *atrack = 506093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::AudioTrack *>(track); 507093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 508093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcmp("A_AAC", codecID)) { 509093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 510093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize >= 2); 511093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 512093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addESDSFromAudioSpecificInfo( 513093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta, codecPrivate, codecPrivateSize); 514093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("A_VORBIS", codecID)) { 515093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); 516093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 517093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize); 518093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 519093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 520093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 521093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 522093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeySampleRate, atrack->GetSamplingRate()); 523093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyChannelCount, atrack->GetChannels()); 524093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 525093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 526093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 527093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber default: 528093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 529093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 530093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 531093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long durationNs = mSegment->GetDuration(); 532093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt64(kKeyDuration, (durationNs + 500) / 1000); 533093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 534093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTracks.push(); 535093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1); 536093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber trackInfo->mTrackNum = track->GetNumber(); 537093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber trackInfo->mMeta = meta; 538093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 539093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 540093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 5415279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid MatroskaExtractor::findThumbnails() { 5425279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 5435279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber TrackInfo *info = &mTracks.editItemAt(i); 5445279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 5455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const char *mime; 5465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber CHECK(info->mMeta->findCString(kKeyMIMEType, &mime)); 5475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 5485279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (strncasecmp(mime, "video/", 6)) { 5495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber continue; 5505279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 5515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 5525279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator iter(mSegment, info->mTrackNum); 5535279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int32_t i = 0; 5545279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t thumbnailTimeUs = 0; 5555279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber size_t maxBlockSize = 0; 5565279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!iter.eos() && i < 20) { 5575279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (iter.block()->IsKey()) { 5585279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber ++i; 5595279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 5605279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber size_t blockSize = iter.block()->GetSize(); 5615279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (blockSize > maxBlockSize) { 5625279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber maxBlockSize = blockSize; 5635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber thumbnailTimeUs = iter.blockTimeUs(); 5645279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 5655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 5665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber iter.advance(); 5675279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 5685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 5695279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 5705279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 5715279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 572093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getMetaData() { 573093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MetaData> meta = new MetaData; 574093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MATROSKA); 575093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 576093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return meta; 577093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 578093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 579093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberbool SniffMatroska( 580093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 581093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader reader(source); 582093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 583093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 584093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(&reader, pos) < 0) { 585093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return false; 586093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 587093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 588093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA); 589093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *confidence = 0.6; 590093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 591093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return true; 592093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 593093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 594093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} // namespace android 595