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 250f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber#include <media/stagefright/foundation/ADebug.h> 260f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas 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> 330f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas 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) { 61b1262a8b1dd23abad64465f9ffd25c44facdf4d2James Dong off64_t size; 62072f5247ef893e683728263a540bb93daafda376Andreas Huber if (mSource->getSize(&size) != OK) { 638885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber *total = -1; 648885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber *available = (long long)((1ull << 63) - 1); 658885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 668885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber return 0; 67072f5247ef893e683728263a540bb93daafda376Andreas Huber } 68072f5247ef893e683728263a540bb93daafda376Andreas Huber 69072f5247ef893e683728263a540bb93daafda376Andreas Huber if (total) { 70072f5247ef893e683728263a540bb93daafda376Andreas Huber *total = size; 71072f5247ef893e683728263a540bb93daafda376Andreas Huber } 72072f5247ef893e683728263a540bb93daafda376Andreas Huber 73072f5247ef893e683728263a540bb93daafda376Andreas Huber if (available) { 74072f5247ef893e683728263a540bb93daafda376Andreas Huber *available = size; 75072f5247ef893e683728263a540bb93daafda376Andreas Huber } 76072f5247ef893e683728263a540bb93daafda376Andreas Huber 77072f5247ef893e683728263a540bb93daafda376Andreas Huber return 0; 78072f5247ef893e683728263a540bb93daafda376Andreas Huber } 79072f5247ef893e683728263a540bb93daafda376Andreas Huber 80072f5247ef893e683728263a540bb93daafda376Andreas Huberprivate: 81072f5247ef893e683728263a540bb93daafda376Andreas Huber sp<DataSource> mSource; 82072f5247ef893e683728263a540bb93daafda376Andreas Huber 83072f5247ef893e683728263a540bb93daafda376Andreas Huber DataSourceReader(const DataSourceReader &); 84072f5247ef893e683728263a540bb93daafda376Andreas Huber DataSourceReader &operator=(const DataSourceReader &); 85072f5247ef893e683728263a540bb93daafda376Andreas Huber}; 86072f5247ef893e683728263a540bb93daafda376Andreas Huber 87072f5247ef893e683728263a540bb93daafda376Andreas Huber//////////////////////////////////////////////////////////////////////////////// 88072f5247ef893e683728263a540bb93daafda376Andreas Huber 896bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huberstruct BlockIterator { 908885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber BlockIterator(MatroskaExtractor *extractor, unsigned long trackNum); 916bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 926bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber bool eos() const; 936bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 946bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber void advance(); 956bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber void reset(); 96089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber void seek(int64_t seekTimeUs, bool seekToKeyFrame); 976bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 986bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber const mkvparser::Block *block() const; 996bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber int64_t blockTimeUs() const; 1006bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 1016bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huberprivate: 1028885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber MatroskaExtractor *mExtractor; 1036bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber unsigned long mTrackNum; 1046bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 1058885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber const mkvparser::Cluster *mCluster; 1066bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber const mkvparser::BlockEntry *mBlockEntry; 1078885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber long mBlockEntryIndex; 1088885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 1098885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber void advance_l(); 1106bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 1116bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber BlockIterator(const BlockIterator &); 1126bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber BlockIterator &operator=(const BlockIterator &); 1136bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber}; 1146bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 115072f5247ef893e683728263a540bb93daafda376Andreas Huberstruct MatroskaSource : public MediaSource { 116072f5247ef893e683728263a540bb93daafda376Andreas Huber MatroskaSource( 117072f5247ef893e683728263a540bb93daafda376Andreas Huber const sp<MatroskaExtractor> &extractor, size_t index); 118072f5247ef893e683728263a540bb93daafda376Andreas Huber 119072f5247ef893e683728263a540bb93daafda376Andreas Huber virtual status_t start(MetaData *params); 120072f5247ef893e683728263a540bb93daafda376Andreas Huber virtual status_t stop(); 121072f5247ef893e683728263a540bb93daafda376Andreas Huber 122072f5247ef893e683728263a540bb93daafda376Andreas Huber virtual sp<MetaData> getFormat(); 123072f5247ef893e683728263a540bb93daafda376Andreas Huber 124072f5247ef893e683728263a540bb93daafda376Andreas Huber virtual status_t read( 125072f5247ef893e683728263a540bb93daafda376Andreas Huber MediaBuffer **buffer, const ReadOptions *options); 126072f5247ef893e683728263a540bb93daafda376Andreas Huber 1276fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huberprotected: 1286fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber virtual ~MatroskaSource(); 1296fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 130072f5247ef893e683728263a540bb93daafda376Andreas Huberprivate: 131072f5247ef893e683728263a540bb93daafda376Andreas Huber enum Type { 132072f5247ef893e683728263a540bb93daafda376Andreas Huber AVC, 133072f5247ef893e683728263a540bb93daafda376Andreas Huber AAC, 134072f5247ef893e683728263a540bb93daafda376Andreas Huber OTHER 135072f5247ef893e683728263a540bb93daafda376Andreas Huber }; 136072f5247ef893e683728263a540bb93daafda376Andreas Huber 137072f5247ef893e683728263a540bb93daafda376Andreas Huber sp<MatroskaExtractor> mExtractor; 138072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t mTrackIndex; 139072f5247ef893e683728263a540bb93daafda376Andreas Huber Type mType; 140089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber bool mIsAudio; 1416bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber BlockIterator mBlockIter; 1420f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber size_t mNALSizeLen; // for type AVC 143072f5247ef893e683728263a540bb93daafda376Andreas Huber 1446fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber List<MediaBuffer *> mPendingFrames; 1456fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 146072f5247ef893e683728263a540bb93daafda376Andreas Huber status_t advance(); 147072f5247ef893e683728263a540bb93daafda376Andreas Huber 1486fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber status_t readBlock(); 1496fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber void clearPendingFrames(); 1506fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 151072f5247ef893e683728263a540bb93daafda376Andreas Huber MatroskaSource(const MatroskaSource &); 152072f5247ef893e683728263a540bb93daafda376Andreas Huber MatroskaSource &operator=(const MatroskaSource &); 153072f5247ef893e683728263a540bb93daafda376Andreas Huber}; 154072f5247ef893e683728263a540bb93daafda376Andreas Huber 155072f5247ef893e683728263a540bb93daafda376Andreas HuberMatroskaSource::MatroskaSource( 156072f5247ef893e683728263a540bb93daafda376Andreas Huber const sp<MatroskaExtractor> &extractor, size_t index) 157072f5247ef893e683728263a540bb93daafda376Andreas Huber : mExtractor(extractor), 158072f5247ef893e683728263a540bb93daafda376Andreas Huber mTrackIndex(index), 159072f5247ef893e683728263a540bb93daafda376Andreas Huber mType(OTHER), 160089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber mIsAudio(false), 1618885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mBlockIter(mExtractor.get(), 1620f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber mExtractor->mTracks.itemAt(index).mTrackNum), 1630f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber mNALSizeLen(0) { 1640f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta; 1650f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber 166072f5247ef893e683728263a540bb93daafda376Andreas Huber const char *mime; 1670f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 168072f5247ef893e683728263a540bb93daafda376Andreas Huber 169089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber mIsAudio = !strncasecmp("audio/", mime, 6); 170089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber 171072f5247ef893e683728263a540bb93daafda376Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 172072f5247ef893e683728263a540bb93daafda376Andreas Huber mType = AVC; 1730f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber 1740f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber uint32_t dummy; 1750f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber const uint8_t *avcc; 1760f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber size_t avccSize; 1770f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber CHECK(meta->findData( 1780f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber kKeyAVCC, &dummy, (const void **)&avcc, &avccSize)); 1790f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber 1800f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber CHECK_GE(avccSize, 5u); 1810f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber 1820f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber mNALSizeLen = 1 + (avcc[4] & 3); 1830f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber LOGV("mNALSizeLen = %d", mNALSizeLen); 184072f5247ef893e683728263a540bb93daafda376Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 185072f5247ef893e683728263a540bb93daafda376Andreas Huber mType = AAC; 186072f5247ef893e683728263a540bb93daafda376Andreas Huber } 187072f5247ef893e683728263a540bb93daafda376Andreas Huber} 188072f5247ef893e683728263a540bb93daafda376Andreas Huber 1896fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas HuberMatroskaSource::~MatroskaSource() { 1906fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber clearPendingFrames(); 1916fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber} 1926fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 193072f5247ef893e683728263a540bb93daafda376Andreas Huberstatus_t MatroskaSource::start(MetaData *params) { 1946bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mBlockIter.reset(); 195072f5247ef893e683728263a540bb93daafda376Andreas Huber 196072f5247ef893e683728263a540bb93daafda376Andreas Huber return OK; 197072f5247ef893e683728263a540bb93daafda376Andreas Huber} 198072f5247ef893e683728263a540bb93daafda376Andreas Huber 199072f5247ef893e683728263a540bb93daafda376Andreas Huberstatus_t MatroskaSource::stop() { 2006fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber clearPendingFrames(); 2016fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 202072f5247ef893e683728263a540bb93daafda376Andreas Huber return OK; 203072f5247ef893e683728263a540bb93daafda376Andreas Huber} 204072f5247ef893e683728263a540bb93daafda376Andreas Huber 205072f5247ef893e683728263a540bb93daafda376Andreas Hubersp<MetaData> MatroskaSource::getFormat() { 206072f5247ef893e683728263a540bb93daafda376Andreas Huber return mExtractor->mTracks.itemAt(mTrackIndex).mMeta; 207072f5247ef893e683728263a540bb93daafda376Andreas Huber} 208072f5247ef893e683728263a540bb93daafda376Andreas Huber 2096bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber//////////////////////////////////////////////////////////////////////////////// 2106bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2116bdf2edba4de7f971639e8a50e938d218b6d7299Andreas HuberBlockIterator::BlockIterator( 2128885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber MatroskaExtractor *extractor, unsigned long trackNum) 2138885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber : mExtractor(extractor), 2146bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mTrackNum(trackNum), 2156bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mCluster(NULL), 2168885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mBlockEntry(NULL), 2178885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mBlockEntryIndex(0) { 2186bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber reset(); 2196bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 2206bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2216bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huberbool BlockIterator::eos() const { 2226bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber return mCluster == NULL || mCluster->EOS(); 2236bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 2246bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2256bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Hubervoid BlockIterator::advance() { 2268885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 2278885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber advance_l(); 2288885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber} 2298885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2308885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Hubervoid BlockIterator::advance_l() { 2318885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber for (;;) { 2328885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry); 2338885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber LOGV("GetEntry returned %ld", res); 2348885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2358885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber long long pos; 2368885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber long len; 2378885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber if (res < 0) { 2388885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber // Need to parse this cluster some more 2398885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2408885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL); 2418885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2428885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber res = mCluster->Parse(pos, len); 2438885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber LOGV("Parse returned %ld", res); 2448885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2458885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber if (res < 0) { 2468885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber // I/O error 2478885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2488885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber LOGE("Cluster::Parse returned result %ld", res); 2496bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2508885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mCluster = NULL; 2516bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber break; 252072f5247ef893e683728263a540bb93daafda376Andreas Huber } 2536bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2548885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber continue; 2558885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber } else if (res == 0) { 2568885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber // We're done with this cluster 2578885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2588885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber const mkvparser::Cluster *nextCluster; 2598885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber res = mExtractor->mSegment->ParseNext( 2608885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mCluster, nextCluster, pos, len); 2618885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber LOGV("ParseNext returned %ld", res); 2628885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2638885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber if (res > 0) { 2648885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber // EOF 2658885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2668885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mCluster = NULL; 2678885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber break; 2688885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber } 2698885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2708885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber CHECK_EQ(res, 0); 2718885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber CHECK(nextCluster != NULL); 2728885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber CHECK(!nextCluster->EOS()); 2738885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2748885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mCluster = nextCluster; 2758885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2768885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber res = mCluster->Parse(pos, len); 2778885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber LOGV("Parse (2) returned %ld", res); 2788885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber CHECK_GE(res, 0); 2798885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2808885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mBlockEntryIndex = 0; 2818885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber continue; 282072f5247ef893e683728263a540bb93daafda376Andreas Huber } 283072f5247ef893e683728263a540bb93daafda376Andreas Huber 2848885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber CHECK(mBlockEntry != NULL); 2858885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber CHECK(mBlockEntry->GetBlock() != NULL); 2868885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber ++mBlockEntryIndex; 2878885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 2888885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) { 2896bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber break; 290072f5247ef893e683728263a540bb93daafda376Andreas Huber } 2916bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 2926bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 2936bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 2946bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Hubervoid BlockIterator::reset() { 2958885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 296072f5247ef893e683728263a540bb93daafda376Andreas Huber 2978885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mCluster = mExtractor->mSegment->GetFirst(); 29821796929d37a290f069faad4bd04b356c5579296Andreas Huber mBlockEntry = NULL; 2998885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mBlockEntryIndex = 0; 3008885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 3018885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber do { 3028885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber advance_l(); 3038885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber } while (!eos() && block()->GetTrackNumber() != mTrackNum); 3046bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 305072f5247ef893e683728263a540bb93daafda376Andreas Huber 306089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Hubervoid BlockIterator::seek(int64_t seekTimeUs, bool seekToKeyFrame) { 3078885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 3088885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 3098885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll); 31021796929d37a290f069faad4bd04b356c5579296Andreas Huber mBlockEntry = NULL; 3118885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mBlockEntryIndex = 0; 3126bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 31321796929d37a290f069faad4bd04b356c5579296Andreas Huber do { 3148885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber advance_l(); 3156bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 31621796929d37a290f069faad4bd04b356c5579296Andreas Huber while (!eos() && block()->GetTrackNumber() != mTrackNum); 3176bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 318089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber if (seekToKeyFrame) { 319089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber while (!eos() && !mBlockEntry->GetBlock()->IsKey()) { 320089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber advance_l(); 321089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber } 3226bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 323072f5247ef893e683728263a540bb93daafda376Andreas Huber} 324072f5247ef893e683728263a540bb93daafda376Andreas Huber 3256bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huberconst mkvparser::Block *BlockIterator::block() const { 3266bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber CHECK(!eos()); 3276bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 3286bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber return mBlockEntry->GetBlock(); 3296bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 3306bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 3316bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huberint64_t BlockIterator::blockTimeUs() const { 3326bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll; 3336bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 3346bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 3356bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber//////////////////////////////////////////////////////////////////////////////// 3366bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 3370f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huberstatic unsigned U24_AT(const uint8_t *ptr) { 3380f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; 3390f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber} 3400f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber 3416fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huberstatic size_t clz(uint8_t x) { 3426fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber size_t numLeadingZeroes = 0; 343072f5247ef893e683728263a540bb93daafda376Andreas Huber 3446fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber while (!(x & 0x80)) { 3456fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber ++numLeadingZeroes; 3466fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber x = x << 1; 347072f5247ef893e683728263a540bb93daafda376Andreas Huber } 348072f5247ef893e683728263a540bb93daafda376Andreas Huber 3496fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber return numLeadingZeroes; 3506fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber} 3516fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 3526fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Hubervoid MatroskaSource::clearPendingFrames() { 3536fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber while (!mPendingFrames.empty()) { 3546fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber MediaBuffer *frame = *mPendingFrames.begin(); 3556fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 3566fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 3576fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber frame->release(); 3586fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber frame = NULL; 3596fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber } 3606fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber} 3616fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 3626fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huberstatus_t MatroskaSource::readBlock() { 3636fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber CHECK(mPendingFrames.empty()); 3646fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 3656bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if (mBlockIter.eos()) { 366072f5247ef893e683728263a540bb93daafda376Andreas Huber return ERROR_END_OF_STREAM; 367072f5247ef893e683728263a540bb93daafda376Andreas Huber } 368072f5247ef893e683728263a540bb93daafda376Andreas Huber 3696bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber const mkvparser::Block *block = mBlockIter.block(); 3706fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 3716bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber int64_t timeUs = mBlockIter.blockTimeUs(); 372072f5247ef893e683728263a540bb93daafda376Andreas Huber 3738885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber for (int i = 0; i < block->GetFrameCount(); ++i) { 3748885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber const mkvparser::Block::Frame &frame = block->GetFrame(i); 3750f624584347a1b2d1b1c1e7d013b8c8aa73fa32cAndreas Huber 3768885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber MediaBuffer *mbuf = new MediaBuffer(frame.len); 3778885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mbuf->meta_data()->setInt64(kKeyTime, timeUs); 3788885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mbuf->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey()); 379072f5247ef893e683728263a540bb93daafda376Andreas Huber 3808885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber long n = frame.Read(mExtractor->mReader, (unsigned char *)mbuf->data()); 3818885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber if (n != 0) { 3828885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mPendingFrames.clear(); 3836fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 3848885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mBlockIter.advance(); 3858885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber return ERROR_IO; 3866fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber } 3876fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 3886fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber mPendingFrames.push_back(mbuf); 3896fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber } 3906fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 3918885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mBlockIter.advance(); 3926fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 3936fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber return OK; 3946fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber} 3956fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 3966fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huberstatus_t MatroskaSource::read( 3976fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber MediaBuffer **out, const ReadOptions *options) { 3986fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber *out = NULL; 3996fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4006fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber int64_t seekTimeUs; 4016fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber ReadOptions::SeekMode mode; 4028885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode) 4038885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber && !mExtractor->isLiveStreaming()) { 4046fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber clearPendingFrames(); 405089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber 406089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber // Apparently keyframe indication in audio tracks is unreliable, 407089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber // fortunately in all our currently supported audio encodings every 408089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber // frame is effectively a keyframe. 409089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber mBlockIter.seek(seekTimeUs, !mIsAudio); 4106fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber } 4116fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4126fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huberagain: 4136fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber while (mPendingFrames.empty()) { 4146fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber status_t err = readBlock(); 4156fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4166fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber if (err != OK) { 4176fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber clearPendingFrames(); 4186fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4196fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber return err; 4206fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber } 4216fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber } 4226fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4236fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber MediaBuffer *frame = *mPendingFrames.begin(); 4246fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 4256fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4266fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber if (mType != AVC) { 4276fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber *out = frame; 4286fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4296fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber return OK; 4306fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber } 4316fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4322378341174055957833e5af17dc32596c2996335Andreas Huber // Each input frame contains one or more NAL fragments, each fragment 4332378341174055957833e5af17dc32596c2996335Andreas Huber // is prefixed by mNALSizeLen bytes giving the fragment length, 4342378341174055957833e5af17dc32596c2996335Andreas Huber // followed by a corresponding number of bytes containing the fragment. 4352378341174055957833e5af17dc32596c2996335Andreas Huber // We output all these fragments into a single large buffer separated 4362378341174055957833e5af17dc32596c2996335Andreas Huber // by startcodes (0x00 0x00 0x00 0x01). 4372378341174055957833e5af17dc32596c2996335Andreas Huber 4382378341174055957833e5af17dc32596c2996335Andreas Huber const uint8_t *srcPtr = 4392378341174055957833e5af17dc32596c2996335Andreas Huber (const uint8_t *)frame->data() + frame->range_offset(); 4402378341174055957833e5af17dc32596c2996335Andreas Huber 4412378341174055957833e5af17dc32596c2996335Andreas Huber size_t srcSize = frame->range_length(); 4422378341174055957833e5af17dc32596c2996335Andreas Huber 4432378341174055957833e5af17dc32596c2996335Andreas Huber size_t dstSize = 0; 4442378341174055957833e5af17dc32596c2996335Andreas Huber MediaBuffer *buffer = NULL; 4452378341174055957833e5af17dc32596c2996335Andreas Huber uint8_t *dstPtr = NULL; 4462378341174055957833e5af17dc32596c2996335Andreas Huber 4472378341174055957833e5af17dc32596c2996335Andreas Huber for (int32_t pass = 0; pass < 2; ++pass) { 4482378341174055957833e5af17dc32596c2996335Andreas Huber size_t srcOffset = 0; 4492378341174055957833e5af17dc32596c2996335Andreas Huber size_t dstOffset = 0; 4502378341174055957833e5af17dc32596c2996335Andreas Huber while (srcOffset + mNALSizeLen <= srcSize) { 4512378341174055957833e5af17dc32596c2996335Andreas Huber size_t NALsize; 4522378341174055957833e5af17dc32596c2996335Andreas Huber switch (mNALSizeLen) { 4532378341174055957833e5af17dc32596c2996335Andreas Huber case 1: NALsize = srcPtr[srcOffset]; break; 4542378341174055957833e5af17dc32596c2996335Andreas Huber case 2: NALsize = U16_AT(srcPtr + srcOffset); break; 4552378341174055957833e5af17dc32596c2996335Andreas Huber case 3: NALsize = U24_AT(srcPtr + srcOffset); break; 4562378341174055957833e5af17dc32596c2996335Andreas Huber case 4: NALsize = U32_AT(srcPtr + srcOffset); break; 4572378341174055957833e5af17dc32596c2996335Andreas Huber default: 4582378341174055957833e5af17dc32596c2996335Andreas Huber TRESPASS(); 4592378341174055957833e5af17dc32596c2996335Andreas Huber } 4606fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4612378341174055957833e5af17dc32596c2996335Andreas Huber if (srcOffset + mNALSizeLen + NALsize > srcSize) { 4622378341174055957833e5af17dc32596c2996335Andreas Huber break; 4632378341174055957833e5af17dc32596c2996335Andreas Huber } 4646fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4652378341174055957833e5af17dc32596c2996335Andreas Huber if (pass == 1) { 4662378341174055957833e5af17dc32596c2996335Andreas Huber memcpy(&dstPtr[dstOffset], "\x00\x00\x00\x01", 4); 4676fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4682378341174055957833e5af17dc32596c2996335Andreas Huber memcpy(&dstPtr[dstOffset + 4], 4692378341174055957833e5af17dc32596c2996335Andreas Huber &srcPtr[srcOffset + mNALSizeLen], 4702378341174055957833e5af17dc32596c2996335Andreas Huber NALsize); 4712378341174055957833e5af17dc32596c2996335Andreas Huber } 4726fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4732378341174055957833e5af17dc32596c2996335Andreas Huber dstOffset += 4; // 0x00 00 00 01 4742378341174055957833e5af17dc32596c2996335Andreas Huber dstOffset += NALsize; 4756fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4762378341174055957833e5af17dc32596c2996335Andreas Huber srcOffset += mNALSizeLen + NALsize; 4772378341174055957833e5af17dc32596c2996335Andreas Huber } 4786fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4792378341174055957833e5af17dc32596c2996335Andreas Huber if (srcOffset < srcSize) { 4802378341174055957833e5af17dc32596c2996335Andreas Huber // There were trailing bytes or not enough data to complete 4812378341174055957833e5af17dc32596c2996335Andreas Huber // a fragment. 4826fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4832378341174055957833e5af17dc32596c2996335Andreas Huber frame->release(); 4842378341174055957833e5af17dc32596c2996335Andreas Huber frame = NULL; 4856fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4862378341174055957833e5af17dc32596c2996335Andreas Huber return ERROR_MALFORMED; 4872378341174055957833e5af17dc32596c2996335Andreas Huber } 4886fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4892378341174055957833e5af17dc32596c2996335Andreas Huber if (pass == 0) { 4902378341174055957833e5af17dc32596c2996335Andreas Huber dstSize = dstOffset; 4916fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4922378341174055957833e5af17dc32596c2996335Andreas Huber buffer = new MediaBuffer(dstSize); 4936fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4942378341174055957833e5af17dc32596c2996335Andreas Huber int64_t timeUs; 4952378341174055957833e5af17dc32596c2996335Andreas Huber CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs)); 4962378341174055957833e5af17dc32596c2996335Andreas Huber int32_t isSync; 4972378341174055957833e5af17dc32596c2996335Andreas Huber CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)); 4986fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 4992378341174055957833e5af17dc32596c2996335Andreas Huber buffer->meta_data()->setInt64(kKeyTime, timeUs); 5002378341174055957833e5af17dc32596c2996335Andreas Huber buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 5016fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 5022378341174055957833e5af17dc32596c2996335Andreas Huber dstPtr = (uint8_t *)buffer->data(); 5032378341174055957833e5af17dc32596c2996335Andreas Huber } 5046fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber } 5056fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 5062378341174055957833e5af17dc32596c2996335Andreas Huber frame->release(); 5072378341174055957833e5af17dc32596c2996335Andreas Huber frame = NULL; 5086fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber 5096fe6b4c6f3cd96b69f8124a3cdb0dad3145bac91Andreas Huber *out = buffer; 510072f5247ef893e683728263a540bb93daafda376Andreas Huber 511072f5247ef893e683728263a540bb93daafda376Andreas Huber return OK; 512072f5247ef893e683728263a540bb93daafda376Andreas Huber} 513072f5247ef893e683728263a540bb93daafda376Andreas Huber 514072f5247ef893e683728263a540bb93daafda376Andreas Huber//////////////////////////////////////////////////////////////////////////////// 515072f5247ef893e683728263a540bb93daafda376Andreas Huber 516072f5247ef893e683728263a540bb93daafda376Andreas HuberMatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source) 517072f5247ef893e683728263a540bb93daafda376Andreas Huber : mDataSource(source), 518072f5247ef893e683728263a540bb93daafda376Andreas Huber mReader(new DataSourceReader(mDataSource)), 5196bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mSegment(NULL), 5206e37cf90f90678a083eef57c62d47831fd208f48Andreas Huber mExtractedThumbnails(false), 5216e37cf90f90678a083eef57c62d47831fd208f48Andreas Huber mIsWebm(false) { 5228885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber off64_t size; 5238885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber mIsLiveStreaming = 5248885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber (mDataSource->flags() 5258885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber & (DataSource::kWantsPrefetching 5268885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber | DataSource::kIsCachingDataSource)) 5278885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber && mDataSource->getSize(&size) != OK; 5288885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 529072f5247ef893e683728263a540bb93daafda376Andreas Huber mkvparser::EBMLHeader ebmlHeader; 530072f5247ef893e683728263a540bb93daafda376Andreas Huber long long pos; 531072f5247ef893e683728263a540bb93daafda376Andreas Huber if (ebmlHeader.Parse(mReader, pos) < 0) { 532072f5247ef893e683728263a540bb93daafda376Andreas Huber return; 533072f5247ef893e683728263a540bb93daafda376Andreas Huber } 534072f5247ef893e683728263a540bb93daafda376Andreas Huber 5356e37cf90f90678a083eef57c62d47831fd208f48Andreas Huber if (ebmlHeader.m_docType && !strcmp("webm", ebmlHeader.m_docType)) { 5366e37cf90f90678a083eef57c62d47831fd208f48Andreas Huber mIsWebm = true; 5376e37cf90f90678a083eef57c62d47831fd208f48Andreas Huber } 5386e37cf90f90678a083eef57c62d47831fd208f48Andreas Huber 539072f5247ef893e683728263a540bb93daafda376Andreas Huber long long ret = 540072f5247ef893e683728263a540bb93daafda376Andreas Huber mkvparser::Segment::CreateInstance(mReader, pos, mSegment); 541072f5247ef893e683728263a540bb93daafda376Andreas Huber 542072f5247ef893e683728263a540bb93daafda376Andreas Huber if (ret) { 543072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(mSegment == NULL); 544072f5247ef893e683728263a540bb93daafda376Andreas Huber return; 545072f5247ef893e683728263a540bb93daafda376Andreas Huber } 546072f5247ef893e683728263a540bb93daafda376Andreas Huber 5478885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber if (isLiveStreaming()) { 5488885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber ret = mSegment->ParseHeaders(); 5498885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber CHECK_EQ(ret, 0); 5508885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 5518885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber long len; 5528885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber ret = mSegment->LoadCluster(pos, len); 5538885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber CHECK_EQ(ret, 0); 5548885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber } else { 5558885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber ret = mSegment->Load(); 5568885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber } 557072f5247ef893e683728263a540bb93daafda376Andreas Huber 558072f5247ef893e683728263a540bb93daafda376Andreas Huber if (ret < 0) { 559072f5247ef893e683728263a540bb93daafda376Andreas Huber delete mSegment; 560072f5247ef893e683728263a540bb93daafda376Andreas Huber mSegment = NULL; 561072f5247ef893e683728263a540bb93daafda376Andreas Huber return; 562072f5247ef893e683728263a540bb93daafda376Andreas Huber } 563072f5247ef893e683728263a540bb93daafda376Andreas Huber 564089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber#if 0 565089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber const mkvparser::SegmentInfo *info = mSegment->GetInfo(); 566089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber LOGI("muxing app: %s, writing app: %s", 567089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber info->GetMuxingAppAsUTF8(), 568089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber info->GetWritingAppAsUTF8()); 569089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber#endif 570089d3e3f14101140ff8baa3cc44f3dd8586ad285Andreas Huber 571072f5247ef893e683728263a540bb93daafda376Andreas Huber addTracks(); 572072f5247ef893e683728263a540bb93daafda376Andreas Huber} 573072f5247ef893e683728263a540bb93daafda376Andreas Huber 574072f5247ef893e683728263a540bb93daafda376Andreas HuberMatroskaExtractor::~MatroskaExtractor() { 575072f5247ef893e683728263a540bb93daafda376Andreas Huber delete mSegment; 576072f5247ef893e683728263a540bb93daafda376Andreas Huber mSegment = NULL; 577072f5247ef893e683728263a540bb93daafda376Andreas Huber 578072f5247ef893e683728263a540bb93daafda376Andreas Huber delete mReader; 579072f5247ef893e683728263a540bb93daafda376Andreas Huber mReader = NULL; 580072f5247ef893e683728263a540bb93daafda376Andreas Huber} 581072f5247ef893e683728263a540bb93daafda376Andreas Huber 582072f5247ef893e683728263a540bb93daafda376Andreas Hubersize_t MatroskaExtractor::countTracks() { 583072f5247ef893e683728263a540bb93daafda376Andreas Huber return mTracks.size(); 584072f5247ef893e683728263a540bb93daafda376Andreas Huber} 585072f5247ef893e683728263a540bb93daafda376Andreas Huber 586072f5247ef893e683728263a540bb93daafda376Andreas Hubersp<MediaSource> MatroskaExtractor::getTrack(size_t index) { 587072f5247ef893e683728263a540bb93daafda376Andreas Huber if (index >= mTracks.size()) { 588072f5247ef893e683728263a540bb93daafda376Andreas Huber return NULL; 589072f5247ef893e683728263a540bb93daafda376Andreas Huber } 590072f5247ef893e683728263a540bb93daafda376Andreas Huber 591072f5247ef893e683728263a540bb93daafda376Andreas Huber return new MatroskaSource(this, index); 592072f5247ef893e683728263a540bb93daafda376Andreas Huber} 593072f5247ef893e683728263a540bb93daafda376Andreas Huber 594072f5247ef893e683728263a540bb93daafda376Andreas Hubersp<MetaData> MatroskaExtractor::getTrackMetaData( 595072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t index, uint32_t flags) { 596072f5247ef893e683728263a540bb93daafda376Andreas Huber if (index >= mTracks.size()) { 597072f5247ef893e683728263a540bb93daafda376Andreas Huber return NULL; 598072f5247ef893e683728263a540bb93daafda376Andreas Huber } 599072f5247ef893e683728263a540bb93daafda376Andreas Huber 6008885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails 6018885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber && !isLiveStreaming()) { 6026bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber findThumbnails(); 6036bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber mExtractedThumbnails = true; 6046bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 6056bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 606072f5247ef893e683728263a540bb93daafda376Andreas Huber return mTracks.itemAt(index).mMeta; 607072f5247ef893e683728263a540bb93daafda376Andreas Huber} 608072f5247ef893e683728263a540bb93daafda376Andreas Huber 6098885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huberbool MatroskaExtractor::isLiveStreaming() const { 6108885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber return mIsLiveStreaming; 6118885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber} 6128885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 613072f5247ef893e683728263a540bb93daafda376Andreas Huberstatic void addESDSFromAudioSpecificInfo( 614072f5247ef893e683728263a540bb93daafda376Andreas Huber const sp<MetaData> &meta, const void *asi, size_t asiSize) { 615072f5247ef893e683728263a540bb93daafda376Andreas Huber static const uint8_t kStaticESDS[] = { 616072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x03, 22, 617072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x00, 0x00, // ES_ID 618072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 619072f5247ef893e683728263a540bb93daafda376Andreas Huber 620072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x04, 17, 621072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x40, // Audio ISO/IEC 14496-3 622072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x00, 0x00, 0x00, 0x00, 623072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x00, 0x00, 0x00, 0x00, 624072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x00, 0x00, 0x00, 0x00, 625072f5247ef893e683728263a540bb93daafda376Andreas Huber 626072f5247ef893e683728263a540bb93daafda376Andreas Huber 0x05, 627072f5247ef893e683728263a540bb93daafda376Andreas Huber // AudioSpecificInfo (with size prefix) follows 628072f5247ef893e683728263a540bb93daafda376Andreas Huber }; 629072f5247ef893e683728263a540bb93daafda376Andreas Huber 63065b96059766a12454236712931d66bffb311729cAndreas Huber // Make sure all sizes can be coded in a single byte. 63165b96059766a12454236712931d66bffb311729cAndreas Huber CHECK(asiSize + 22 - 2 < 128); 632072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1; 633072f5247ef893e683728263a540bb93daafda376Andreas Huber uint8_t *esds = new uint8_t[esdsSize]; 634072f5247ef893e683728263a540bb93daafda376Andreas Huber memcpy(esds, kStaticESDS, sizeof(kStaticESDS)); 635072f5247ef893e683728263a540bb93daafda376Andreas Huber uint8_t *ptr = esds + sizeof(kStaticESDS); 636072f5247ef893e683728263a540bb93daafda376Andreas Huber *ptr++ = asiSize; 637072f5247ef893e683728263a540bb93daafda376Andreas Huber memcpy(ptr, asi, asiSize); 638072f5247ef893e683728263a540bb93daafda376Andreas Huber 63965b96059766a12454236712931d66bffb311729cAndreas Huber // Increment by codecPrivateSize less 2 bytes that are accounted for 64065b96059766a12454236712931d66bffb311729cAndreas Huber // already in lengths of 22/17 64165b96059766a12454236712931d66bffb311729cAndreas Huber esds[1] += asiSize - 2; 64265b96059766a12454236712931d66bffb311729cAndreas Huber esds[6] += asiSize - 2; 64365b96059766a12454236712931d66bffb311729cAndreas Huber 644072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setData(kKeyESDS, 0, esds, esdsSize); 645072f5247ef893e683728263a540bb93daafda376Andreas Huber 646072f5247ef893e683728263a540bb93daafda376Andreas Huber delete[] esds; 647072f5247ef893e683728263a540bb93daafda376Andreas Huber esds = NULL; 648072f5247ef893e683728263a540bb93daafda376Andreas Huber} 649072f5247ef893e683728263a540bb93daafda376Andreas Huber 650072f5247ef893e683728263a540bb93daafda376Andreas Hubervoid addVorbisCodecInfo( 651072f5247ef893e683728263a540bb93daafda376Andreas Huber const sp<MetaData> &meta, 652072f5247ef893e683728263a540bb93daafda376Andreas Huber const void *_codecPrivate, size_t codecPrivateSize) { 653072f5247ef893e683728263a540bb93daafda376Andreas Huber // printf("vorbis private data follows:\n"); 654072f5247ef893e683728263a540bb93daafda376Andreas Huber // hexdump(_codecPrivate, codecPrivateSize); 655072f5247ef893e683728263a540bb93daafda376Andreas Huber 656072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivateSize >= 3); 657072f5247ef893e683728263a540bb93daafda376Andreas Huber 658072f5247ef893e683728263a540bb93daafda376Andreas Huber const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate; 659072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivate[0] == 0x02); 660072f5247ef893e683728263a540bb93daafda376Andreas Huber 661072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t len1 = codecPrivate[1]; 662072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t len2 = codecPrivate[2]; 663072f5247ef893e683728263a540bb93daafda376Andreas Huber 664072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivateSize > 3 + len1 + len2); 665072f5247ef893e683728263a540bb93daafda376Andreas Huber 666072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivate[3] == 0x01); 667072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1); 668072f5247ef893e683728263a540bb93daafda376Andreas Huber 669072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivate[len1 + 3] == 0x03); 670072f5247ef893e683728263a540bb93daafda376Andreas Huber 671072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivate[len1 + len2 + 3] == 0x05); 672072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setData( 673072f5247ef893e683728263a540bb93daafda376Andreas Huber kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3], 674072f5247ef893e683728263a540bb93daafda376Andreas Huber codecPrivateSize - len1 - len2 - 3); 675072f5247ef893e683728263a540bb93daafda376Andreas Huber} 676072f5247ef893e683728263a540bb93daafda376Andreas Huber 677072f5247ef893e683728263a540bb93daafda376Andreas Hubervoid MatroskaExtractor::addTracks() { 678072f5247ef893e683728263a540bb93daafda376Andreas Huber const mkvparser::Tracks *tracks = mSegment->GetTracks(); 679072f5247ef893e683728263a540bb93daafda376Andreas Huber 680072f5247ef893e683728263a540bb93daafda376Andreas Huber for (size_t index = 0; index < tracks->GetTracksCount(); ++index) { 681072f5247ef893e683728263a540bb93daafda376Andreas Huber const mkvparser::Track *track = tracks->GetTrackByIndex(index); 682072f5247ef893e683728263a540bb93daafda376Andreas Huber 683dfe8d9b1ffd016744504cd63a777d243fd2099ceAndreas Huber if (track == NULL) { 684dfe8d9b1ffd016744504cd63a777d243fd2099ceAndreas Huber // Apparently this is currently valid (if unexpected) behaviour 685dfe8d9b1ffd016744504cd63a777d243fd2099ceAndreas Huber // of the mkv parser lib. 686dfe8d9b1ffd016744504cd63a777d243fd2099ceAndreas Huber continue; 687dfe8d9b1ffd016744504cd63a777d243fd2099ceAndreas Huber } 688dfe8d9b1ffd016744504cd63a777d243fd2099ceAndreas Huber 689072f5247ef893e683728263a540bb93daafda376Andreas Huber const char *const codecID = track->GetCodecId(); 690072f5247ef893e683728263a540bb93daafda376Andreas Huber LOGV("codec id = %s", codecID); 691072f5247ef893e683728263a540bb93daafda376Andreas Huber LOGV("codec name = %s", track->GetCodecNameAsUTF8()); 692072f5247ef893e683728263a540bb93daafda376Andreas Huber 693072f5247ef893e683728263a540bb93daafda376Andreas Huber size_t codecPrivateSize; 694072f5247ef893e683728263a540bb93daafda376Andreas Huber const unsigned char *codecPrivate = 6954b844457885853cfa0c1feafe4d9661af5a3b41dAndreas Huber track->GetCodecPrivate(codecPrivateSize); 696072f5247ef893e683728263a540bb93daafda376Andreas Huber 697072f5247ef893e683728263a540bb93daafda376Andreas Huber enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; 698072f5247ef893e683728263a540bb93daafda376Andreas Huber 699072f5247ef893e683728263a540bb93daafda376Andreas Huber sp<MetaData> meta = new MetaData; 700072f5247ef893e683728263a540bb93daafda376Andreas Huber 701072f5247ef893e683728263a540bb93daafda376Andreas Huber switch (track->GetType()) { 702072f5247ef893e683728263a540bb93daafda376Andreas Huber case VIDEO_TRACK: 703072f5247ef893e683728263a540bb93daafda376Andreas Huber { 704072f5247ef893e683728263a540bb93daafda376Andreas Huber const mkvparser::VideoTrack *vtrack = 705072f5247ef893e683728263a540bb93daafda376Andreas Huber static_cast<const mkvparser::VideoTrack *>(track); 706072f5247ef893e683728263a540bb93daafda376Andreas Huber 707072f5247ef893e683728263a540bb93daafda376Andreas Huber if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { 708072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 709072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); 710072f5247ef893e683728263a540bb93daafda376Andreas Huber } else if (!strcmp("V_VP8", codecID)) { 711072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX); 712072f5247ef893e683728263a540bb93daafda376Andreas Huber } else { 713072f5247ef893e683728263a540bb93daafda376Andreas Huber continue; 714072f5247ef893e683728263a540bb93daafda376Andreas Huber } 715072f5247ef893e683728263a540bb93daafda376Andreas Huber 716072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setInt32(kKeyWidth, vtrack->GetWidth()); 717072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setInt32(kKeyHeight, vtrack->GetHeight()); 718072f5247ef893e683728263a540bb93daafda376Andreas Huber break; 719072f5247ef893e683728263a540bb93daafda376Andreas Huber } 720072f5247ef893e683728263a540bb93daafda376Andreas Huber 721072f5247ef893e683728263a540bb93daafda376Andreas Huber case AUDIO_TRACK: 722072f5247ef893e683728263a540bb93daafda376Andreas Huber { 723072f5247ef893e683728263a540bb93daafda376Andreas Huber const mkvparser::AudioTrack *atrack = 724072f5247ef893e683728263a540bb93daafda376Andreas Huber static_cast<const mkvparser::AudioTrack *>(track); 725072f5247ef893e683728263a540bb93daafda376Andreas Huber 726072f5247ef893e683728263a540bb93daafda376Andreas Huber if (!strcmp("A_AAC", codecID)) { 727072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 728072f5247ef893e683728263a540bb93daafda376Andreas Huber CHECK(codecPrivateSize >= 2); 729072f5247ef893e683728263a540bb93daafda376Andreas Huber 730072f5247ef893e683728263a540bb93daafda376Andreas Huber addESDSFromAudioSpecificInfo( 731072f5247ef893e683728263a540bb93daafda376Andreas Huber meta, codecPrivate, codecPrivateSize); 732072f5247ef893e683728263a540bb93daafda376Andreas Huber } else if (!strcmp("A_VORBIS", codecID)) { 733072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); 734072f5247ef893e683728263a540bb93daafda376Andreas Huber 735072f5247ef893e683728263a540bb93daafda376Andreas Huber addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize); 736072f5247ef893e683728263a540bb93daafda376Andreas Huber } else { 737072f5247ef893e683728263a540bb93daafda376Andreas Huber continue; 738072f5247ef893e683728263a540bb93daafda376Andreas Huber } 739072f5247ef893e683728263a540bb93daafda376Andreas Huber 740072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setInt32(kKeySampleRate, atrack->GetSamplingRate()); 741072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setInt32(kKeyChannelCount, atrack->GetChannels()); 742072f5247ef893e683728263a540bb93daafda376Andreas Huber break; 743072f5247ef893e683728263a540bb93daafda376Andreas Huber } 744072f5247ef893e683728263a540bb93daafda376Andreas Huber 745072f5247ef893e683728263a540bb93daafda376Andreas Huber default: 746072f5247ef893e683728263a540bb93daafda376Andreas Huber continue; 747072f5247ef893e683728263a540bb93daafda376Andreas Huber } 748072f5247ef893e683728263a540bb93daafda376Andreas Huber 749072f5247ef893e683728263a540bb93daafda376Andreas Huber long long durationNs = mSegment->GetDuration(); 750072f5247ef893e683728263a540bb93daafda376Andreas Huber meta->setInt64(kKeyDuration, (durationNs + 500) / 1000); 751072f5247ef893e683728263a540bb93daafda376Andreas Huber 752072f5247ef893e683728263a540bb93daafda376Andreas Huber mTracks.push(); 753072f5247ef893e683728263a540bb93daafda376Andreas Huber TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1); 754072f5247ef893e683728263a540bb93daafda376Andreas Huber trackInfo->mTrackNum = track->GetNumber(); 755072f5247ef893e683728263a540bb93daafda376Andreas Huber trackInfo->mMeta = meta; 756072f5247ef893e683728263a540bb93daafda376Andreas Huber } 757072f5247ef893e683728263a540bb93daafda376Andreas Huber} 758072f5247ef893e683728263a540bb93daafda376Andreas Huber 7596bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Hubervoid MatroskaExtractor::findThumbnails() { 7606bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 7616bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber TrackInfo *info = &mTracks.editItemAt(i); 7626bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 7636bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber const char *mime; 7646bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber CHECK(info->mMeta->findCString(kKeyMIMEType, &mime)); 7656bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 7666bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if (strncasecmp(mime, "video/", 6)) { 7676bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber continue; 7686bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 7696bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 7708885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber BlockIterator iter(this, info->mTrackNum); 7716bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber int32_t i = 0; 7726bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber int64_t thumbnailTimeUs = 0; 7736bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber size_t maxBlockSize = 0; 7746bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber while (!iter.eos() && i < 20) { 7756bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if (iter.block()->IsKey()) { 7766bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber ++i; 7776bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 7788885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber size_t blockSize = 0; 7798885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber for (int i = 0; i < iter.block()->GetFrameCount(); ++i) { 7808885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber blockSize += iter.block()->GetFrame(i).len; 7818885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber } 7828885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 7836bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber if (blockSize > maxBlockSize) { 7846bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber maxBlockSize = blockSize; 7856bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber thumbnailTimeUs = iter.blockTimeUs(); 7866bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 7876bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 7886bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber iter.advance(); 7896bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 7906bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 7916bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber } 7926bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber} 7936bdf2edba4de7f971639e8a50e938d218b6d7299Andreas Huber 794072f5247ef893e683728263a540bb93daafda376Andreas Hubersp<MetaData> MatroskaExtractor::getMetaData() { 795072f5247ef893e683728263a540bb93daafda376Andreas Huber sp<MetaData> meta = new MetaData; 7966e37cf90f90678a083eef57c62d47831fd208f48Andreas Huber 7976e37cf90f90678a083eef57c62d47831fd208f48Andreas Huber meta->setCString( 7986e37cf90f90678a083eef57c62d47831fd208f48Andreas Huber kKeyMIMEType, 7996e37cf90f90678a083eef57c62d47831fd208f48Andreas Huber mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA); 800072f5247ef893e683728263a540bb93daafda376Andreas Huber 801072f5247ef893e683728263a540bb93daafda376Andreas Huber return meta; 802072f5247ef893e683728263a540bb93daafda376Andreas Huber} 803072f5247ef893e683728263a540bb93daafda376Andreas Huber 8048885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huberuint32_t MatroskaExtractor::flags() const { 8058885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber uint32_t x = CAN_PAUSE; 8068885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber if (!isLiveStreaming()) { 8078885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK; 8088885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber } 8098885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 8108885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber return x; 8118885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber} 8128885e679fc65ff856898fccd6fca8a388f42a4e5Andreas Huber 813072f5247ef893e683728263a540bb93daafda376Andreas Huberbool SniffMatroska( 814efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 815efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber sp<AMessage> *) { 816072f5247ef893e683728263a540bb93daafda376Andreas Huber DataSourceReader reader(source); 817072f5247ef893e683728263a540bb93daafda376Andreas Huber mkvparser::EBMLHeader ebmlHeader; 818072f5247ef893e683728263a540bb93daafda376Andreas Huber long long pos; 819072f5247ef893e683728263a540bb93daafda376Andreas Huber if (ebmlHeader.Parse(&reader, pos) < 0) { 820072f5247ef893e683728263a540bb93daafda376Andreas Huber return false; 821072f5247ef893e683728263a540bb93daafda376Andreas Huber } 822072f5247ef893e683728263a540bb93daafda376Andreas Huber 823072f5247ef893e683728263a540bb93daafda376Andreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA); 824072f5247ef893e683728263a540bb93daafda376Andreas Huber *confidence = 0.6; 825072f5247ef893e683728263a540bb93daafda376Andreas Huber 826072f5247ef893e683728263a540bb93daafda376Andreas Huber return true; 827072f5247ef893e683728263a540bb93daafda376Andreas Huber} 828072f5247ef893e683728263a540bb93daafda376Andreas Huber 829072f5247ef893e683728263a540bb93daafda376Andreas Huber} // namespace android 830