1072f5247ef893e683728263a540bb93daafda376Andreas Huber/* 2072f5247ef893e683728263a540bb93daafda376Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3072f5247ef893e683728263a540bb93daafda376Andreas Huber * 4072f5247ef893e683728263a540bb93daafda376Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5072f5247ef893e683728263a540bb93daafda376Andreas Huber * you may not use this file except in compliance with the License. 6072f5247ef893e683728263a540bb93daafda376Andreas Huber * You may obtain a copy of the License at 7072f5247ef893e683728263a540bb93daafda376Andreas Huber * 8072f5247ef893e683728263a540bb93daafda376Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9072f5247ef893e683728263a540bb93daafda376Andreas Huber * 10072f5247ef893e683728263a540bb93daafda376Andreas Huber * Unless required by applicable law or agreed to in writing, software 11072f5247ef893e683728263a540bb93daafda376Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12072f5247ef893e683728263a540bb93daafda376Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13072f5247ef893e683728263a540bb93daafda376Andreas Huber * See the License for the specific language governing permissions and 14072f5247ef893e683728263a540bb93daafda376Andreas Huber * limitations under the License. 15072f5247ef893e683728263a540bb93daafda376Andreas Huber */ 16072f5247ef893e683728263a540bb93daafda376Andreas Huber 17072f5247ef893e683728263a540bb93daafda376Andreas Huber//#define LOG_NDEBUG 0 18072f5247ef893e683728263a540bb93daafda376Andreas Huber#define LOG_TAG "MatroskaExtractor" 19072f5247ef893e683728263a540bb93daafda376Andreas Huber#include <utils/Log.h> 20072f5247ef893e683728263a540bb93daafda376Andreas Huber 21072f5247ef893e683728263a540bb93daafda376Andreas Huber#include "MatroskaExtractor.h" 22072f5247ef893e683728263a540bb93daafda376Andreas Huber 23072f5247ef893e683728263a540bb93daafda376Andreas Huber#include "mkvparser.hpp" 24072f5247ef893e683728263a540bb93daafda376Andreas Huber 257e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber#include <media/stagefright/foundation/ADebug.h> 267e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber#include <media/stagefright/foundation/hexdump.h> 27072f5247ef893e683728263a540bb93daafda376Andreas Huber#include <media/stagefright/DataSource.h> 28072f5247ef893e683728263a540bb93daafda376Andreas Huber#include <media/stagefright/MediaBuffer.h> 29072f5247ef893e683728263a540bb93daafda376Andreas Huber#include <media/stagefright/MediaDefs.h> 30072f5247ef893e683728263a540bb93daafda376Andreas Huber#include <media/stagefright/MediaErrors.h> 31072f5247ef893e683728263a540bb93daafda376Andreas Huber#include <media/stagefright/MediaSource.h> 32072f5247ef893e683728263a540bb93daafda376Andreas Huber#include <media/stagefright/MetaData.h> 337e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber#include <media/stagefright/Utils.h> 34072f5247ef893e683728263a540bb93daafda376Andreas Huber#include <utils/String8.h> 35072f5247ef893e683728263a540bb93daafda376Andreas Huber 36072f5247ef893e683728263a540bb93daafda376Andreas Hubernamespace android { 37072f5247ef893e683728263a540bb93daafda376Andreas Huber 38072f5247ef893e683728263a540bb93daafda376Andreas Huberstruct DataSourceReader : public mkvparser::IMkvReader { 39072f5247ef893e683728263a540bb93daafda376Andreas Huber DataSourceReader(const sp<DataSource> &source) 40072f5247ef893e683728263a540bb93daafda376Andreas Huber : mSource(source) { 41072f5247ef893e683728263a540bb93daafda376Andreas Huber } 42072f5247ef893e683728263a540bb93daafda376Andreas Huber 43072f5247ef893e683728263a540bb93daafda376Andreas Huber virtual int Read(long long position, long length, unsigned char* buffer) { 44072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(position >= 0); 45072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(length >= 0); 46072f5247ef893e683728263a540bb93daafda376Andreas Huber 47072f5247ef893e683728263a540bb93daafda376Andreas Huber if (length == 0) { 48072f5247ef893e683728263a540bb93daafda376Andreas Huber return 0; 49072f5247ef893e683728263a540bb93daafda376Andreas Huber } 50072f5247ef893e683728263a540bb93daafda376Andreas Huber 51072f5247ef893e683728263a540bb93daafda376Andreas Huber ssize_t n = mSource->readAt(position, buffer, length); 52072f5247ef893e683728263a540bb93daafda376Andreas Huber 53072f5247ef893e683728263a540bb93daafda376Andreas Huber if (n <= 0) { 54072f5247ef893e683728263a540bb93daafda376Andreas Huber return -1; 55072f5247ef893e683728263a540bb93daafda376Andreas Huber } 56072f5247ef893e683728263a540bb93daafda376Andreas Huber 57072f5247ef893e683728263a540bb93daafda376Andreas Huber return 0; 58072f5247ef893e683728263a540bb93daafda376Andreas Huber } 59072f5247ef893e683728263a540bb93daafda376Andreas Huber 60072f5247ef893e683728263a540bb93daafda376Andreas Huber virtual int Length(long long* total, long long* available) { 61072f5247ef893e683728263a540bb93daafda376Andreas Huber off_t size; 62072f5247ef893e683728263a540bb93daafda376Andreas Huber if (mSource->getSize(&size) != OK) { 63072f5247ef893e683728263a540bb93daafda376Andreas Huber return -1; 64072f5247ef893e683728263a540bb93daafda376Andreas Huber } 65072f5247ef893e683728263a540bb93daafda376Andreas Huber 66072f5247ef893e683728263a540bb93daafda376Andreas Huber if (total) { 67072f5247ef893e683728263a540bb93daafda376Andreas Huber *total = size; 68072f5247ef893e683728263a540bb93daafda376Andreas Huber } 69072f5247ef893e683728263a540bb93daafda376Andreas Huber 70072f5247ef893e683728263a540bb93daafda376Andreas Huber if (available) { 71072f5247ef893e683728263a540bb93daafda376Andreas Huber *available = size; 72072f5247ef893e683728263a540bb93daafda376Andreas Huber } 73072f5247ef893e683728263a540bb93daafda376Andreas Huber 74072f5247ef893e683728263a540bb93daafda376Andreas Huber return 0; 75072f5247ef893e683728263a540bb93daafda376Andreas Huber } 76072f5247ef893e683728263a540bb93daafda376Andreas Huber 77072f5247ef893e683728263a540bb93daafda376Andreas Huberprivate: 78072f5247ef893e683728263a540bb93daafda376Andreas Huber sp<DataSource> mSource; 79072f5247ef893e683728263a540bb93daafda376Andreas Huber 80072f5247ef893e683728263a540bb93daafda376Andreas Huber DataSourceReader(const DataSourceReader &); 81072f5247ef893e683728263a540bb93daafda376Andreas Huber DataSourceReader &operator=(const DataSourceReader &); 82072f5247ef893e683728263a540bb93daafda376Andreas Huber}; 83072f5247ef893e683728263a540bb93daafda376Andreas Huber 84072f5247ef893e683728263a540bb93daafda376Andreas Huber//////////////////////////////////////////////////////////////////////////////// 85072f5247ef893e683728263a540bb93daafda376Andreas Huber 866bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huberstruct BlockIterator { 876bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber BlockIterator(mkvparser::Segment *segment, unsigned long trackNum); 886bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 896bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber bool eos() const; 906bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 916bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber void advance(); 926bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber void reset(); 936bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber void seek(int64_t seekTimeUs); 946bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 956bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber const mkvparser::Block *block() const; 966bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber int64_t blockTimeUs() const; 976bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 986bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huberprivate: 996bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mkvparser::Segment *mSegment; 1006bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber unsigned long mTrackNum; 1016bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 1026bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mkvparser::Cluster *mCluster; 1036bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber const mkvparser::BlockEntry *mBlockEntry; 1046bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 1056bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber BlockIterator(const BlockIterator &); 1066bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber BlockIterator &operator=(const BlockIterator &); 1076bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber}; 1086bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 109072f5247ef893e683728263a540bb93daafda376Andreas Huberstruct MatroskaSource : public MediaSource { 110072f5247ef893e683728263a540bb93daafda376Andreas Huber MatroskaSource( 111072f5247ef893e683728263a540bb93daafda376Andreas Huber const sp<MatroskaExtractor> &extractor, size_t index); 112072f5247ef893e683728263a540bb93daafda376Andreas Huber 113072f5247ef893e683728263a540bb93daafda376Andreas Huber virtual status_t start(MetaData *params); 114072f5247ef893e683728263a540bb93daafda376Andreas Huber virtual status_t stop(); 115072f5247ef893e683728263a540bb93daafda376Andreas Huber 116072f5247ef893e683728263a540bb93daafda376Andreas Huber virtual sp<MetaData> getFormat(); 117072f5247ef893e683728263a540bb93daafda376Andreas Huber 118072f5247ef893e683728263a540bb93daafda376Andreas Huber virtual status_t read( 119072f5247ef893e683728263a540bb93daafda376Andreas Huber MediaBuffer **buffer, const ReadOptions *options); 120072f5247ef893e683728263a540bb93daafda376Andreas Huber 1217e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huberprotected: 1227e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber virtual ~MatroskaSource(); 1237e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 124072f5247ef893e683728263a540bb93daafda376Andreas Huberprivate: 125072f5247ef893e683728263a540bb93daafda376Andreas Huber enum Type { 126072f5247ef893e683728263a540bb93daafda376Andreas Huber AVC, 127072f5247ef893e683728263a540bb93daafda376Andreas Huber AAC, 128072f5247ef893e683728263a540bb93daafda376Andreas Huber OTHER 129072f5247ef893e683728263a540bb93daafda376Andreas Huber }; 130072f5247ef893e683728263a540bb93daafda376Andreas Huber 131072f5247ef893e683728263a540bb93daafda376Andreas Huber sp<MatroskaExtractor> mExtractor; 132072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t mTrackIndex; 133072f5247ef893e683728263a540bb93daafda376Andreas Huber Type mType; 1346bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber BlockIterator mBlockIter; 1357e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size_t mNALSizeLen; // for type AVC 1367e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 1377e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber List<MediaBuffer *> mPendingFrames; 138072f5247ef893e683728263a540bb93daafda376Andreas Huber 139072f5247ef893e683728263a540bb93daafda376Andreas Huber status_t advance(); 140072f5247ef893e683728263a540bb93daafda376Andreas Huber 1417e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber status_t readBlock(); 1427e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber void clearPendingFrames(); 1437e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 144072f5247ef893e683728263a540bb93daafda376Andreas Huber MatroskaSource(const MatroskaSource &); 145072f5247ef893e683728263a540bb93daafda376Andreas Huber MatroskaSource &operator=(const MatroskaSource &); 146072f5247ef893e683728263a540bb93daafda376Andreas Huber}; 147072f5247ef893e683728263a540bb93daafda376Andreas Huber 148072f5247ef893e683728263a540bb93daafda376Andreas HuberMatroskaSource::MatroskaSource( 149072f5247ef893e683728263a540bb93daafda376Andreas Huber const sp<MatroskaExtractor> &extractor, size_t index) 150072f5247ef893e683728263a540bb93daafda376Andreas Huber : mExtractor(extractor), 151072f5247ef893e683728263a540bb93daafda376Andreas Huber mTrackIndex(index), 152072f5247ef893e683728263a540bb93daafda376Andreas Huber mType(OTHER), 1536bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mBlockIter(mExtractor->mSegment, 1547e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mExtractor->mTracks.itemAt(index).mTrackNum), 1557e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mNALSizeLen(0) { 1567e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta; 1577e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 158072f5247ef893e683728263a540bb93daafda376Andreas Huber const char *mime; 1597e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 160072f5247ef893e683728263a540bb93daafda376Andreas Huber 161072f5247ef893e683728263a540bb93daafda376Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 162072f5247ef893e683728263a540bb93daafda376Andreas Huber mType = AVC; 1637e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 1647e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber uint32_t dummy; 1657e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber const uint8_t *avcc; 1667e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size_t avccSize; 1677e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber CHECK(meta->findData( 1687e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber kKeyAVCC, &dummy, (const void **)&avcc, &avccSize)); 1697e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 1707e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber CHECK_GE(avccSize, 5u); 1717e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 1727e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mNALSizeLen = 1 + (avcc[4] & 3); 1737e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber LOGV("mNALSizeLen = %d", mNALSizeLen); 174072f5247ef893e683728263a540bb93daafda376Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 175072f5247ef893e683728263a540bb93daafda376Andreas Huber mType = AAC; 176072f5247ef893e683728263a540bb93daafda376Andreas Huber } 177072f5247ef893e683728263a540bb93daafda376Andreas Huber} 178072f5247ef893e683728263a540bb93daafda376Andreas Huber 1797e2f9cc81da788006790365ff11f06551fc1bc26Andreas HuberMatroskaSource::~MatroskaSource() { 1807e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber clearPendingFrames(); 1817e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber} 1827e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 183072f5247ef893e683728263a540bb93daafda376Andreas Huberstatus_t MatroskaSource::start(MetaData *params) { 1846bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mBlockIter.reset(); 185072f5247ef893e683728263a540bb93daafda376Andreas Huber 186072f5247ef893e683728263a540bb93daafda376Andreas Huber return OK; 187072f5247ef893e683728263a540bb93daafda376Andreas Huber} 188072f5247ef893e683728263a540bb93daafda376Andreas Huber 189072f5247ef893e683728263a540bb93daafda376Andreas Huberstatus_t MatroskaSource::stop() { 1907e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber clearPendingFrames(); 1917e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 192072f5247ef893e683728263a540bb93daafda376Andreas Huber return OK; 193072f5247ef893e683728263a540bb93daafda376Andreas Huber} 194072f5247ef893e683728263a540bb93daafda376Andreas Huber 195072f5247ef893e683728263a540bb93daafda376Andreas Hubersp<MetaData> MatroskaSource::getFormat() { 196072f5247ef893e683728263a540bb93daafda376Andreas Huber return mExtractor->mTracks.itemAt(mTrackIndex).mMeta; 197072f5247ef893e683728263a540bb93daafda376Andreas Huber} 198072f5247ef893e683728263a540bb93daafda376Andreas Huber 1996bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber//////////////////////////////////////////////////////////////////////////////// 2006bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2016bdf2edba4de7f971639e8a50e938d218b6d7299Andreas HuberBlockIterator::BlockIterator( 2026bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mkvparser::Segment *segment, unsigned long trackNum) 2036bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber : mSegment(segment), 2046bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mTrackNum(trackNum), 2056bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mCluster(NULL), 2066bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mBlockEntry(NULL) { 2076bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber reset(); 2086bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 2096bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2106bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huberbool BlockIterator::eos() const { 2116bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber return mCluster == NULL || mCluster->EOS(); 2126bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 2136bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2146bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Hubervoid BlockIterator::advance() { 2156bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber while (!eos()) { 2166bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if (mBlockEntry != NULL) { 2176bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mBlockEntry = mCluster->GetNext(mBlockEntry); 2186bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } else if (mCluster != NULL) { 2196bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mCluster = mSegment->GetNext(mCluster); 2206bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2216bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if (eos()) { 2226bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber break; 223072f5247ef893e683728263a540bb93daafda376Andreas Huber } 2246bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 225072f5247ef893e683728263a540bb93daafda376Andreas Huber mBlockEntry = mCluster->GetFirst(); 226072f5247ef893e683728263a540bb93daafda376Andreas Huber } 227072f5247ef893e683728263a540bb93daafda376Andreas Huber 2286bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if (mBlockEntry != NULL 2296bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber && mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) { 2306bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber break; 231072f5247ef893e683728263a540bb93daafda376Andreas Huber } 2326bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 2336bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 2346bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2356bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Hubervoid BlockIterator::reset() { 2366bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mCluster = mSegment->GetFirst(); 2376bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mBlockEntry = mCluster->GetFirst(); 238072f5247ef893e683728263a540bb93daafda376Andreas Huber 2396bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber while (!eos() && block()->GetTrackNumber() != mTrackNum) { 2406bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber advance(); 241072f5247ef893e683728263a540bb93daafda376Andreas Huber } 2426bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 243072f5247ef893e683728263a540bb93daafda376Andreas Huber 2446bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Hubervoid BlockIterator::seek(int64_t seekTimeUs) { 245d208a2c7b0993da0fba7c453763c472746ad4282Andreas Huber mCluster = mSegment->FindCluster(seekTimeUs * 1000ll); 2466bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mBlockEntry = mCluster != NULL ? mCluster->GetFirst() : NULL; 2476bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2486bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber while (!eos() && block()->GetTrackNumber() != mTrackNum) { 2496bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber advance(); 2506bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 2516bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2526bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber while (!eos() && !mBlockEntry->GetBlock()->IsKey()) { 2536bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber advance(); 2546bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 255072f5247ef893e683728263a540bb93daafda376Andreas Huber} 256072f5247ef893e683728263a540bb93daafda376Andreas Huber 2576bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huberconst mkvparser::Block *BlockIterator::block() const { 2586bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber CHECK(!eos()); 2596bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2606bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber return mBlockEntry->GetBlock(); 2616bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 2626bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2636bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huberint64_t BlockIterator::blockTimeUs() const { 2646bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll; 2656bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 2666bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2676bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber//////////////////////////////////////////////////////////////////////////////// 2686bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2697e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huberstatic unsigned U24_AT(const uint8_t *ptr) { 2707e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; 2717e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber} 272072f5247ef893e683728263a540bb93daafda376Andreas Huber 2737e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huberstatic size_t clz(uint8_t x) { 2747e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size_t numLeadingZeroes = 0; 2757e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 2767e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber while (!(x & 0x80)) { 2777e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber ++numLeadingZeroes; 2787e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber x = x << 1; 279072f5247ef893e683728263a540bb93daafda376Andreas Huber } 280072f5247ef893e683728263a540bb93daafda376Andreas Huber 2817e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber return numLeadingZeroes; 2827e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber} 2837e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 2847e2f9cc81da788006790365ff11f06551fc1bc26Andreas Hubervoid MatroskaSource::clearPendingFrames() { 2857e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber while (!mPendingFrames.empty()) { 2867e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber MediaBuffer *frame = *mPendingFrames.begin(); 2877e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 2887e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 2897e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frame->release(); 2907e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frame = NULL; 2917e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 2927e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber} 2937e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 2947e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber#define BAIL(err) \ 2957e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber do { \ 2967e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (bigbuf) { \ 2977e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber bigbuf->release(); \ 2987e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber bigbuf = NULL; \ 2997e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } \ 3007e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber \ 3017e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber return err; \ 3027e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } while (0) 3037e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3047e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huberstatus_t MatroskaSource::readBlock() { 3057e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber CHECK(mPendingFrames.empty()); 3067e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3076bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if (mBlockIter.eos()) { 308072f5247ef893e683728263a540bb93daafda376Andreas Huber return ERROR_END_OF_STREAM; 309072f5247ef893e683728263a540bb93daafda376Andreas Huber } 310072f5247ef893e683728263a540bb93daafda376Andreas Huber 3116bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber const mkvparser::Block *block = mBlockIter.block(); 3127e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 313072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t size = block->GetSize(); 3146bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber int64_t timeUs = mBlockIter.blockTimeUs(); 3157e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber int32_t isSync = block->IsKey(); 316072f5247ef893e683728263a540bb93daafda376Andreas Huber 3177e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber MediaBuffer *bigbuf = new MediaBuffer(size); 318072f5247ef893e683728263a540bb93daafda376Andreas Huber 319072f5247ef893e683728263a540bb93daafda376Andreas Huber long res = block->Read( 3207e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mExtractor->mReader, (unsigned char *)bigbuf->data()); 321072f5247ef893e683728263a540bb93daafda376Andreas Huber 322072f5247ef893e683728263a540bb93daafda376Andreas Huber if (res != 0) { 3237e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber bigbuf->release(); 3247e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber bigbuf = NULL; 3257e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 326072f5247ef893e683728263a540bb93daafda376Andreas Huber return ERROR_END_OF_STREAM; 327072f5247ef893e683728263a540bb93daafda376Andreas Huber } 328072f5247ef893e683728263a540bb93daafda376Andreas Huber 3297e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mBlockIter.advance(); 3307e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3317e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber bigbuf->meta_data()->setInt64(kKeyTime, timeUs); 3327e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber bigbuf->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 333072f5247ef893e683728263a540bb93daafda376Andreas Huber 3347e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber unsigned lacing = (block->Flags() >> 1) & 3; 335072f5247ef893e683728263a540bb93daafda376Andreas Huber 3367e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (lacing == 0) { 3377e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mPendingFrames.push_back(bigbuf); 3387e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber return OK; 3397e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 340072f5247ef893e683728263a540bb93daafda376Andreas Huber 3417e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber LOGV("lacing = %u, size = %d", lacing, size); 342072f5247ef893e683728263a540bb93daafda376Andreas Huber 3437e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber const uint8_t *data = (const uint8_t *)bigbuf->data(); 3447e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber // hexdump(data, size); 345072f5247ef893e683728263a540bb93daafda376Andreas Huber 3467e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (size == 0) { 3477e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber BAIL(ERROR_MALFORMED); 348072f5247ef893e683728263a540bb93daafda376Andreas Huber } 349072f5247ef893e683728263a540bb93daafda376Andreas Huber 3507e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber unsigned numFrames = (unsigned)data[0] + 1; 3517e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber ++data; 3527e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber --size; 3537e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3547e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber Vector<uint64_t> frameSizes; 3557e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3567e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber switch (lacing) { 3577e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber case 1: // Xiph 3587e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber { 3597e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber for (size_t i = 0; i < numFrames - 1; ++i) { 3607e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size_t frameSize = 0; 3617e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber uint8_t byte; 3627e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber do { 3637e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (size == 0) { 3647e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber BAIL(ERROR_MALFORMED); 3657e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 3667e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber byte = data[0]; 3677e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber ++data; 3687e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber --size; 3697e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3707e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frameSize += byte; 3717e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } while (byte == 0xff); 3727e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3737e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frameSizes.push(frameSize); 3747e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 3757e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3767e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber break; 3777e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 3787e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3797e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber case 2: // fixed-size 3807e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber { 3817e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if ((size % numFrames) != 0) { 3827e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber BAIL(ERROR_MALFORMED); 3837e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 3847e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3857e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size_t frameSize = size / numFrames; 3867e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber for (size_t i = 0; i < numFrames - 1; ++i) { 3877e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frameSizes.push(frameSize); 3887e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 3897e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3907e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber break; 3917e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 3927e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3937e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber case 3: // EBML 3947e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber { 3957e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber uint64_t lastFrameSize = 0; 3967e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber for (size_t i = 0; i < numFrames - 1; ++i) { 3977e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber uint8_t byte; 3987e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 3997e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (size == 0) { 4007e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber BAIL(ERROR_MALFORMED); 4017e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 4027e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber byte = data[0]; 4037e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber ++data; 4047e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber --size; 4057e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4067e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size_t numLeadingZeroes = clz(byte); 4077e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4087e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber uint64_t frameSize = byte & ~(0x80 >> numLeadingZeroes); 4097e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber for (size_t j = 0; j < numLeadingZeroes; ++j) { 4107e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (size == 0) { 4117e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber BAIL(ERROR_MALFORMED); 4127e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 4137e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4147e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frameSize = frameSize << 8; 4157e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frameSize |= data[0]; 4167e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber ++data; 4177e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber --size; 4187e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 4197e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4207e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (i == 0) { 4217e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frameSizes.push(frameSize); 4227e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } else { 4237e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size_t shift = 4247e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 7 - numLeadingZeroes + 8 * numLeadingZeroes; 4257e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4267e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber int64_t delta = 4277e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber (int64_t)frameSize - (1ll << (shift - 1)) + 1; 4287e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4297e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frameSize = lastFrameSize + delta; 4307e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4317e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frameSizes.push(frameSize); 4327e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 4337e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4347e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber lastFrameSize = frameSize; 4357e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 4367e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber break; 4377e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 4387e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4397e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber default: 4407e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber TRESPASS(); 4417e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 442072f5247ef893e683728263a540bb93daafda376Andreas Huber 443072f5247ef893e683728263a540bb93daafda376Andreas Huber#if 0 4447e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber AString out; 4457e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber for (size_t i = 0; i < frameSizes.size(); ++i) { 4467e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (i > 0) { 4477e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber out.append(", "); 4487e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 4497e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber out.append(StringPrintf("%llu", frameSizes.itemAt(i))); 4507e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 4517e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber LOGV("sizes = [%s]", out.c_str()); 452072f5247ef893e683728263a540bb93daafda376Andreas Huber#endif 453072f5247ef893e683728263a540bb93daafda376Andreas Huber 4547e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber for (size_t i = 0; i < frameSizes.size(); ++i) { 4557e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber uint64_t frameSize = frameSizes.itemAt(i); 4567e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4577e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (size < frameSize) { 4587e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber BAIL(ERROR_MALFORMED); 4597e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 4607e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4617e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber MediaBuffer *mbuf = new MediaBuffer(frameSize); 4627e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mbuf->meta_data()->setInt64(kKeyTime, timeUs); 4637e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mbuf->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 4647e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber memcpy(mbuf->data(), data, frameSize); 4657e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mPendingFrames.push_back(mbuf); 4667e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4677e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber data += frameSize; 4687e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size -= frameSize; 4697e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 4707e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4717e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size_t offset = bigbuf->range_length() - size; 4727e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber bigbuf->set_range(offset, size); 4737e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4747e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mPendingFrames.push_back(bigbuf); 4757e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4767e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber return OK; 4777e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber} 4787e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4797e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber#undef BAIL 4807e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4817e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huberstatus_t MatroskaSource::read( 4827e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber MediaBuffer **out, const ReadOptions *options) { 4837e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber *out = NULL; 4847e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4857e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber int64_t seekTimeUs; 4867e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber ReadOptions::SeekMode mode; 4877e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 4887e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber clearPendingFrames(); 4897e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mBlockIter.seek(seekTimeUs); 4907e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 4917e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4927e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huberagain: 4937e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber while (mPendingFrames.empty()) { 4947e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber status_t err = readBlock(); 4957e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4967e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (err != OK) { 4977e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber clearPendingFrames(); 4987e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 4997e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber return err; 5007e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 5017e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 5027e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5037e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber MediaBuffer *frame = *mPendingFrames.begin(); 5047e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 5057e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5067e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size_t size = frame->range_length(); 5077e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5087e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (mType != AVC) { 5097e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber *out = frame; 5107e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5117e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber return OK; 5127e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 5137e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5147e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (size < mNALSizeLen) { 5157e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frame->release(); 5167e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frame = NULL; 5177e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5187e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber return ERROR_MALFORMED; 5197e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 5207e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5217e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber // In the case of AVC content, each NAL unit is prefixed by 5227e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber // mNALSizeLen bytes of length. We want to prefix the data with 5237e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber // a four-byte 0x00000001 startcode instead of the length prefix. 5247e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber // mNALSizeLen ranges from 1 through 4 bytes, so add an extra 5257e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber // 3 bytes of padding to the buffer start. 5267e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber static const size_t kPadding = 3; 5277e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5287e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber MediaBuffer *buffer = new MediaBuffer(size + kPadding); 5297e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5307e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber int64_t timeUs; 5317e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs)); 5327e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber int32_t isSync; 5337e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)); 5347e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5357e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber buffer->meta_data()->setInt64(kKeyTime, timeUs); 5367e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 5377e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5387e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber memcpy((uint8_t *)buffer->data() + kPadding, 5397e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber (const uint8_t *)frame->data() + frame->range_offset(), 5407e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size); 5417e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5427e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber buffer->set_range(kPadding, size); 5437e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5447e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frame->release(); 5457e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber frame = NULL; 5467e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5477e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber uint8_t *data = (uint8_t *)buffer->data(); 5487e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5497e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber size_t NALsize; 5507e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber switch (mNALSizeLen) { 5517e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber case 1: NALsize = data[kPadding]; break; 5527e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber case 2: NALsize = U16_AT(&data[kPadding]); break; 5537e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber case 3: NALsize = U24_AT(&data[kPadding]); break; 5547e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber case 4: NALsize = U32_AT(&data[kPadding]); break; 5557e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber default: 5567e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber TRESPASS(); 5577e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 5587e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5597e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (size < NALsize + mNALSizeLen) { 5607e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber buffer->release(); 5617e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber buffer = NULL; 5627e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5637e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber return ERROR_MALFORMED; 5647e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 5657e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5667e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber if (size > NALsize + mNALSizeLen) { 5677e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber LOGW("discarding %d bytes of data.", size - NALsize - mNALSizeLen); 5687e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber } 5697e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5707e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber // actual data starts at &data[kPadding + mNALSizeLen] 5717e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5727e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber memcpy(&data[mNALSizeLen - 1], "\x00\x00\x00\x01", 4); 5737e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber buffer->set_range(mNALSizeLen - 1, NALsize + 4); 5747e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber 5757e2f9cc81da788006790365ff11f06551fc1bc26Andreas Huber *out = buffer; 576072f5247ef893e683728263a540bb93daafda376Andreas Huber 577072f5247ef893e683728263a540bb93daafda376Andreas Huber return OK; 578072f5247ef893e683728263a540bb93daafda376Andreas Huber} 579072f5247ef893e683728263a540bb93daafda376Andreas Huber 580072f5247ef893e683728263a540bb93daafda376Andreas Huber//////////////////////////////////////////////////////////////////////////////// 581072f5247ef893e683728263a540bb93daafda376Andreas Huber 582072f5247ef893e683728263a540bb93daafda376Andreas HuberMatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source) 583072f5247ef893e683728263a540bb93daafda376Andreas Huber : mDataSource(source), 584072f5247ef893e683728263a540bb93daafda376Andreas Huber mReader(new DataSourceReader(mDataSource)), 5856bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mSegment(NULL), 5866bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mExtractedThumbnails(false) { 587072f5247ef893e683728263a540bb93daafda376Andreas Huber mkvparser::EBMLHeader ebmlHeader; 588072f5247ef893e683728263a540bb93daafda376Andreas Huber long long pos; 589072f5247ef893e683728263a540bb93daafda376Andreas Huber if (ebmlHeader.Parse(mReader, pos) < 0) { 590072f5247ef893e683728263a540bb93daafda376Andreas Huber return; 591072f5247ef893e683728263a540bb93daafda376Andreas Huber } 592072f5247ef893e683728263a540bb93daafda376Andreas Huber 593072f5247ef893e683728263a540bb93daafda376Andreas Huber long long ret = 594072f5247ef893e683728263a540bb93daafda376Andreas Huber mkvparser::Segment::CreateInstance(mReader, pos, mSegment); 595072f5247ef893e683728263a540bb93daafda376Andreas Huber 596072f5247ef893e683728263a540bb93daafda376Andreas Huber if (ret) { 597072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(mSegment == NULL); 598072f5247ef893e683728263a540bb93daafda376Andreas Huber return; 599072f5247ef893e683728263a540bb93daafda376Andreas Huber } 600072f5247ef893e683728263a540bb93daafda376Andreas Huber 601072f5247ef893e683728263a540bb93daafda376Andreas Huber ret = mSegment->Load(); 602072f5247ef893e683728263a540bb93daafda376Andreas Huber 603072f5247ef893e683728263a540bb93daafda376Andreas Huber if (ret < 0) { 604072f5247ef893e683728263a540bb93daafda376Andreas Huber delete mSegment; 605072f5247ef893e683728263a540bb93daafda376Andreas Huber mSegment = NULL; 606072f5247ef893e683728263a540bb93daafda376Andreas Huber return; 607072f5247ef893e683728263a540bb93daafda376Andreas Huber } 608072f5247ef893e683728263a540bb93daafda376Andreas Huber 609072f5247ef893e683728263a540bb93daafda376Andreas Huber addTracks(); 610072f5247ef893e683728263a540bb93daafda376Andreas Huber} 611072f5247ef893e683728263a540bb93daafda376Andreas Huber 612072f5247ef893e683728263a540bb93daafda376Andreas HuberMatroskaExtractor::~MatroskaExtractor() { 613072f5247ef893e683728263a540bb93daafda376Andreas Huber delete mSegment; 614072f5247ef893e683728263a540bb93daafda376Andreas Huber mSegment = NULL; 615072f5247ef893e683728263a540bb93daafda376Andreas Huber 616072f5247ef893e683728263a540bb93daafda376Andreas Huber delete mReader; 617072f5247ef893e683728263a540bb93daafda376Andreas Huber mReader = NULL; 618072f5247ef893e683728263a540bb93daafda376Andreas Huber} 619072f5247ef893e683728263a540bb93daafda376Andreas Huber 620072f5247ef893e683728263a540bb93daafda376Andreas Hubersize_t MatroskaExtractor::countTracks() { 621072f5247ef893e683728263a540bb93daafda376Andreas Huber return mTracks.size(); 622072f5247ef893e683728263a540bb93daafda376Andreas Huber} 623072f5247ef893e683728263a540bb93daafda376Andreas Huber 624072f5247ef893e683728263a540bb93daafda376Andreas Hubersp<MediaSource> MatroskaExtractor::getTrack(size_t index) { 625072f5247ef893e683728263a540bb93daafda376Andreas Huber if (index >= mTracks.size()) { 626072f5247ef893e683728263a540bb93daafda376Andreas Huber return NULL; 627072f5247ef893e683728263a540bb93daafda376Andreas Huber } 628072f5247ef893e683728263a540bb93daafda376Andreas Huber 629072f5247ef893e683728263a540bb93daafda376Andreas Huber return new MatroskaSource(this, index); 630072f5247ef893e683728263a540bb93daafda376Andreas Huber} 631072f5247ef893e683728263a540bb93daafda376Andreas Huber 632072f5247ef893e683728263a540bb93daafda376Andreas Hubersp<MetaData> MatroskaExtractor::getTrackMetaData( 633072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t index, uint32_t flags) { 634072f5247ef893e683728263a540bb93daafda376Andreas Huber if (index >= mTracks.size()) { 635072f5247ef893e683728263a540bb93daafda376Andreas Huber return NULL; 636072f5247ef893e683728263a540bb93daafda376Andreas Huber } 637072f5247ef893e683728263a540bb93daafda376Andreas Huber 6386bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails) { 6396bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber findThumbnails(); 6406bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mExtractedThumbnails = true; 6416bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 6426bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 643072f5247ef893e683728263a540bb93daafda376Andreas Huber return mTracks.itemAt(index).mMeta; 644072f5247ef893e683728263a540bb93daafda376Andreas Huber} 645072f5247ef893e683728263a540bb93daafda376Andreas Huber 646072f5247ef893e683728263a540bb93daafda376Andreas Huberstatic void addESDSFromAudioSpecificInfo( 647072f5247ef893e683728263a540bb93daafda376Andreas Huber const sp<MetaData> &meta, const void *asi, size_t asiSize) { 648072f5247ef893e683728263a540bb93daafda376Andreas Huber static const uint8_t kStaticESDS[] = { 649072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x03, 22, 650072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x00, 0x00, // ES_ID 651072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 652072f5247ef893e683728263a540bb93daafda376Andreas Huber 653072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x04, 17, 654072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x40, // Audio ISO/IEC 14496-3 655072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x00, 0x00, 0x00, 0x00, 656072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x00, 0x00, 0x00, 0x00, 657072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x00, 0x00, 0x00, 0x00, 658072f5247ef893e683728263a540bb93daafda376Andreas Huber 659072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x05, 660072f5247ef893e683728263a540bb93daafda376Andreas Huber // AudioSpecificInfo (with size prefix) follows 661072f5247ef893e683728263a540bb93daafda376Andreas Huber }; 662072f5247ef893e683728263a540bb93daafda376Andreas Huber 663072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(asiSize < 128); 664072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1; 665072f5247ef893e683728263a540bb93daafda376Andreas Huber uint8_t *esds = new uint8_t[esdsSize]; 666072f5247ef893e683728263a540bb93daafda376Andreas Huber memcpy(esds, kStaticESDS, sizeof(kStaticESDS)); 667072f5247ef893e683728263a540bb93daafda376Andreas Huber uint8_t *ptr = esds + sizeof(kStaticESDS); 668072f5247ef893e683728263a540bb93daafda376Andreas Huber *ptr++ = asiSize; 669072f5247ef893e683728263a540bb93daafda376Andreas Huber memcpy(ptr, asi, asiSize); 670072f5247ef893e683728263a540bb93daafda376Andreas Huber 671072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setData(kKeyESDS, 0, esds, esdsSize); 672072f5247ef893e683728263a540bb93daafda376Andreas Huber 673072f5247ef893e683728263a540bb93daafda376Andreas Huber delete[] esds; 674072f5247ef893e683728263a540bb93daafda376Andreas Huber esds = NULL; 675072f5247ef893e683728263a540bb93daafda376Andreas Huber} 676072f5247ef893e683728263a540bb93daafda376Andreas Huber 677072f5247ef893e683728263a540bb93daafda376Andreas Hubervoid addVorbisCodecInfo( 678072f5247ef893e683728263a540bb93daafda376Andreas Huber const sp<MetaData> &meta, 679072f5247ef893e683728263a540bb93daafda376Andreas Huber const void *_codecPrivate, size_t codecPrivateSize) { 680072f5247ef893e683728263a540bb93daafda376Andreas Huber // printf("vorbis private data follows:\n"); 681072f5247ef893e683728263a540bb93daafda376Andreas Huber // hexdump(_codecPrivate, codecPrivateSize); 682072f5247ef893e683728263a540bb93daafda376Andreas Huber 683072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivateSize >= 3); 684072f5247ef893e683728263a540bb93daafda376Andreas Huber 685072f5247ef893e683728263a540bb93daafda376Andreas Huber const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate; 686072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivate[0] == 0x02); 687072f5247ef893e683728263a540bb93daafda376Andreas Huber 688072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t len1 = codecPrivate[1]; 689072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t len2 = codecPrivate[2]; 690072f5247ef893e683728263a540bb93daafda376Andreas Huber 691072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivateSize > 3 + len1 + len2); 692072f5247ef893e683728263a540bb93daafda376Andreas Huber 693072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivate[3] == 0x01); 694072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1); 695072f5247ef893e683728263a540bb93daafda376Andreas Huber 696072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivate[len1 + 3] == 0x03); 697072f5247ef893e683728263a540bb93daafda376Andreas Huber 698072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivate[len1 + len2 + 3] == 0x05); 699072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setData( 700072f5247ef893e683728263a540bb93daafda376Andreas Huber kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3], 701072f5247ef893e683728263a540bb93daafda376Andreas Huber codecPrivateSize - len1 - len2 - 3); 702072f5247ef893e683728263a540bb93daafda376Andreas Huber} 703072f5247ef893e683728263a540bb93daafda376Andreas Huber 704072f5247ef893e683728263a540bb93daafda376Andreas Hubervoid MatroskaExtractor::addTracks() { 705072f5247ef893e683728263a540bb93daafda376Andreas Huber const mkvparser::Tracks *tracks = mSegment->GetTracks(); 706072f5247ef893e683728263a540bb93daafda376Andreas Huber 707072f5247ef893e683728263a540bb93daafda376Andreas Huber for (size_t index = 0; index < tracks->GetTracksCount(); ++index) { 708072f5247ef893e683728263a540bb93daafda376Andreas Huber const mkvparser::Track *track = tracks->GetTrackByIndex(index); 709072f5247ef893e683728263a540bb93daafda376Andreas Huber 710072f5247ef893e683728263a540bb93daafda376Andreas Huber const char *const codecID = track->GetCodecId(); 711072f5247ef893e683728263a540bb93daafda376Andreas Huber LOGV("codec id = %s", codecID); 712072f5247ef893e683728263a540bb93daafda376Andreas Huber LOGV("codec name = %s", track->GetCodecNameAsUTF8()); 713072f5247ef893e683728263a540bb93daafda376Andreas Huber 714072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t codecPrivateSize; 715072f5247ef893e683728263a540bb93daafda376Andreas Huber const unsigned char *codecPrivate = 716d208a2c7b0993da0fba7c453763c472746ad4282Andreas Huber track->GetCodecPrivate(codecPrivateSize); 717072f5247ef893e683728263a540bb93daafda376Andreas Huber 718072f5247ef893e683728263a540bb93daafda376Andreas Huber enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; 719072f5247ef893e683728263a540bb93daafda376Andreas Huber 720072f5247ef893e683728263a540bb93daafda376Andreas Huber sp<MetaData> meta = new MetaData; 721072f5247ef893e683728263a540bb93daafda376Andreas Huber 722072f5247ef893e683728263a540bb93daafda376Andreas Huber switch (track->GetType()) { 723072f5247ef893e683728263a540bb93daafda376Andreas Huber case VIDEO_TRACK: 724072f5247ef893e683728263a540bb93daafda376Andreas Huber { 725072f5247ef893e683728263a540bb93daafda376Andreas Huber const mkvparser::VideoTrack *vtrack = 726072f5247ef893e683728263a540bb93daafda376Andreas Huber static_cast<const mkvparser::VideoTrack *>(track); 727072f5247ef893e683728263a540bb93daafda376Andreas Huber 728072f5247ef893e683728263a540bb93daafda376Andreas Huber if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { 729072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 730072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); 731072f5247ef893e683728263a540bb93daafda376Andreas Huber } else if (!strcmp("V_VP8", codecID)) { 732072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX); 733072f5247ef893e683728263a540bb93daafda376Andreas Huber } else { 734072f5247ef893e683728263a540bb93daafda376Andreas Huber continue; 735072f5247ef893e683728263a540bb93daafda376Andreas Huber } 736072f5247ef893e683728263a540bb93daafda376Andreas Huber 737072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setInt32(kKeyWidth, vtrack->GetWidth()); 738072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setInt32(kKeyHeight, vtrack->GetHeight()); 739072f5247ef893e683728263a540bb93daafda376Andreas Huber break; 740072f5247ef893e683728263a540bb93daafda376Andreas Huber } 741072f5247ef893e683728263a540bb93daafda376Andreas Huber 742072f5247ef893e683728263a540bb93daafda376Andreas Huber case AUDIO_TRACK: 743072f5247ef893e683728263a540bb93daafda376Andreas Huber { 744072f5247ef893e683728263a540bb93daafda376Andreas Huber const mkvparser::AudioTrack *atrack = 745072f5247ef893e683728263a540bb93daafda376Andreas Huber static_cast<const mkvparser::AudioTrack *>(track); 746072f5247ef893e683728263a540bb93daafda376Andreas Huber 747072f5247ef893e683728263a540bb93daafda376Andreas Huber if (!strcmp("A_AAC", codecID)) { 748072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 749072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivateSize >= 2); 750072f5247ef893e683728263a540bb93daafda376Andreas Huber 751072f5247ef893e683728263a540bb93daafda376Andreas Huber addESDSFromAudioSpecificInfo( 752072f5247ef893e683728263a540bb93daafda376Andreas Huber meta, codecPrivate, codecPrivateSize); 753072f5247ef893e683728263a540bb93daafda376Andreas Huber } else if (!strcmp("A_VORBIS", codecID)) { 754072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); 755072f5247ef893e683728263a540bb93daafda376Andreas Huber 756072f5247ef893e683728263a540bb93daafda376Andreas Huber addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize); 757072f5247ef893e683728263a540bb93daafda376Andreas Huber } else { 758072f5247ef893e683728263a540bb93daafda376Andreas Huber continue; 759072f5247ef893e683728263a540bb93daafda376Andreas Huber } 760072f5247ef893e683728263a540bb93daafda376Andreas Huber 761072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setInt32(kKeySampleRate, atrack->GetSamplingRate()); 762072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setInt32(kKeyChannelCount, atrack->GetChannels()); 763072f5247ef893e683728263a540bb93daafda376Andreas Huber break; 764072f5247ef893e683728263a540bb93daafda376Andreas Huber } 765072f5247ef893e683728263a540bb93daafda376Andreas Huber 766072f5247ef893e683728263a540bb93daafda376Andreas Huber default: 767072f5247ef893e683728263a540bb93daafda376Andreas Huber continue; 768072f5247ef893e683728263a540bb93daafda376Andreas Huber } 769072f5247ef893e683728263a540bb93daafda376Andreas Huber 770072f5247ef893e683728263a540bb93daafda376Andreas Huber long long durationNs = mSegment->GetDuration(); 771072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setInt64(kKeyDuration, (durationNs + 500) / 1000); 772072f5247ef893e683728263a540bb93daafda376Andreas Huber 773072f5247ef893e683728263a540bb93daafda376Andreas Huber mTracks.push(); 774072f5247ef893e683728263a540bb93daafda376Andreas Huber TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1); 775072f5247ef893e683728263a540bb93daafda376Andreas Huber trackInfo->mTrackNum = track->GetNumber(); 776072f5247ef893e683728263a540bb93daafda376Andreas Huber trackInfo->mMeta = meta; 777072f5247ef893e683728263a540bb93daafda376Andreas Huber } 778072f5247ef893e683728263a540bb93daafda376Andreas Huber} 779072f5247ef893e683728263a540bb93daafda376Andreas Huber 7806bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Hubervoid MatroskaExtractor::findThumbnails() { 7816bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 7826bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber TrackInfo *info = &mTracks.editItemAt(i); 7836bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 7846bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber const char *mime; 7856bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber CHECK(info->mMeta->findCString(kKeyMIMEType, &mime)); 7866bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 7876bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if (strncasecmp(mime, "video/", 6)) { 7886bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber continue; 7896bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 7906bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 7916bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber BlockIterator iter(mSegment, info->mTrackNum); 7926bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber int32_t i = 0; 7936bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber int64_t thumbnailTimeUs = 0; 7946bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber size_t maxBlockSize = 0; 7956bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber while (!iter.eos() && i < 20) { 7966bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if (iter.block()->IsKey()) { 7976bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber ++i; 7986bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 7996bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber size_t blockSize = iter.block()->GetSize(); 8006bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if (blockSize > maxBlockSize) { 8016bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber maxBlockSize = blockSize; 8026bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber thumbnailTimeUs = iter.blockTimeUs(); 8036bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 8046bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 8056bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber iter.advance(); 8066bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 8076bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 8086bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 8096bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 8106bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 811072f5247ef893e683728263a540bb93daafda376Andreas Hubersp<MetaData> MatroskaExtractor::getMetaData() { 812072f5247ef893e683728263a540bb93daafda376Andreas Huber sp<MetaData> meta = new MetaData; 813072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MATROSKA); 814072f5247ef893e683728263a540bb93daafda376Andreas Huber 815072f5247ef893e683728263a540bb93daafda376Andreas Huber return meta; 816072f5247ef893e683728263a540bb93daafda376Andreas Huber} 817072f5247ef893e683728263a540bb93daafda376Andreas Huber 818072f5247ef893e683728263a540bb93daafda376Andreas Huberbool SniffMatroska( 819efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 820efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber sp<AMessage> *) { 821072f5247ef893e683728263a540bb93daafda376Andreas Huber DataSourceReader reader(source); 822072f5247ef893e683728263a540bb93daafda376Andreas Huber mkvparser::EBMLHeader ebmlHeader; 823072f5247ef893e683728263a540bb93daafda376Andreas Huber long long pos; 824072f5247ef893e683728263a540bb93daafda376Andreas Huber if (ebmlHeader.Parse(&reader, pos) < 0) { 825072f5247ef893e683728263a540bb93daafda376Andreas Huber return false; 826072f5247ef893e683728263a540bb93daafda376Andreas Huber } 827072f5247ef893e683728263a540bb93daafda376Andreas Huber 828072f5247ef893e683728263a540bb93daafda376Andreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA); 829072f5247ef893e683728263a540bb93daafda376Andreas Huber *confidence = 0.6; 830072f5247ef893e683728263a540bb93daafda376Andreas Huber 831072f5247ef893e683728263a540bb93daafda376Andreas Huber return true; 832072f5247ef893e683728263a540bb93daafda376Andreas Huber} 833072f5247ef893e683728263a540bb93daafda376Andreas Huber 834072f5247ef893e683728263a540bb93daafda376Andreas Huber} // namespace android 835