MatroskaExtractor.cpp revision b10f3669a9b73cd024662c2b70f5155bc0c2cd21
1093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber/* 2093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Copyright (C) 2010 The Android Open Source Project 3093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * 4093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * you may not use this file except in compliance with the License. 6093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * You may obtain a copy of the License at 7093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * 8093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * 10093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Unless required by applicable law or agreed to in writing, software 11093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * See the License for the specific language governing permissions and 14093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * limitations under the License. 15093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber */ 16093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 17093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//#define LOG_NDEBUG 0 18093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#define LOG_TAG "MatroskaExtractor" 19093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <utils/Log.h> 20093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 21093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "MatroskaExtractor.h" 22093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 23093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "mkvparser.hpp" 24093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 25b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include <media/stagefright/foundation/ADebug.h> 26b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include <media/stagefright/foundation/hexdump.h> 27093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/DataSource.h> 28093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaBuffer.h> 29093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaDefs.h> 30093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaErrors.h> 31093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaSource.h> 32093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MetaData.h> 33b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include <media/stagefright/Utils.h> 34093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <utils/String8.h> 35093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 36093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubernamespace android { 37093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 38093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstruct DataSourceReader : public mkvparser::IMkvReader { 39093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader(const sp<DataSource> &source) 40093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mSource(source) { 41093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 42093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 43093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual int Read(long long position, long length, unsigned char* buffer) { 44093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(position >= 0); 45093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(length >= 0); 46093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 47093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (length == 0) { 48093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 49093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 50093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 51093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber ssize_t n = mSource->readAt(position, buffer, length); 52093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 53093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (n <= 0) { 54093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return -1; 55093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 56093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 57093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 58093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 59093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 60093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual int Length(long long* total, long long* available) { 61093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber off_t size; 62093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (mSource->getSize(&size) != OK) { 63093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return -1; 64093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 65093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 66093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (total) { 67093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *total = size; 68093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 69093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 70093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (available) { 71093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *available = size; 72093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 73093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 74093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 75093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 76093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 77093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate: 78093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<DataSource> mSource; 79093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 80093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader(const DataSourceReader &); 81093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader &operator=(const DataSourceReader &); 82093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; 83093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 84093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 85093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberstruct BlockIterator { 875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator(mkvparser::Segment *segment, unsigned long trackNum); 885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber bool eos() const; 905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void advance(); 925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void reset(); 935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void seek(int64_t seekTimeUs); 945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::Block *block() const; 965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t blockTimeUs() const; 975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberprivate: 995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mkvparser::Segment *mSegment; 1005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber unsigned long mTrackNum; 1015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mkvparser::Cluster *mCluster; 1035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::BlockEntry *mBlockEntry; 1045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator(const BlockIterator &); 1065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator &operator=(const BlockIterator &); 1075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}; 1085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 109093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstruct MatroskaSource : public MediaSource { 110093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource( 111093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MatroskaExtractor> &extractor, size_t index); 112093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 113093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t start(MetaData *params); 114093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t stop(); 115093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 116093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual sp<MetaData> getFormat(); 117093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 118093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t read( 119093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MediaBuffer **buffer, const ReadOptions *options); 120093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 121093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate: 122093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber enum Type { 123093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber AVC, 124093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber AAC, 125093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber OTHER 126093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber }; 127093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 128093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MatroskaExtractor> mExtractor; 129093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t mTrackIndex; 130093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber Type mType; 1315279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator mBlockIter; 132b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber size_t mNALSizeLen; // for type AVC 133093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 134093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber status_t advance(); 135093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 136093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource(const MatroskaSource &); 137093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource &operator=(const MatroskaSource &); 138093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; 139093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 140093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaSource::MatroskaSource( 141093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MatroskaExtractor> &extractor, size_t index) 142093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mExtractor(extractor), 143093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTrackIndex(index), 144093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType(OTHER), 1455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter(mExtractor->mSegment, 146b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mExtractor->mTracks.itemAt(index).mTrackNum), 147b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mNALSizeLen(0) { 148b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta; 149b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 150093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *mime; 151b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 152093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 153093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 154093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AVC; 155b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 156b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber uint32_t dummy; 157b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber const uint8_t *avcc; 158b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber size_t avccSize; 159b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK(meta->findData( 160b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber kKeyAVCC, &dummy, (const void **)&avcc, &avccSize)); 161b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 162b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK_GE(avccSize, 5u); 163b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 164b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mNALSizeLen = 1 + (avcc[4] & 3); 165b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber LOGV("mNALSizeLen = %d", mNALSizeLen); 166093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 167093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AAC; 168093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 169093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 170093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 171093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::start(MetaData *params) { 1725279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter.reset(); 173093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 174093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 175093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 176093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 177093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::stop() { 178093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 179093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 180093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 181093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaSource::getFormat() { 182093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mExtractor->mTracks.itemAt(mTrackIndex).mMeta; 183093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 184093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber//////////////////////////////////////////////////////////////////////////////// 1865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas HuberBlockIterator::BlockIterator( 1885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mkvparser::Segment *segment, unsigned long trackNum) 1895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber : mSegment(segment), 1905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mTrackNum(trackNum), 1915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster(NULL), 1925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry(NULL) { 1935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber reset(); 1945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 1955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberbool BlockIterator::eos() const { 1975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mCluster == NULL || mCluster->EOS(); 1985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 1995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::advance() { 2015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos()) { 2025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockEntry != NULL) { 2035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry = mCluster->GetNext(mBlockEntry); 2045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } else if (mCluster != NULL) { 2055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster = mSegment->GetNext(mCluster); 2065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (eos()) { 2085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 209093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 211093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mBlockEntry = mCluster->GetFirst(); 212093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 213093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockEntry != NULL 2155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber && mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) { 2165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 217093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 2195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::reset() { 2225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster = mSegment->GetFirst(); 2235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry = mCluster->GetFirst(); 224093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos() && block()->GetTrackNumber() != mTrackNum) { 2265279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber advance(); 227093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 2285279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 229093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::seek(int64_t seekTimeUs) { 231ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber mCluster = mSegment->FindCluster(seekTimeUs * 1000ll); 2325279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockEntry = mCluster != NULL ? mCluster->GetFirst() : NULL; 2335279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos() && block()->GetTrackNumber() != mTrackNum) { 2355279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber advance(); 2365279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 2375279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2385279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!eos() && !mBlockEntry->GetBlock()->IsKey()) { 2395279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber advance(); 2405279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 241093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 242093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2435279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberconst mkvparser::Block *BlockIterator::block() const { 2445279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber CHECK(!eos()); 2455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mBlockEntry->GetBlock(); 2475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2485279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberint64_t BlockIterator::blockTimeUs() const { 2505279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll; 2515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 2525279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2535279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber//////////////////////////////////////////////////////////////////////////////// 2545279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 255b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huberstatic unsigned U24_AT(const uint8_t *ptr) { 256b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; 257b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber} 258b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 259093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::read( 260093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MediaBuffer **out, const ReadOptions *options) { 261093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *out = NULL; 262093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 263093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber int64_t seekTimeUs; 264abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 265abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 2665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter.seek(seekTimeUs); 267093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 268093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 269b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huberagain: 2705279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockIter.eos()) { 271093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return ERROR_END_OF_STREAM; 272093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 273093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2745279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::Block *block = mBlockIter.block(); 275093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t size = block->GetSize(); 2765279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t timeUs = mBlockIter.blockTimeUs(); 277093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 278b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber // In the case of AVC content, each NAL unit is prefixed by 279b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber // mNALSizeLen bytes of length. We want to prefix the data with 280b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber // a four-byte 0x00000001 startcode instead of the length prefix. 281b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber // mNALSizeLen ranges from 1 through 4 bytes, so add an extra 282b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber // 3 bytes of padding to the buffer start. 283b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber static const size_t kPadding = 3; 284b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 285b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber MediaBuffer *buffer = new MediaBuffer(size + kPadding); 2865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber buffer->meta_data()->setInt64(kKeyTime, timeUs); 2878bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber buffer->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey()); 288093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 289093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long res = block->Read( 290b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mExtractor->mReader, (unsigned char *)buffer->data() + kPadding); 291093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 292093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (res != 0) { 293093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return ERROR_END_OF_STREAM; 294093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 295093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 296b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber buffer->set_range(kPadding, size); 297093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 298093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (mType == AVC) { 299b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK_GE(size, mNALSizeLen); 300093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 301093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *data = (uint8_t *)buffer->data(); 302093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 303b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber size_t NALsize; 304b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber switch (mNALSizeLen) { 305b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber case 1: NALsize = data[kPadding]; break; 306b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber case 2: NALsize = U16_AT(&data[kPadding]); break; 307b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber case 3: NALsize = U24_AT(&data[kPadding]); break; 308b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber case 4: NALsize = U32_AT(&data[kPadding]); break; 309b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber default: 310b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber TRESPASS(); 311b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber } 312b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 313b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber CHECK_GE(size, NALsize + mNALSizeLen); 314b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber if (size > NALsize + mNALSizeLen) { 315b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber LOGW("discarding %d bytes of data.", size - NALsize - mNALSizeLen); 316b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber } 317b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 318b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber // actual data starts at &data[kPadding + mNALSizeLen] 319093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 320b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber memcpy(&data[mNALSizeLen - 1], "\x00\x00\x00\x01", 4); 321b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber buffer->set_range(mNALSizeLen - 1, NALsize + 4); 322093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (mType == AAC) { 323093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // There's strange junk at the beginning... 324093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 325b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber const uint8_t *data = (const uint8_t *)buffer->data() + kPadding; 326b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 327b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber // hexdump(data, size); 328b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 329093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t offset = 0; 330093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber while (offset < size && data[offset] != 0x21) { 331093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber ++offset; 332093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 333b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 334b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber if (size == offset) { 335b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber buffer->release(); 336b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 337b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber mBlockIter.advance(); 338b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber goto again; 339b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber } 340b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 341b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber buffer->set_range(kPadding + offset, size - offset); 342093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 343093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 344093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *out = buffer; 345093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 346093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#if 0 347093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber hexdump((const uint8_t *)buffer->data() + buffer->range_offset(), 348093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber buffer->range_length()); 349093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#endif 350093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 3515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter.advance(); 352093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 353093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 354093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 355093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 356093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 357093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 358093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source) 359093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mDataSource(source), 360093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mReader(new DataSourceReader(mDataSource)), 3615279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mSegment(NULL), 3625279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mExtractedThumbnails(false) { 363093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 364093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 365093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(mReader, pos) < 0) { 366093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 367093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 368093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 369093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long ret = 370093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::Segment::CreateInstance(mReader, pos, mSegment); 371093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 372093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret) { 373093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(mSegment == NULL); 374093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 375093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 376093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 377093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber ret = mSegment->Load(); 378093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 379093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret < 0) { 380093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 381093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 382093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 383093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 384093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 385093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addTracks(); 386093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 387093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 388093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::~MatroskaExtractor() { 389093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 390093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 391093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 392093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mReader; 393093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mReader = NULL; 394093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 395093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 396093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersize_t MatroskaExtractor::countTracks() { 397093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mTracks.size(); 398093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 399093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 400093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MediaSource> MatroskaExtractor::getTrack(size_t index) { 401093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 402093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return NULL; 403093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 404093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 405093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return new MatroskaSource(this, index); 406093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 407093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 408093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getTrackMetaData( 409093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t index, uint32_t flags) { 410093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 411093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return NULL; 412093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 413093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 4145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails) { 4155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber findThumbnails(); 4165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mExtractedThumbnails = true; 4175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 4185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 419093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mTracks.itemAt(index).mMeta; 420093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 421093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 422093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic void addESDSFromAudioSpecificInfo( 423093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MetaData> &meta, const void *asi, size_t asiSize) { 424093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static const uint8_t kStaticESDS[] = { 425093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x03, 22, 426093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, // ES_ID 427093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 428093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 429093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x04, 17, 430093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x40, // Audio ISO/IEC 14496-3 431093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 432093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 433093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x00, 0x00, 0x00, 0x00, 434093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 435093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 0x05, 436093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // AudioSpecificInfo (with size prefix) follows 437093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber }; 438093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 439093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(asiSize < 128); 440093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1; 441093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *esds = new uint8_t[esdsSize]; 442093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber memcpy(esds, kStaticESDS, sizeof(kStaticESDS)); 443093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *ptr = esds + sizeof(kStaticESDS); 444093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *ptr++ = asiSize; 445093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber memcpy(ptr, asi, asiSize); 446093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 447093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyESDS, 0, esds, esdsSize); 448093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 449093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete[] esds; 450093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber esds = NULL; 451093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 452093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 453093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid addVorbisCodecInfo( 454093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const sp<MetaData> &meta, 455093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const void *_codecPrivate, size_t codecPrivateSize) { 456093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // printf("vorbis private data follows:\n"); 457093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // hexdump(_codecPrivate, codecPrivateSize); 458093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 459093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize >= 3); 460093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 461093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate; 462093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[0] == 0x02); 463093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 464093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t len1 = codecPrivate[1]; 465093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t len2 = codecPrivate[2]; 466093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 467093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize > 3 + len1 + len2); 468093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 469093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[3] == 0x01); 470093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1); 471093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 472093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[len1 + 3] == 0x03); 473093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 474093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivate[len1 + len2 + 3] == 0x05); 475093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData( 476093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3], 477093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber codecPrivateSize - len1 - len2 - 3); 478093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 479093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 480093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid MatroskaExtractor::addTracks() { 481093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Tracks *tracks = mSegment->GetTracks(); 482093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 483093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber for (size_t index = 0; index < tracks->GetTracksCount(); ++index) { 484093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Track *track = tracks->GetTrackByIndex(index); 485093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 486093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *const codecID = track->GetCodecId(); 487093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber LOGV("codec id = %s", codecID); 488093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber LOGV("codec name = %s", track->GetCodecNameAsUTF8()); 489093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 490093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t codecPrivateSize; 491093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const unsigned char *codecPrivate = 492ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber track->GetCodecPrivate(codecPrivateSize); 493093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 494093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; 495093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 496093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MetaData> meta = new MetaData; 497093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 498093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber switch (track->GetType()) { 499093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case VIDEO_TRACK: 500093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 501093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::VideoTrack *vtrack = 502093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::VideoTrack *>(track); 503093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 504093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { 505093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 506093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); 507093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("V_VP8", codecID)) { 508093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX); 509093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 510093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 511093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 512093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 513093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyWidth, vtrack->GetWidth()); 514093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyHeight, vtrack->GetHeight()); 515093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 516093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 517093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 518093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case AUDIO_TRACK: 519093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 520093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::AudioTrack *atrack = 521093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::AudioTrack *>(track); 522093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 523093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcmp("A_AAC", codecID)) { 524093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 525093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize >= 2); 526093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 527093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addESDSFromAudioSpecificInfo( 528093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta, codecPrivate, codecPrivateSize); 529093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("A_VORBIS", codecID)) { 530093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); 531093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 532093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize); 533093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 534093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 535093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 536093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 537093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeySampleRate, atrack->GetSamplingRate()); 538093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt32(kKeyChannelCount, atrack->GetChannels()); 539093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 540093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 541093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 542093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber default: 543093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 544093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 545093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 546093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long durationNs = mSegment->GetDuration(); 547093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setInt64(kKeyDuration, (durationNs + 500) / 1000); 548093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 549093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTracks.push(); 550093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1); 551093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber trackInfo->mTrackNum = track->GetNumber(); 552093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber trackInfo->mMeta = meta; 553093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 554093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 555093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 5565279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid MatroskaExtractor::findThumbnails() { 5575279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 5585279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber TrackInfo *info = &mTracks.editItemAt(i); 5595279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 5605279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const char *mime; 5615279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber CHECK(info->mMeta->findCString(kKeyMIMEType, &mime)); 5625279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 5635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (strncasecmp(mime, "video/", 6)) { 5645279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber continue; 5655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 5665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 5675279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator iter(mSegment, info->mTrackNum); 5685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int32_t i = 0; 5695279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t thumbnailTimeUs = 0; 5705279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber size_t maxBlockSize = 0; 5715279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber while (!iter.eos() && i < 20) { 5725279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (iter.block()->IsKey()) { 5735279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber ++i; 5745279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 5755279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber size_t blockSize = iter.block()->GetSize(); 5765279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (blockSize > maxBlockSize) { 5775279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber maxBlockSize = blockSize; 5785279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber thumbnailTimeUs = iter.blockTimeUs(); 5795279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 5805279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 5815279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber iter.advance(); 5825279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 5835279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 5845279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 5855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 5865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 587093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getMetaData() { 588093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber sp<MetaData> meta = new MetaData; 589093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MATROSKA); 590093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 591093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return meta; 592093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 593093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 594093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberbool SniffMatroska( 5955a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 5965a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 597093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber DataSourceReader reader(source); 598093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 599093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 600093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(&reader, pos) < 0) { 601093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return false; 602093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 603093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 604093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA); 605093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *confidence = 0.6; 606093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 607093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return true; 608093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 609093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 610093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} // namespace android 611