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 21f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia#include "FLACDecoder.h" 22093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "MatroskaExtractor.h" 23093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 242a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen#include <media/DataSourceBase.h> 25a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen#include <media/ExtractorUtils.h> 263d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <media/MediaTrack.h> 27b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include <media/stagefright/foundation/ADebug.h> 282dcf6138ebc9c5688aeae151d2fbde55a2826128Robert Shih#include <media/stagefright/foundation/AUtils.h> 294f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih#include <media/stagefright/foundation/ABuffer.h> 30607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang#include <media/stagefright/foundation/ByteUtils.h> 31d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar#include <media/stagefright/foundation/ColorUtils.h> 32b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include <media/stagefright/foundation/hexdump.h> 331889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang#include <media/stagefright/MediaBufferBase.h> 34093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaDefs.h> 35093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaErrors.h> 36093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MetaData.h> 377dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang#include <media/stagefright/MetaDataUtils.h> 38093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <utils/String8.h> 39093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 40a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih#include <arpa/inet.h> 41b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross#include <inttypes.h> 42a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih#include <vector> 43b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross 44093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubernamespace android { 45093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 462a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissenstruct DataSourceBaseReader : public mkvparser::IMkvReader { 472a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen explicit DataSourceBaseReader(DataSourceBase *source) 48093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mSource(source) { 49093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 50093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 51093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual int Read(long long position, long length, unsigned char* buffer) { 52093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(position >= 0); 53093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(length >= 0); 54093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 55093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (length == 0) { 56093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 57093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 58093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 59093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber ssize_t n = mSource->readAt(position, buffer, length); 60093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 61093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (n <= 0) { 62093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return -1; 63093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 64093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 65093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 66093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 67093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 68093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual int Length(long long* total, long long* available) { 69c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t size; 70093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (mSource->getSize(&size) != OK) { 71d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber *total = -1; 72d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber *available = (long long)((1ull << 63) - 1); 73d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 74d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber return 0; 75093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 76093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 77093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (total) { 78093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *total = size; 79093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 80093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 81093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (available) { 82093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *available = size; 83093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 84093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 85093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return 0; 86093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 87093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 88093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate: 892a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen DataSourceBase *mSource; 90093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 912a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen DataSourceBaseReader(const DataSourceBaseReader &); 922a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen DataSourceBaseReader &operator=(const DataSourceBaseReader &); 93093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; 94093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 95093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 96093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberstruct BlockIterator { 982f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih BlockIterator(MatroskaExtractor *extractor, unsigned long trackNum, unsigned long index); 995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber bool eos() const; 1015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void advance(); 1035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber void reset(); 1045ec58d925520e6913fba3fc54413881af751c610Andreas Huber 1055ec58d925520e6913fba3fc54413881af751c610Andreas Huber void seek( 106f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann int64_t seekTimeUs, bool isAudio, 1075ec58d925520e6913fba3fc54413881af751c610Andreas Huber int64_t *actualFrameTimeUs); 1085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1095279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::Block *block() const; 1105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t blockTimeUs() const; 1115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1125279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberprivate: 113d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber MatroskaExtractor *mExtractor; 114b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross long long mTrackNum; 1152f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih unsigned long mIndex; 1165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 117d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber const mkvparser::Cluster *mCluster; 1185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::BlockEntry *mBlockEntry; 119d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long mBlockEntryIndex; 120d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 121d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber void advance_l(); 1225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator(const BlockIterator &); 1245279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator &operator=(const BlockIterator &); 1255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}; 1265279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1273d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstruct MatroskaSource : public MediaTrack { 1287d880c31d2079299000b036c6ae742dc695a5b19Marco Nelissen MatroskaSource(MatroskaExtractor *extractor, size_t index); 129093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1303d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen virtual status_t start(MetaDataBase *params); 131093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t stop(); 132093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1333d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen virtual status_t getFormat(MetaDataBase &); 134093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 135093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber virtual status_t read( 1361889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase **buffer, const ReadOptions *options); 137093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 13850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberprotected: 13950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber virtual ~MatroskaSource(); 14050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 141093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate: 142093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber enum Type { 143093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber AVC, 144093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber AAC, 145f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik HEVC, 146093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber OTHER 147093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber }; 148093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1497d880c31d2079299000b036c6ae742dc695a5b19Marco Nelissen MatroskaExtractor *mExtractor; 150093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t mTrackIndex; 151093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber Type mType; 15274a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber bool mIsAudio; 1535279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber BlockIterator mBlockIter; 154f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik ssize_t mNALSizeLen; // for type AVC or HEVC 155093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1561889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang List<MediaBufferBase *> mPendingFrames; 15750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 158093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber status_t advance(); 159093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1601889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang status_t setWebmBlockCryptoInfo(MediaBufferBase *mbuf); 16150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber status_t readBlock(); 16250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber void clearPendingFrames(); 16350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 164093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource(const MatroskaSource &); 165093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber MatroskaSource &operator=(const MatroskaSource &); 166093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}; 167093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1682f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihconst mkvparser::Track* MatroskaExtractor::TrackInfo::getTrack() const { 1692f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih return mExtractor->mSegment->GetTracks()->GetTrackByNumber(mTrackNum); 1702f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih} 1712f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih 1722f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih// This function does exactly the same as mkvparser::Cues::Find, except that it 1732f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih// searches in our own track based vectors. We should not need this once mkvparser 1742f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih// adds the same functionality. 1752f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shihconst mkvparser::CuePoint::TrackPosition *MatroskaExtractor::TrackInfo::find( 1762f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih long long timeNs) const { 1772f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih ALOGV("mCuePoints.size %zu", mCuePoints.size()); 1782f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih if (mCuePoints.empty()) { 1792f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih return NULL; 1802f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } 1812f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih 1822f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih const mkvparser::CuePoint* cp = mCuePoints.itemAt(0); 1832f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih const mkvparser::Track* track = getTrack(); 1842f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih if (timeNs <= cp->GetTime(mExtractor->mSegment)) { 1852f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih return cp->Find(track); 1862f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } 1872f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih 1882f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih // Binary searches through relevant cues; assumes cues are ordered by timecode. 1892f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih // If we do detect out-of-order cues, return NULL. 1902f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih size_t lo = 0; 1912f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih size_t hi = mCuePoints.size(); 1922f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih while (lo < hi) { 1932f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih const size_t mid = lo + (hi - lo) / 2; 1942f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih const mkvparser::CuePoint* const midCp = mCuePoints.itemAt(mid); 1952f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih const long long cueTimeNs = midCp->GetTime(mExtractor->mSegment); 1962f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih if (cueTimeNs <= timeNs) { 1972f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih lo = mid + 1; 1982f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } else { 1992f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih hi = mid; 2002f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } 2012f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } 2022f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih 2032f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih if (lo == 0) { 2042f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih return NULL; 2052f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } 2062f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih 2072f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih cp = mCuePoints.itemAt(lo - 1); 2082f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih if (cp->GetTime(mExtractor->mSegment) > timeNs) { 2092f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih return NULL; 2102f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } 2112f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih 2122f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih return cp->Find(track); 2132f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih} 2142f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih 215093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaSource::MatroskaSource( 2167d880c31d2079299000b036c6ae742dc695a5b19Marco Nelissen MatroskaExtractor *extractor, size_t index) 217093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mExtractor(extractor), 218093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTrackIndex(index), 219093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType(OTHER), 22074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber mIsAudio(false), 2217d880c31d2079299000b036c6ae742dc695a5b19Marco Nelissen mBlockIter(mExtractor, 2222f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih mExtractor->mTracks.itemAt(index).mTrackNum, 2232f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih index), 2244f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih mNALSizeLen(-1) { 2253d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen MetaDataBase &meta = mExtractor->mTracks.editItemAt(index).mMeta; 226b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 227093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *mime; 2283d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen CHECK(meta.findCString(kKeyMIMEType, &mime)); 229093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 23074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber mIsAudio = !strncasecmp("audio/", mime, 6); 23174a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber 232093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 233093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AVC; 234b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 235b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber uint32_t dummy; 236b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber const uint8_t *avcc; 237b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber size_t avccSize; 2384f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih int32_t nalSizeLen = 0; 2393d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen if (meta.findInt32(kKeyNalLengthSize, &nalSizeLen)) { 2404f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih if (nalSizeLen >= 0 && nalSizeLen <= 4) { 2414f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih mNALSizeLen = nalSizeLen; 2424f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih } 2433d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen } else if (meta.findData(kKeyAVCC, &dummy, (const void **)&avcc, &avccSize) 2444f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih && avccSize >= 5u) { 2454f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih mNALSizeLen = 1 + (avcc[4] & 3); 2464f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih ALOGV("mNALSizeLen = %zd", mNALSizeLen); 2474f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih } else { 2484f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih ALOGE("No mNALSizeLen"); 2494f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih } 250f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { 251f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik mType = HEVC; 252f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik 253f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik uint32_t dummy; 254f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik const uint8_t *hvcc; 255f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik size_t hvccSize; 2563d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen if (meta.findData(kKeyHVCC, &dummy, (const void **)&hvcc, &hvccSize) 257f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik && hvccSize >= 22u) { 258f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik mNALSizeLen = 1 + (hvcc[14+7] & 3); 259f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik ALOGV("mNALSizeLen = %zu", mNALSizeLen); 260f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik } else { 261f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik ALOGE("No mNALSizeLen"); 262f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik } 263093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 264093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mType = AAC; 265093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 266093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 267093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 26850c8bea8fba2fcafb14696399028bdbc094dc995Andreas HuberMatroskaSource::~MatroskaSource() { 26950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 27050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 27150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 2723d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstatus_t MatroskaSource::start(MetaDataBase * /* params */) { 2734f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih if (mType == AVC && mNALSizeLen < 0) { 2744f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih return ERROR_MALFORMED; 2754f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih } 2764f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih 2775279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mBlockIter.reset(); 278093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 279093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 280093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 281093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 282093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::stop() { 28350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 28450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 285093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 286093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 287093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2883d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstatus_t MatroskaSource::getFormat(MetaDataBase &meta) { 2893d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta; 2903d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen return OK; 291093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 292093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 2935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber//////////////////////////////////////////////////////////////////////////////// 2945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 2955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas HuberBlockIterator::BlockIterator( 2962f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih MatroskaExtractor *extractor, unsigned long trackNum, unsigned long index) 297d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber : mExtractor(extractor), 2985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mTrackNum(trackNum), 2992f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih mIndex(index), 3005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mCluster(NULL), 301d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntry(NULL), 302d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntryIndex(0) { 3035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber reset(); 3045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 3055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberbool BlockIterator::eos() const { 3075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mCluster == NULL || mCluster->EOS(); 3085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 3095279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::advance() { 311d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 312d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber advance_l(); 313d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber} 314d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 315d42573cace9db2b5948e540c32beaef80f04153cAndreas Hubervoid BlockIterator::advance_l() { 316d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber for (;;) { 317d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry); 3183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("GetEntry returned %ld", res); 319d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 320d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long long pos; 321d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber long len; 322d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (res < 0) { 323d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber // Need to parse this cluster some more 324d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 325d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL); 326d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 327d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber res = mCluster->Parse(pos, len); 3283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Parse returned %ld", res); 329d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 330d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (res < 0) { 331d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber // I/O error 332d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 33329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Cluster::Parse returned result %ld", res); 3345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 335d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = NULL; 3365279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 337093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 3385279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 339d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber continue; 340d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } else if (res == 0) { 341d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber // We're done with this cluster 342d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 343d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber const mkvparser::Cluster *nextCluster; 344d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber res = mExtractor->mSegment->ParseNext( 345d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster, nextCluster, pos, len); 3463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("ParseNext returned %ld", res); 347d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 348e467ef084b75b074d0081616080b54212a7024c8Lajos Molnar if (res != 0) { 349e467ef084b75b074d0081616080b54212a7024c8Lajos Molnar // EOF or error 350d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 351d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = NULL; 352d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber break; 353d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } 354d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 355d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK_EQ(res, 0); 356d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(nextCluster != NULL); 357d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(!nextCluster->EOS()); 358d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 359d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = nextCluster; 360d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 361d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber res = mCluster->Parse(pos, len); 3623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Parse (2) returned %ld", res); 363918ddcc97b5679ba2afd0bfeb6f79be111ad6166Dongwon Kang 364918ddcc97b5679ba2afd0bfeb6f79be111ad6166Dongwon Kang if (res < 0) { 365918ddcc97b5679ba2afd0bfeb6f79be111ad6166Dongwon Kang // I/O error 366918ddcc97b5679ba2afd0bfeb6f79be111ad6166Dongwon Kang 367918ddcc97b5679ba2afd0bfeb6f79be111ad6166Dongwon Kang ALOGE("Cluster::Parse returned result %ld", res); 368918ddcc97b5679ba2afd0bfeb6f79be111ad6166Dongwon Kang 369918ddcc97b5679ba2afd0bfeb6f79be111ad6166Dongwon Kang mCluster = NULL; 370918ddcc97b5679ba2afd0bfeb6f79be111ad6166Dongwon Kang break; 371918ddcc97b5679ba2afd0bfeb6f79be111ad6166Dongwon Kang } 372d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 373d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntryIndex = 0; 374d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber continue; 375093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 376093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 377d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(mBlockEntry != NULL); 378d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber CHECK(mBlockEntry->GetBlock() != NULL); 379d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber ++mBlockEntryIndex; 380d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 381d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) { 3825279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber break; 383093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 3845279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 3855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 3865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 3875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::reset() { 388d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 389093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 390d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mCluster = mExtractor->mSegment->GetFirst(); 3912ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber mBlockEntry = NULL; 392d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockEntryIndex = 0; 393d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 394d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber do { 395d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber advance_l(); 396d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } while (!eos() && block()->GetTrackNumber() != mTrackNum); 3975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 398093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 3995ec58d925520e6913fba3fc54413881af751c610Andreas Hubervoid BlockIterator::seek( 400f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann int64_t seekTimeUs, bool isAudio, 4015ec58d925520e6913fba3fc54413881af751c610Andreas Huber int64_t *actualFrameTimeUs) { 402d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber Mutex::Autolock autoLock(mExtractor->mLock); 403d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 4045ec58d925520e6913fba3fc54413881af751c610Andreas Huber *actualFrameTimeUs = -1ll; 4055ec58d925520e6913fba3fc54413881af751c610Andreas Huber 4066b8937f4a81447968b22b75a6f1e450bbda1a18fMarco Nelissen if (seekTimeUs > INT64_MAX / 1000ll || 4076b8937f4a81447968b22b75a6f1e450bbda1a18fMarco Nelissen seekTimeUs < INT64_MIN / 1000ll || 4086b8937f4a81447968b22b75a6f1e450bbda1a18fMarco Nelissen (mExtractor->mSeekPreRollNs > 0 && 4096b8937f4a81447968b22b75a6f1e450bbda1a18fMarco Nelissen (seekTimeUs * 1000ll) < INT64_MIN + mExtractor->mSeekPreRollNs) || 4106b8937f4a81447968b22b75a6f1e450bbda1a18fMarco Nelissen (mExtractor->mSeekPreRollNs < 0 && 4116b8937f4a81447968b22b75a6f1e450bbda1a18fMarco Nelissen (seekTimeUs * 1000ll) > INT64_MAX + mExtractor->mSeekPreRollNs)) { 4126b8937f4a81447968b22b75a6f1e450bbda1a18fMarco Nelissen ALOGE("cannot seek to %lld", (long long) seekTimeUs); 4136b8937f4a81447968b22b75a6f1e450bbda1a18fMarco Nelissen return; 4146b8937f4a81447968b22b75a6f1e450bbda1a18fMarco Nelissen } 4156b8937f4a81447968b22b75a6f1e450bbda1a18fMarco Nelissen 416bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian const int64_t seekTimeNs = seekTimeUs * 1000ll - mExtractor->mSeekPreRollNs; 41710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann 41810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann mkvparser::Segment* const pSegment = mExtractor->mSegment; 41910f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann 42010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann // Special case the 0 seek to avoid loading Cues when the application 42110f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann // extraneously seeks to 0 before playing. 42210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann if (seekTimeNs <= 0) { 423b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("Seek to beginning: %" PRId64, seekTimeUs); 42410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann mCluster = pSegment->GetFirst(); 42510f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann mBlockEntryIndex = 0; 42610f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann do { 42710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann advance_l(); 42810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } while (!eos() && block()->GetTrackNumber() != mTrackNum); 42910f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann return; 43010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } 4315ec58d925520e6913fba3fc54413881af751c610Andreas Huber 432b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("Seeking to: %" PRId64, seekTimeUs); 43310f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann 43410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann // If the Cues have not been located then find them. 43510f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann const mkvparser::Cues* pCues = pSegment->GetCues(); 43610f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann const mkvparser::SeekHead* pSH = pSegment->GetSeekHead(); 43710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann if (!pCues && pSH) { 43810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann const size_t count = pSH->GetCount(); 43910f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann const mkvparser::SeekHead::Entry* pEntry; 44010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann ALOGV("No Cues yet"); 44110f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann 44210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann for (size_t index = 0; index < count; index++) { 44310f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann pEntry = pSH->GetEntry(index); 44410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann 44510f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann if (pEntry->id == 0x0C53BB6B) { // Cues ID 44610f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann long len; long long pos; 44710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann pSegment->ParseCues(pEntry->pos, pos, len); 44810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann pCues = pSegment->GetCues(); 449be7ac3d682729048af27871311808a76c618abdbJohann ALOGV("Cues found"); 45010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann break; 45110f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } 45210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } 45310f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann 45410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann if (!pCues) { 45510f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann ALOGE("No Cues in file"); 45610f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann return; 45710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } 45810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } 45910f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann else if (!pSH) { 46010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann ALOGE("No SeekHead"); 46110f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann return; 46210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } 46310f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann 46410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann const mkvparser::CuePoint* pCP; 4652f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih mkvparser::Tracks const *pTracks = pSegment->GetTracks(); 46610f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann while (!pCues->DoneParsing()) { 467be7ac3d682729048af27871311808a76c618abdbJohann pCues->LoadCuePoint(); 46810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann pCP = pCues->GetLast(); 4692f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih CHECK(pCP); 4702f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih 4710644f95a8976470e84c6c0a6d96585ae6437ecd2Robert Shih size_t trackCount = mExtractor->mTracks.size(); 4722f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih for (size_t index = 0; index < trackCount; ++index) { 4730644f95a8976470e84c6c0a6d96585ae6437ecd2Robert Shih MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(index); 4740644f95a8976470e84c6c0a6d96585ae6437ecd2Robert Shih const mkvparser::Track *pTrack = pTracks->GetTrackByNumber(track.mTrackNum); 4752f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih if (pTrack && pTrack->GetType() == 1 && pCP->Find(pTrack)) { // VIDEO_TRACK 4762f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih track.mCuePoints.push_back(pCP); 4772f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } 4782f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } 479be7ac3d682729048af27871311808a76c618abdbJohann 48010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann if (pCP->GetTime(pSegment) >= seekTimeNs) { 481be7ac3d682729048af27871311808a76c618abdbJohann ALOGV("Parsed past relevant Cue"); 48210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann break; 48310f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } 48410f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } 48510f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann 4862f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih const mkvparser::CuePoint::TrackPosition *pTP = NULL; 4870644f95a8976470e84c6c0a6d96585ae6437ecd2Robert Shih const mkvparser::Track *thisTrack = pTracks->GetTrackByNumber(mTrackNum); 4882f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih if (thisTrack->GetType() == 1) { // video 4892f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(mIndex); 4902f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih pTP = track.find(seekTimeNs); 4912f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } else { 4922f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih // The Cue index is built around video keyframes 4930644f95a8976470e84c6c0a6d96585ae6437ecd2Robert Shih unsigned long int trackCount = pTracks->GetTracksCount(); 4942f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih for (size_t index = 0; index < trackCount; ++index) { 4952f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih const mkvparser::Track *pTrack = pTracks->GetTrackByIndex(index); 4962f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih if (pTrack && pTrack->GetType() == 1 && pCues->Find(seekTimeNs, pTrack, pCP, pTP)) { 4972f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih ALOGV("Video track located at %zu", index); 4982f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih break; 4992f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } 50010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } 50110f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } 50210f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann 5032f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih 504f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann // Always *search* based on the video track, but finalize based on mTrackNum 5052f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih if (!pTP) { 506f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann ALOGE("Did not locate the video track for seeking"); 50710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann return; 50810f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann } 50910f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann 51010f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann mCluster = pSegment->FindOrPreloadCluster(pTP->m_pos); 5115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 512f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann CHECK(mCluster); 513f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann CHECK(!mCluster->EOS()); 514f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann 515f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann // mBlockEntryIndex starts at 0 but m_block starts at 1 516f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann CHECK_GT(pTP->m_block, 0); 517f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann mBlockEntryIndex = pTP->m_block - 1; 5185ec58d925520e6913fba3fc54413881af751c610Andreas Huber 5195ec58d925520e6913fba3fc54413881af751c610Andreas Huber for (;;) { 520d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber advance_l(); 5215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 522f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann if (eos()) break; 5235ec58d925520e6913fba3fc54413881af751c610Andreas Huber 524f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann if (isAudio || block()->IsKey()) { 525f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann // Accept the first key frame 5262f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih int64_t frameTimeUs = (block()->GetTime(mCluster) + 500LL) / 1000LL; 5272f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih if (thisTrack->GetType() == 1 || frameTimeUs >= seekTimeUs) { 5282f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih *actualFrameTimeUs = frameTimeUs; 5292f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih ALOGV("Requested seek point: %" PRId64 " actual: %" PRId64, 5302f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih seekTimeUs, *actualFrameTimeUs); 5312f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih break; 5322f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih } 53374a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber } 5345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 535093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 536093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 5375279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberconst mkvparser::Block *BlockIterator::block() const { 5385279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber CHECK(!eos()); 5395279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 5405279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return mBlockEntry->GetBlock(); 5415279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 5425279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 5435279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberint64_t BlockIterator::blockTimeUs() const { 5444f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih if (mCluster == NULL || mBlockEntry == NULL) { 5454f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih return -1; 5464f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih } 5475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll; 5485279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 5495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 5505279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber//////////////////////////////////////////////////////////////////////////////// 5515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 552b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huberstatic unsigned U24_AT(const uint8_t *ptr) { 553b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber return ptr[0] << 16 | ptr[1] << 8 | ptr[2]; 554b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber} 555b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 556b486b52b2b67961073677d583a02269cbdc9a3fcDongwon Kangstatic AString uriDebugString(const char *uri) { 557607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang // find scheme 558607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang AString scheme; 559b486b52b2b67961073677d583a02269cbdc9a3fcDongwon Kang for (size_t i = 0; i < strlen(uri); i++) { 560b486b52b2b67961073677d583a02269cbdc9a3fcDongwon Kang const char c = uri[i]; 561607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang if (!isascii(c)) { 562607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang break; 563607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang } else if (isalpha(c)) { 564607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang continue; 565607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang } else if (i == 0) { 566607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang // first character must be a letter 567607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang break; 568607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang } else if (isdigit(c) || c == '+' || c == '.' || c =='-') { 569607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang continue; 570607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang } else if (c != ':') { 571607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang break; 572607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang } 573607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang scheme = AString(uri, 0, i); 574607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang scheme.append("://<suppressed>"); 575607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang return scheme; 576607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang } 577607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang return AString("<no-scheme URI suppressed>"); 578607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang} 579607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang 58050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Hubervoid MatroskaSource::clearPendingFrames() { 58150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber while (!mPendingFrames.empty()) { 5821889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase *frame = *mPendingFrames.begin(); 58350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 58450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 58550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame->release(); 58650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber frame = NULL; 58750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 58850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 58950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 5901889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kangstatus_t MatroskaSource::setWebmBlockCryptoInfo(MediaBufferBase *mbuf) { 591793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih if (mbuf->range_length() < 1 || mbuf->range_length() - 1 > INT32_MAX) { 592793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih // 1-byte signal 593793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih return ERROR_MALFORMED; 594793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 595793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 596793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih const uint8_t *data = (const uint8_t *)mbuf->data() + mbuf->range_offset(); 597a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih bool encrypted = data[0] & 0x1; 598a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih bool partitioned = data[0] & 0x2; 599a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih if (encrypted && mbuf->range_length() < 9) { 600793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih // 1-byte signal + 8-byte IV 601793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih return ERROR_MALFORMED; 602793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 603793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 6043d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen MetaDataBase &meta = mbuf->meta_data(); 605a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih if (encrypted) { 606793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih uint8_t ctrCounter[16] = { 0 }; 607793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih uint32_t type; 608793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih const uint8_t *keyId; 609793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih size_t keyIdSize; 6103d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen const MetaDataBase &trackMeta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta; 6113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen CHECK(trackMeta.findData(kKeyCryptoKey, &type, (const void **)&keyId, &keyIdSize)); 6123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData(kKeyCryptoKey, 0, keyId, keyIdSize); 613793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih memcpy(ctrCounter, data + 1, 8); 6143d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData(kKeyCryptoIV, 0, ctrCounter, 16); 615a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih if (partitioned) { 616a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih /* 0 1 2 3 617a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 618a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 619a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | Signal Byte | | 620a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * +-+-+-+-+-+-+-+-+ IV | 621a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | | 622a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 623a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | | num_partition | Partition 0 offset -> | 624a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| 625a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | -> Partition 0 offset | ... | 626a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| 627a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | ... | Partition n-1 offset -> | 628a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| 629a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | -> Partition n-1 offset | | 630a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 631a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | Clear/encrypted sample data | 632a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | | 633a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | | 634a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 635a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih */ 636a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih if (mbuf->range_length() < 10) { 637a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih return ERROR_MALFORMED; 638a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih } 639a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih uint8_t numPartitions = data[9]; 640a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih if (mbuf->range_length() - 10 < numPartitions * sizeof(uint32_t)) { 641a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih return ERROR_MALFORMED; 642a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih } 643a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih std::vector<uint32_t> plainSizes, encryptedSizes; 644a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih uint32_t prev = 0; 645a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih uint32_t frameOffset = 10 + numPartitions * sizeof(uint32_t); 646a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih const uint32_t *partitions = reinterpret_cast<const uint32_t*>(data + 10); 647a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih for (uint32_t i = 0; i <= numPartitions; ++i) { 648a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih uint32_t p_i = i < numPartitions 649a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih ? ntohl(partitions[i]) 650a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih : (mbuf->range_length() - frameOffset); 651a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih if (p_i < prev) { 652a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih return ERROR_MALFORMED; 653a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih } 654a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih uint32_t size = p_i - prev; 655a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih prev = p_i; 656a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih if (i % 2) { 657a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih encryptedSizes.push_back(size); 658a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih } else { 659a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih plainSizes.push_back(size); 660a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih } 661a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih } 662a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih if (plainSizes.size() > encryptedSizes.size()) { 663a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih encryptedSizes.push_back(0); 664a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih } 665a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih uint32_t sizeofPlainSizes = sizeof(uint32_t) * plainSizes.size(); 666a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih uint32_t sizeofEncryptedSizes = sizeof(uint32_t) * encryptedSizes.size(); 667a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih meta.setData(kKeyPlainSizes, 0, plainSizes.data(), sizeofPlainSizes); 668a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih meta.setData(kKeyEncryptedSizes, 0, encryptedSizes.data(), sizeofEncryptedSizes); 669a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih mbuf->set_range(frameOffset, mbuf->range_length() - frameOffset); 670a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih } else { 671a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih /* 672a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * 0 1 2 3 673a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 674a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 675a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | Signal Byte | | 676a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * +-+-+-+-+-+-+-+-+ IV | 677a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | | 678a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 679a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | | | 680a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * |-+-+-+-+-+-+-+-+ | 681a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * : Bytes 1..N of encrypted frame : 682a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | | 683a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * | | 684a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 685a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih */ 686a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih int32_t plainSizes[] = { 0 }; 687a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih int32_t encryptedSizes[] = { static_cast<int32_t>(mbuf->range_length() - 9) }; 688a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes)); 689a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes)); 690a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih mbuf->set_range(9, mbuf->range_length() - 9); 691a2c4181b9cc30703b0471831e2e5fa03253b5690Robert Shih } 692793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } else { 693793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih /* 694793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih * 0 1 2 3 695793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 696793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 697793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih * | Signal Byte | | 698793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih * +-+-+-+-+-+-+-+-+ | 699793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih * : Bytes 1..N of unencrypted frame : 700793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih * | | 701793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih * | | 702793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 703793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih */ 704793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih int32_t plainSizes[] = { static_cast<int32_t>(mbuf->range_length() - 1) }; 705793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih int32_t encryptedSizes[] = { 0 }; 7063d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes)); 7073d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes)); 708793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih mbuf->set_range(1, mbuf->range_length() - 1); 709793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 710793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 711793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih return OK; 712793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih} 713793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 71450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::readBlock() { 71550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber CHECK(mPendingFrames.empty()); 71650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 7175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (mBlockIter.eos()) { 718093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return ERROR_END_OF_STREAM; 719093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 720093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 7215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const mkvparser::Block *block = mBlockIter.block(); 72250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 7235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t timeUs = mBlockIter.blockTimeUs(); 724093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 725d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber for (int i = 0; i < block->GetFrameCount(); ++i) { 726580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih MatroskaExtractor::TrackInfo *trackInfo = &mExtractor->mTracks.editItemAt(mTrackIndex); 727d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber const mkvparser::Block::Frame &frame = block->GetFrame(i); 728580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih size_t len = frame.len; 729580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih if (SIZE_MAX - len < trackInfo->mHeaderLen) { 730580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih return ERROR_MALFORMED; 731580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih } 732580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih 733580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih len += trackInfo->mHeaderLen; 7341889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase *mbuf = MediaBufferBase::Create(len); 735580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih uint8_t *data = static_cast<uint8_t *>(mbuf->data()); 736580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih if (trackInfo->mHeader) { 737580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih memcpy(data, trackInfo->mHeader, trackInfo->mHeaderLen); 738580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih } 739b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber 7403d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mbuf->meta_data().setInt64(kKeyTime, timeUs); 7413d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mbuf->meta_data().setInt32(kKeyIsSyncFrame, block->IsKey()); 742093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 743580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih status_t err = frame.Read(mExtractor->mReader, data + trackInfo->mHeaderLen); 744793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih if (err == OK 745793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih && mExtractor->mIsWebm 746580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih && trackInfo->mEncrypted) { 747793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih err = setWebmBlockCryptoInfo(mbuf); 748793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 749793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 750793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih if (err != OK) { 751d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mPendingFrames.clear(); 75250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 753d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockIter.advance(); 754ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen mbuf->release(); 755793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih return err; 75650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 75750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 75850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.push_back(mbuf); 75950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 76050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 761d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mBlockIter.advance(); 76250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 76350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return OK; 76450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber} 76550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 76650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::read( 7671889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase **out, const ReadOptions *options) { 76850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = NULL; 76950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 7705ec58d925520e6913fba3fc54413881af751c610Andreas Huber int64_t targetSampleTimeUs = -1ll; 7715ec58d925520e6913fba3fc54413881af751c610Andreas Huber 77250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber int64_t seekTimeUs; 77350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber ReadOptions::SeekMode mode; 774d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang if (options && options->getSeekTo(&seekTimeUs, &mode)) { 775d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang if (mode == ReadOptions::SEEK_FRAME_INDEX) { 776d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang return ERROR_UNSUPPORTED; 777d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang } 778d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang 779d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang if (!mExtractor->isLiveStreaming()) { 780d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang clearPendingFrames(); 781d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang 782d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang // The audio we want is located by using the Cues to seek the video 783d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang // stream to find the target Cluster then iterating to finalize for 784d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang // audio. 785d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang int64_t actualFrameTimeUs; 786d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang mBlockIter.seek(seekTimeUs, mIsAudio, &actualFrameTimeUs); 787d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang if (mode == ReadOptions::SEEK_CLOSEST) { 788d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang targetSampleTimeUs = actualFrameTimeUs; 789d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang } 7905ec58d925520e6913fba3fc54413881af751c610Andreas Huber } 79150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 79250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 79350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber while (mPendingFrames.empty()) { 79450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber status_t err = readBlock(); 79550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 79650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber if (err != OK) { 79750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber clearPendingFrames(); 79850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 79950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return err; 80050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 80150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 80250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 8031889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase *frame = *mPendingFrames.begin(); 80450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber mPendingFrames.erase(mPendingFrames.begin()); 80550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 806f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik if ((mType != AVC && mType != HEVC) || mNALSizeLen == 0) { 8075ec58d925520e6913fba3fc54413881af751c610Andreas Huber if (targetSampleTimeUs >= 0ll) { 8083d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen frame->meta_data().setInt64( 8095ec58d925520e6913fba3fc54413881af751c610Andreas Huber kKeyTargetTime, targetSampleTimeUs); 8105ec58d925520e6913fba3fc54413881af751c610Andreas Huber } 8115ec58d925520e6913fba3fc54413881af751c610Andreas Huber 81250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = frame; 81350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 81450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber return OK; 81550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 81650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 817792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // Each input frame contains one or more NAL fragments, each fragment 818792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // is prefixed by mNALSizeLen bytes giving the fragment length, 819792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // followed by a corresponding number of bytes containing the fragment. 820792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // We output all these fragments into a single large buffer separated 821792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // by startcodes (0x00 0x00 0x00 0x01). 8224f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih // 8234f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih // When mNALSizeLen is 0, we assume the data is already in the format 8244f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih // desired. 825792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber 826792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber const uint8_t *srcPtr = 827792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber (const uint8_t *)frame->data() + frame->range_offset(); 828792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber 829792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber size_t srcSize = frame->range_length(); 830792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber 831792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber size_t dstSize = 0; 8321889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase *buffer = NULL; 833792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber uint8_t *dstPtr = NULL; 834792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber 835792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber for (int32_t pass = 0; pass < 2; ++pass) { 836792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber size_t srcOffset = 0; 837792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber size_t dstOffset = 0; 838792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber while (srcOffset + mNALSizeLen <= srcSize) { 839792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber size_t NALsize; 840792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber switch (mNALSizeLen) { 841792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber case 1: NALsize = srcPtr[srcOffset]; break; 842792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber case 2: NALsize = U16_AT(srcPtr + srcOffset); break; 843792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber case 3: NALsize = U24_AT(srcPtr + srcOffset); break; 844792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber case 4: NALsize = U32_AT(srcPtr + srcOffset); break; 845792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber default: 846792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber TRESPASS(); 847792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 84850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 8492dcf6138ebc9c5688aeae151d2fbde55a2826128Robert Shih if (srcOffset + mNALSizeLen + NALsize <= srcOffset + mNALSizeLen) { 8502dcf6138ebc9c5688aeae151d2fbde55a2826128Robert Shih frame->release(); 8512dcf6138ebc9c5688aeae151d2fbde55a2826128Robert Shih frame = NULL; 8522dcf6138ebc9c5688aeae151d2fbde55a2826128Robert Shih 8532dcf6138ebc9c5688aeae151d2fbde55a2826128Robert Shih return ERROR_MALFORMED; 8542dcf6138ebc9c5688aeae151d2fbde55a2826128Robert Shih } else if (srcOffset + mNALSizeLen + NALsize > srcSize) { 855792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber break; 856792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 85750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 858792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber if (pass == 1) { 859792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber memcpy(&dstPtr[dstOffset], "\x00\x00\x00\x01", 4); 86050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 861ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen if (frame != buffer) { 862ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen memcpy(&dstPtr[dstOffset + 4], 863ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen &srcPtr[srcOffset + mNALSizeLen], 864ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen NALsize); 865ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen } 866792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 86750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 868792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber dstOffset += 4; // 0x00 00 00 01 869792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber dstOffset += NALsize; 87050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 871792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber srcOffset += mNALSizeLen + NALsize; 872792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 87350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 874792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber if (srcOffset < srcSize) { 875792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // There were trailing bytes or not enough data to complete 876792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber // a fragment. 87750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 878792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber frame->release(); 879792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber frame = NULL; 88050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 881792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber return ERROR_MALFORMED; 882792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 88350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 884792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber if (pass == 0) { 885792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber dstSize = dstOffset; 88650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 887ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen if (dstSize == srcSize && mNALSizeLen == 4) { 888ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen // In this special case we can re-use the input buffer by substituting 889ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen // each 4-byte nal size with a 4-byte start code 890ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen buffer = frame; 891ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen } else { 8921889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang buffer = MediaBufferBase::Create(dstSize); 893ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen } 89450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 895792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber int64_t timeUs; 8963d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen CHECK(frame->meta_data().findInt64(kKeyTime, &timeUs)); 897792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber int32_t isSync; 8983d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen CHECK(frame->meta_data().findInt32(kKeyIsSyncFrame, &isSync)); 89950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 9003d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen buffer->meta_data().setInt64(kKeyTime, timeUs); 9013d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen buffer->meta_data().setInt32(kKeyIsSyncFrame, isSync); 90250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 903792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber dstPtr = (uint8_t *)buffer->data(); 904792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber } 90550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber } 90650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 907ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen if (frame != buffer) { 908ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen frame->release(); 909ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen frame = NULL; 910ba29bb20a18aa98813ce42f99cff4910a153e87cMarco Nelissen } 91150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber 9125ec58d925520e6913fba3fc54413881af751c610Andreas Huber if (targetSampleTimeUs >= 0ll) { 9133d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen buffer->meta_data().setInt64( 9145ec58d925520e6913fba3fc54413881af751c610Andreas Huber kKeyTargetTime, targetSampleTimeUs); 9155ec58d925520e6913fba3fc54413881af751c610Andreas Huber } 9165ec58d925520e6913fba3fc54413881af751c610Andreas Huber 91750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *out = buffer; 918093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 919093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return OK; 920093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 921093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 922093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 923093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 9242a243f08193fe9ff1afe018e9953f01c44ced9deMarco NelissenMatroskaExtractor::MatroskaExtractor(DataSourceBase *source) 925093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber : mDataSource(source), 9262a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen mReader(new DataSourceBaseReader(mDataSource)), 9275279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mSegment(NULL), 9288c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber mExtractedThumbnails(false), 929bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mIsWebm(false), 930bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mSeekPreRollNs(0) { 931d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber off64_t size; 932d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber mIsLiveStreaming = 933d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber (mDataSource->flags() 9342a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen & (DataSourceBase::kWantsPrefetching 9352a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen | DataSourceBase::kIsCachingDataSource)) 936d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber && mDataSource->getSize(&size) != OK; 937d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 938093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 939093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 940093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(mReader, pos) < 0) { 941093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 942093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 943093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 9448c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber if (ebmlHeader.m_docType && !strcmp("webm", ebmlHeader.m_docType)) { 9458c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber mIsWebm = true; 9468c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber } 9478c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber 948093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long ret = 949093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::Segment::CreateInstance(mReader, pos, mSegment); 950093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 951093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret) { 952093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(mSegment == NULL); 953093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 954093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 955093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 956c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar // from mkvparser::Segment::Load(), but stop at first cluster 95710f0fe7bcd60bdb0eceb905e84ac11555e8c1b9dJohann ret = mSegment->ParseHeaders(); 958c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar if (ret == 0) { 959c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar long len; 960c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar ret = mSegment->LoadCluster(pos, len); 961c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar if (ret >= 1) { 962c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar // no more clusters 963c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar ret = 0; 964c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar } 965c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar } else if (ret > 0) { 966c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar ret = mkvparser::E_BUFFER_NOT_FULL; 967c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar } 968093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 969093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ret < 0) { 970b486b52b2b67961073677d583a02269cbdc9a3fcDongwon Kang char uri[1024]; 971b486b52b2b67961073677d583a02269cbdc9a3fcDongwon Kang if(!mDataSource->getUri(uri, sizeof(uri))) { 972b486b52b2b67961073677d583a02269cbdc9a3fcDongwon Kang uri[0] = '\0'; 973b486b52b2b67961073677d583a02269cbdc9a3fcDongwon Kang } 974c51db0a6bfb71ea9c934fb7971cb5ae1f1cf03a0Lajos Molnar ALOGW("Corrupt %s source: %s", mIsWebm ? "webm" : "matroska", 975b486b52b2b67961073677d583a02269cbdc9a3fcDongwon Kang uriDebugString(uri).c_str()); 976093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 977093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 978093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return; 979093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 980093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 98174a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber#if 0 98274a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber const mkvparser::SegmentInfo *info = mSegment->GetInfo(); 983df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("muxing app: %s, writing app: %s", 98474a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber info->GetMuxingAppAsUTF8(), 98574a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber info->GetWritingAppAsUTF8()); 98674a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber#endif 98774a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber 988093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber addTracks(); 989093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 990093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 991093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::~MatroskaExtractor() { 992093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mSegment; 993093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mSegment = NULL; 994093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 995093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete mReader; 996093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mReader = NULL; 997093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 998093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 999093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersize_t MatroskaExtractor::countTracks() { 1000093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return mTracks.size(); 1001093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 1002093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 10033d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenMediaTrack *MatroskaExtractor::getTrack(size_t index) { 1004093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 1005093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return NULL; 1006093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 1007093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1008093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return new MatroskaSource(this, index); 1009093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 1010093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 10113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstatus_t MatroskaExtractor::getTrackMetaData( 10123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen MetaDataBase &meta, 1013093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t index, uint32_t flags) { 1014093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (index >= mTracks.size()) { 10153d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen return UNKNOWN_ERROR; 1016093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 1017093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1018d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails 1019d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber && !isLiveStreaming()) { 10205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber findThumbnails(); 10215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber mExtractedThumbnails = true; 10225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 10235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 10243d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta = mTracks.itemAt(index).mMeta; 10253d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen return OK; 1026093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 1027093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1028d42573cace9db2b5948e540c32beaef80f04153cAndreas Huberbool MatroskaExtractor::isLiveStreaming() const { 1029d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber return mIsLiveStreaming; 1030d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber} 1031d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 1032403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissenstatic int bytesForSize(size_t size) { 1033403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen // use at most 28 bits (4 times 7) 1034403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen CHECK(size <= 0xfffffff); 1035403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen 1036403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen if (size > 0x1fffff) { 1037403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen return 4; 1038403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen } else if (size > 0x3fff) { 1039403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen return 3; 1040403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen } else if (size > 0x7f) { 1041403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen return 2; 1042403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen } 1043403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen return 1; 1044403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen} 1045403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen 1046403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissenstatic void storeSize(uint8_t *data, size_t &idx, size_t size) { 1047403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen int numBytes = bytesForSize(size); 1048403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen idx += numBytes; 1049403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen 1050403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen data += idx; 1051403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen size_t next = 0; 1052403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen while (numBytes--) { 1053403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen *--data = (size & 0x7f) | next; 1054403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen size >>= 7; 1055403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen next = 0x80; 1056403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen } 1057403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen} 1058403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen 1059132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kangstatic void addESDSFromCodecPrivate( 10603d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen MetaDataBase &meta, 1061132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang bool isAudio, const void *priv, size_t privSize) { 1062093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1063403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen int privSizeBytesRequired = bytesForSize(privSize); 1064403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen int esdsSize2 = 14 + privSizeBytesRequired + privSize; 1065403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen int esdsSize2BytesRequired = bytesForSize(esdsSize2); 1066403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen int esdsSize1 = 4 + esdsSize2BytesRequired + esdsSize2; 1067403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen int esdsSize1BytesRequired = bytesForSize(esdsSize1); 1068403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen size_t esdsSize = 1 + esdsSize1BytesRequired + esdsSize1; 1069093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber uint8_t *esds = new uint8_t[esdsSize]; 1070403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen 1071403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen size_t idx = 0; 1072403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen esds[idx++] = 0x03; 1073403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen storeSize(esds, idx, esdsSize1); 1074403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen esds[idx++] = 0x00; // ES_ID 1075403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen esds[idx++] = 0x00; // ES_ID 1076403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen esds[idx++] = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 1077403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen esds[idx++] = 0x04; 1078403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen storeSize(esds, idx, esdsSize2); 1079403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen esds[idx++] = isAudio ? 0x40 // Audio ISO/IEC 14496-3 1080403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen : 0x20; // Visual ISO/IEC 14496-2 1081403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen for (int i = 0; i < 12; i++) { 1082403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen esds[idx++] = 0x00; 1083403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen } 1084403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen esds[idx++] = 0x05; 1085403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen storeSize(esds, idx, privSize); 1086403484d6d76ede31fc71c88495b69108a4df8319Marco Nelissen memcpy(esds + idx, priv, privSize); 108782ac8bf2da940c4439786c346f739f4a496864adAndreas Huber 10883d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData(kKeyESDS, 0, esds, esdsSize); 1089093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1090093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber delete[] esds; 1091093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber esds = NULL; 1092093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 1093093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 10945ce181568da90c78ba7fad3e084c8479041545dfAndreas Huberstatus_t addVorbisCodecInfo( 10953d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen MetaDataBase &meta, 1096093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const void *_codecPrivate, size_t codecPrivateSize) { 1097093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber // hexdump(_codecPrivate, codecPrivateSize); 1098093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 10995ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber if (codecPrivateSize < 1) { 11005ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber return ERROR_MALFORMED; 11015ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber } 1102093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1103093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate; 1104093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 11055ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber if (codecPrivate[0] != 0x02) { 11065ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber return ERROR_MALFORMED; 11075ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber } 1108093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 11095ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber // codecInfo starts with two lengths, len1 and len2, that are 11105ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber // "Xiph-style-lacing encoded"... 1111093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 11125ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber size_t offset = 1; 11135ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber size_t len1 = 0; 11145ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) { 11157d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen if (len1 > (SIZE_MAX - 0xff)) { 11167d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen return ERROR_MALFORMED; // would overflow 11177d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen } 11185ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber len1 += 0xff; 11195ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber ++offset; 11205ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber } 11215ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber if (offset >= codecPrivateSize) { 11225ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber return ERROR_MALFORMED; 11235ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber } 11247d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen if (len1 > (SIZE_MAX - codecPrivate[offset])) { 11257d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen return ERROR_MALFORMED; // would overflow 11267d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen } 11275ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber len1 += codecPrivate[offset++]; 1128093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 11295ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber size_t len2 = 0; 11305ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) { 11317d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen if (len2 > (SIZE_MAX - 0xff)) { 11327d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen return ERROR_MALFORMED; // would overflow 11337d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen } 11345ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber len2 += 0xff; 11355ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber ++offset; 11365ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber } 11375ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber if (offset >= codecPrivateSize) { 11385ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber return ERROR_MALFORMED; 11395ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber } 11407d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen if (len2 > (SIZE_MAX - codecPrivate[offset])) { 11417d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen return ERROR_MALFORMED; // would overflow 11427d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen } 11435ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber len2 += codecPrivate[offset++]; 11445ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber 11457d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen if (len1 > SIZE_MAX - len2 || offset > SIZE_MAX - (len1 + len2) || 11467d681539b821664d0417f8dd6beaed3352b34787Marco Nelissen codecPrivateSize < offset + len1 + len2) { 11475ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber return ERROR_MALFORMED; 11485ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber } 11495ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber 11505ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber if (codecPrivate[offset] != 0x01) { 11515ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber return ERROR_MALFORMED; 11525ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber } 11533d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData(kKeyVorbisInfo, 0, &codecPrivate[offset], len1); 11545ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber 11555ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber offset += len1; 11565ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber if (codecPrivate[offset] != 0x03) { 11575ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber return ERROR_MALFORMED; 11585ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber } 11595ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber 11605ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber offset += len2; 11615ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber if (codecPrivate[offset] != 0x05) { 11625ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber return ERROR_MALFORMED; 11635ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber } 1164093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 11653d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData( 11665ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber kKeyVorbisBooks, 0, &codecPrivate[offset], 11675ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber codecPrivateSize - offset); 11685ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber 11695ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber return OK; 1170093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 1171093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1172f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jiastatic status_t addFlacMetadata( 11733d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen MetaDataBase &meta, 1174f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia const void *codecPrivate, size_t codecPrivateSize) { 1175f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia // hexdump(codecPrivate, codecPrivateSize); 1176f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia 11773d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData(kKeyFlacMetadata, 0, codecPrivate, codecPrivateSize); 1178f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia 1179f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia int32_t maxInputSize = 64 << 10; 1180a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen FLACDecoder *flacDecoder = FLACDecoder::Create(); 1181f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia if (flacDecoder != NULL 1182f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia && flacDecoder->parseMetadata((const uint8_t*)codecPrivate, codecPrivateSize) == OK) { 1183f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia FLAC__StreamMetadata_StreamInfo streamInfo = flacDecoder->getStreamInfo(); 1184f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia maxInputSize = streamInfo.max_framesize; 1185f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia if (maxInputSize == 0) { 1186f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia // In case max framesize is not available, use raw data size as max framesize, 1187f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia // assuming there is no expansion. 1188f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia if (streamInfo.max_blocksize != 0 1189f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia && streamInfo.channels != 0 1190f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia && ((streamInfo.bits_per_sample + 7) / 8) > 1191f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia INT32_MAX / streamInfo.max_blocksize / streamInfo.channels) { 1192a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen delete flacDecoder; 1193f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia return ERROR_MALFORMED; 1194f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia } 1195f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia maxInputSize = ((streamInfo.bits_per_sample + 7) / 8) 1196f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia * streamInfo.max_blocksize * streamInfo.channels; 1197f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia } 1198f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia } 11993d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeyMaxInputSize, maxInputSize); 1200f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia 1201a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen delete flacDecoder; 1202f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia return OK; 1203f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia} 1204f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia 12054f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shihstatus_t MatroskaExtractor::synthesizeAVCC(TrackInfo *trackInfo, size_t index) { 12064f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih BlockIterator iter(this, trackInfo->mTrackNum, index); 12074f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih if (iter.eos()) { 12084f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih return ERROR_MALFORMED; 12094f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih } 12104f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih 12114f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih const mkvparser::Block *block = iter.block(); 12124f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih if (block->GetFrameCount() <= 0) { 12134f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih return ERROR_MALFORMED; 12144f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih } 12154f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih 12164f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih const mkvparser::Block::Frame &frame = block->GetFrame(0); 1217a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen auto tmpData = heapbuffer<unsigned char>(frame.len); 1218a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen long n = frame.Read(mReader, tmpData.get()); 12194f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih if (n != 0) { 12204f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih return ERROR_MALFORMED; 12214f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih } 12224f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih 1223a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen if (!MakeAVCCodecSpecificData(trackInfo->mMeta, tmpData.get(), frame.len)) { 12244f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih return ERROR_MALFORMED; 12254f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih } 12264f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih 12274f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih // Override the synthesized nal length size, which is arbitrary 12283d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen trackInfo->mMeta.setInt32(kKeyNalLengthSize, 0); 12294f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih return OK; 12304f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih} 12314f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih 1232d637d296bb0954756d3d231633fad73fadd70316Lajos Molnarstatic inline bool isValidInt32ColourValue(long long value) { 1233d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar return value != mkvparser::Colour::kValueNotPresent 1234d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar && value >= INT32_MIN 1235d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar && value <= INT32_MAX; 1236d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar} 1237d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar 1238d637d296bb0954756d3d231633fad73fadd70316Lajos Molnarstatic inline bool isValidUint16ColourValue(long long value) { 1239d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar return value != mkvparser::Colour::kValueNotPresent 1240d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar && value >= 0 1241d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar && value <= UINT16_MAX; 1242d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar} 1243d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar 1244d637d296bb0954756d3d231633fad73fadd70316Lajos Molnarstatic inline bool isValidPrimary(const mkvparser::PrimaryChromaticity *primary) { 1245d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar return primary != NULL && primary->x >= 0 && primary->x <= 1 1246d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar && primary->y >= 0 && primary->y <= 1; 1247d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar} 1248d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar 1249d637d296bb0954756d3d231633fad73fadd70316Lajos Molnarvoid MatroskaExtractor::getColorInformation( 12503d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen const mkvparser::VideoTrack *vtrack, MetaDataBase &meta) { 1251d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar const mkvparser::Colour *color = vtrack->GetColour(); 1252d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (color == NULL) { 1253d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar return; 1254d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1255d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar 1256d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar // Color Aspects 1257d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar { 1258d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar int32_t primaries = 2; // ISO unspecified 1259d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar int32_t transfer = 2; // ISO unspecified 1260d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar int32_t coeffs = 2; // ISO unspecified 1261d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar bool fullRange = false; // default 1262d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar bool rangeSpecified = false; 1263d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar 1264d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (isValidInt32ColourValue(color->primaries)) { 1265d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar primaries = color->primaries; 1266d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1267d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (isValidInt32ColourValue(color->transfer_characteristics)) { 1268d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar transfer = color->transfer_characteristics; 1269d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1270d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (isValidInt32ColourValue(color->matrix_coefficients)) { 1271d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar coeffs = color->matrix_coefficients; 1272d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1273d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (color->range != mkvparser::Colour::kValueNotPresent 1274d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar && color->range != 0 /* MKV unspecified */) { 1275d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar // We only support MKV broadcast range (== limited) and full range. 1276d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar // We treat all other value as the default limited range. 1277d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar fullRange = color->range == 2 /* MKV fullRange */; 1278d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar rangeSpecified = true; 1279d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1280d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar 1281d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar ColorAspects aspects; 1282d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar ColorUtils::convertIsoColorAspectsToCodecAspects( 1283d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar primaries, transfer, coeffs, fullRange, aspects); 12843d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeyColorPrimaries, aspects.mPrimaries); 12853d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeyTransferFunction, aspects.mTransfer); 12863d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); 12873d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32( 1288d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar kKeyColorRange, rangeSpecified ? aspects.mRange : ColorAspects::RangeUnspecified); 1289d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1290d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar 1291d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar // HDR Static Info 1292d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar { 1293d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar HDRStaticInfo info, nullInfo; // nullInfo is a fully unspecified static info 1294d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar memset(&info, 0, sizeof(info)); 1295d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar memset(&nullInfo, 0, sizeof(nullInfo)); 1296d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (isValidUint16ColourValue(color->max_cll)) { 1297d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mMaxContentLightLevel = color->max_cll; 1298d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1299d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (isValidUint16ColourValue(color->max_fall)) { 1300d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mMaxFrameAverageLightLevel = color->max_fall; 1301d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1302d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar const mkvparser::MasteringMetadata *mastering = color->mastering_metadata; 1303d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (mastering != NULL) { 1304d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar // Convert matroska values to HDRStaticInfo equivalent values for each fully specified 1305d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar // group. See CTA-681.3 section 3.2.1 for more info. 1306d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (mastering->luminance_max >= 0.5 && mastering->luminance_max < 65535.5) { 1307d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mMaxDisplayLuminance = (uint16_t)(mastering->luminance_max + 0.5); 1308d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1309d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (mastering->luminance_min >= 0.00005 && mastering->luminance_min < 6.55355) { 131012c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar // HDRStaticInfo Type1 stores min luminance scaled 10000:1 1311d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mMinDisplayLuminance = 1312d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar (uint16_t)(10000 * mastering->luminance_min + 0.5); 1313d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 131412c703291529dd19bb83579f1e3b33ecb444340dLajos Molnar // HDRStaticInfo Type1 stores primaries scaled 50000:1 1315d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (isValidPrimary(mastering->white_point)) { 1316d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mW.x = (uint16_t)(50000 * mastering->white_point->x + 0.5); 1317d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mW.y = (uint16_t)(50000 * mastering->white_point->y + 0.5); 1318d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1319d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (isValidPrimary(mastering->r) && isValidPrimary(mastering->g) 1320d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar && isValidPrimary(mastering->b)) { 1321d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mR.x = (uint16_t)(50000 * mastering->r->x + 0.5); 1322d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mR.y = (uint16_t)(50000 * mastering->r->y + 0.5); 1323d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mG.x = (uint16_t)(50000 * mastering->g->x + 0.5); 1324d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mG.y = (uint16_t)(50000 * mastering->g->y + 0.5); 1325d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mB.x = (uint16_t)(50000 * mastering->b->x + 0.5); 1326d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.sType1.mB.y = (uint16_t)(50000 * mastering->b->y + 0.5); 1327d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1328d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1329d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar // Only advertise static info if at least one of the groups have been specified. 1330d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar if (memcmp(&info, &nullInfo, sizeof(info)) != 0) { 1331d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar info.mID = HDRStaticInfo::kType1; 13323d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info)); 1333d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1334d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar } 1335d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar} 1336d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar 1337580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shihstatus_t MatroskaExtractor::initTrackInfo( 13383d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen const mkvparser::Track *track, MetaDataBase &meta, TrackInfo *trackInfo) { 1339580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih trackInfo->mTrackNum = track->GetNumber(); 1340580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih trackInfo->mMeta = meta; 1341580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih trackInfo->mExtractor = this; 1342580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih trackInfo->mEncrypted = false; 1343580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih trackInfo->mHeader = NULL; 1344580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih trackInfo->mHeaderLen = 0; 1345580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih 1346580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih for(size_t i = 0; i < track->GetContentEncodingCount(); i++) { 1347580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih const mkvparser::ContentEncoding *encoding = track->GetContentEncodingByIndex(i); 1348580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih for(size_t j = 0; j < encoding->GetEncryptionCount(); j++) { 1349580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih const mkvparser::ContentEncoding::ContentEncryption *encryption; 1350580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih encryption = encoding->GetEncryptionByIndex(j); 13513d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen trackInfo->mMeta.setData(kKeyCryptoKey, 0, encryption->key_id, encryption->key_id_len); 1352580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih trackInfo->mEncrypted = true; 1353580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih break; 1354580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih } 1355580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih 1356580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih for(size_t j = 0; j < encoding->GetCompressionCount(); j++) { 1357580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih const mkvparser::ContentEncoding::ContentCompression *compression; 1358580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih compression = encoding->GetCompressionByIndex(j); 1359580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih ALOGV("compression algo %llu settings_len %lld", 1360580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih compression->algo, compression->settings_len); 1361580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih if (compression->algo == 3 1362580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih && compression->settings 1363580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih && compression->settings_len > 0) { 1364580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih trackInfo->mHeader = compression->settings; 1365580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih trackInfo->mHeaderLen = compression->settings_len; 1366580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih } 1367580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih } 1368580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih } 1369580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih 1370580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih return OK; 1371580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih} 1372580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih 1373093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid MatroskaExtractor::addTracks() { 1374093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Tracks *tracks = mSegment->GetTracks(); 1375093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1376093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber for (size_t index = 0; index < tracks->GetTracksCount(); ++index) { 1377093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::Track *track = tracks->GetTrackByIndex(index); 1378093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 137930ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber if (track == NULL) { 138030ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber // Apparently this is currently valid (if unexpected) behaviour 138130ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber // of the mkv parser lib. 138230ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber continue; 138330ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber } 138430ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber 1385093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const char *const codecID = track->GetCodecId(); 13863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("codec id = %s", codecID); 13873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("codec name = %s", track->GetCodecNameAsUTF8()); 1388093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 13891e2a0e6adc3d70879b00e5295c54a74209b71e1bRobert Shih if (codecID == NULL) { 13901e2a0e6adc3d70879b00e5295c54a74209b71e1bRobert Shih ALOGW("unknown codecID is not supported."); 13911e2a0e6adc3d70879b00e5295c54a74209b71e1bRobert Shih continue; 13921e2a0e6adc3d70879b00e5295c54a74209b71e1bRobert Shih } 13931e2a0e6adc3d70879b00e5295c54a74209b71e1bRobert Shih 1394093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber size_t codecPrivateSize; 1395093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const unsigned char *codecPrivate = 1396ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber track->GetCodecPrivate(codecPrivateSize); 1397093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1398093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 }; 1399093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 14003d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen MetaDataBase meta; 1401093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 14025ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber status_t err = OK; 14035ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber 1404093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber switch (track->GetType()) { 1405093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case VIDEO_TRACK: 1406093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 1407093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::VideoTrack *vtrack = 1408093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::VideoTrack *>(track); 1409093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 14101e2a0e6adc3d70879b00e5295c54a74209b71e1bRobert Shih if (!strcmp("V_MPEG4/ISO/AVC", codecID)) { 14113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 14123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize); 1413f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik } else if (!strcmp("V_MPEGH/ISO/HEVC", codecID)) { 14143d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_HEVC); 1415f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik if (codecPrivateSize > 0) { 14163d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData(kKeyHVCC, kTypeHVCC, codecPrivate, codecPrivateSize); 1417f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik } else { 1418f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik ALOGW("HEVC is detected, but does not have configuration."); 1419f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik continue; 1420f69544accbbe7cade5d9a63f632fdb460ade3e19Patrik } 1421132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) { 1422132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang if (codecPrivateSize > 0) { 14233d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString( 1424132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 1425132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang addESDSFromCodecPrivate( 1426132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang meta, false, codecPrivate, codecPrivateSize); 1427132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang } else { 1428132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang ALOGW("%s is detected, but does not have configuration.", 1429132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang codecID); 1430132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang continue; 1431132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang } 1432093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("V_VP8", codecID)) { 14333d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8); 143494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang } else if (!strcmp("V_VP9", codecID)) { 14353d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP9); 1436d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian if (codecPrivateSize > 0) { 1437d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian // 'csd-0' for VP9 is the Blob of Codec Private data as 1438d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian // specified in http://www.webmproject.org/vp9/profiles/. 14393d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData( 1440d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian kKeyVp9CodecPrivate, 0, codecPrivate, 1441d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian codecPrivateSize); 1442d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian } 1443093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 1444132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang ALOGW("%s is not supported.", codecID); 1445093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 1446093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 1447093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1448917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung const long long width = vtrack->GetWidth(); 1449917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung const long long height = vtrack->GetHeight(); 1450917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung if (width <= 0 || width > INT32_MAX) { 1451917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung ALOGW("track width exceeds int32_t, %lld", width); 1452917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung continue; 1453917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung } 1454917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung if (height <= 0 || height > INT32_MAX) { 1455917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung ALOGW("track height exceeds int32_t, %lld", height); 1456917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung continue; 1457917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung } 14583d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeyWidth, (int32_t)width); 14593d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeyHeight, (int32_t)height); 1460917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung 1461917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung // setting display width/height is optional 1462917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung const long long displayUnit = vtrack->GetDisplayUnit(); 1463917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung const long long displayWidth = vtrack->GetDisplayWidth(); 1464917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung const long long displayHeight = vtrack->GetDisplayHeight(); 1465917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung if (displayWidth > 0 && displayWidth <= INT32_MAX 1466917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung && displayHeight > 0 && displayHeight <= INT32_MAX) { 1467917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung switch (displayUnit) { 1468917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung case 0: // pixels 14693d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeyDisplayWidth, (int32_t)displayWidth); 14703d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeyDisplayHeight, (int32_t)displayHeight); 1471917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung break; 1472917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung case 1: // centimeters 1473917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung case 2: // inches 1474917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung case 3: // aspect ratio 1475917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung { 1476917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung // Physical layout size is treated the same as aspect ratio. 1477917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung // Note: displayWidth and displayHeight are never zero as they are 1478917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung // checked in the if above. 1479917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung const long long computedWidth = 1480917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung std::max(width, height * displayWidth / displayHeight); 1481917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung const long long computedHeight = 1482917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung std::max(height, width * displayHeight / displayWidth); 1483917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung if (computedWidth <= INT32_MAX && computedHeight <= INT32_MAX) { 14843d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeyDisplayWidth, (int32_t)computedWidth); 14853d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeyDisplayHeight, (int32_t)computedHeight); 1486917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung } 1487917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung break; 1488917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung } 1489917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung default: // unknown display units, perhaps future version of spec. 1490917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung break; 1491917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung } 1492917da0898ee9b501b656d90f11c5eecc3d78b5c7Andy Hung } 1493d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar 1494d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar getColorInformation(vtrack, meta); 1495d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar 1496093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 1497093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 1498093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1499093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber case AUDIO_TRACK: 1500093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber { 1501093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber const mkvparser::AudioTrack *atrack = 1502093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber static_cast<const mkvparser::AudioTrack *>(track); 1503093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1504093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (!strcmp("A_AAC", codecID)) { 15053d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 1506093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber CHECK(codecPrivateSize >= 2); 1507093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1508132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang addESDSFromCodecPrivate( 1509132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang meta, true, codecPrivate, codecPrivateSize); 1510093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else if (!strcmp("A_VORBIS", codecID)) { 15113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS); 1512093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 15135ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber err = addVorbisCodecInfo( 15145ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber meta, codecPrivate, codecPrivateSize); 1515bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } else if (!strcmp("A_OPUS", codecID)) { 15163d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_OPUS); 15173d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setData(kKeyOpusHeader, 0, codecPrivate, codecPrivateSize); 15183d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt64(kKeyOpusCodecDelay, track->GetCodecDelay()); 15193d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt64(kKeyOpusSeekPreRoll, track->GetSeekPreRoll()); 1520bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mSeekPreRollNs = track->GetSeekPreRoll(); 1521132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang } else if (!strcmp("A_MPEG/L3", codecID)) { 15223d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 1523f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia } else if (!strcmp("A_FLAC", codecID)) { 15243d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC); 1525f2ddc43bf03b7a26d408e1b349b6b0c74dd6c0a3Wei Jia err = addFlacMetadata(meta, codecPrivate, codecPrivateSize); 1526093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } else { 1527132e88ee86e4f11d1b649c336cd2d6eb5980c3fcDongwon Kang ALOGW("%s is not supported.", codecID); 1528093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 1529093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 1530093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 15313d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeySampleRate, atrack->GetSamplingRate()); 15323d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt32(kKeyChannelCount, atrack->GetChannels()); 1533093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber break; 1534093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 1535093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1536093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber default: 1537093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber continue; 1538093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 1539093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 15400c411418d01d477b60f087f7bc685cf176ae197cPatrik const char *language = track->GetLanguage(); 15410c411418d01d477b60f087f7bc685cf176ae197cPatrik if (language != NULL) { 15420c411418d01d477b60f087f7bc685cf176ae197cPatrik char lang[4]; 15430c411418d01d477b60f087f7bc685cf176ae197cPatrik strncpy(lang, language, 3); 15440c411418d01d477b60f087f7bc685cf176ae197cPatrik lang[3] = '\0'; 15453d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString(kKeyMediaLanguage, lang); 15460c411418d01d477b60f087f7bc685cf176ae197cPatrik } 15470c411418d01d477b60f087f7bc685cf176ae197cPatrik 15485ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber if (err != OK) { 15495ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber ALOGE("skipping track, codec specific data was malformed."); 15505ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber continue; 15515ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber } 15525ce181568da90c78ba7fad3e084c8479041545dfAndreas Huber 1553093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long durationNs = mSegment->GetDuration(); 15543d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setInt64(kKeyDuration, (durationNs + 500) / 1000); 1555093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1556093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mTracks.push(); 15574f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih size_t n = mTracks.size() - 1; 15584f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih TrackInfo *trackInfo = &mTracks.editItemAt(n); 1559580baf5c24f47e95eb3aeef94c51a920f1f426b1Robert Shih initTrackInfo(track, meta, trackInfo); 15604f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih 15614f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih if (!strcmp("V_MPEG4/ISO/AVC", codecID) && codecPrivateSize == 0) { 15624f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih // Attempt to recover from AVC track without codec private data 15634f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih err = synthesizeAVCC(trackInfo, n); 15644f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih if (err != OK) { 15654f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih mTracks.pop(); 15664f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih } 15674f2559d3cdeb7187dedca186d5abc65af4bdb031Robert Shih } 1568093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 1569093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 1570093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 15715279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid MatroskaExtractor::findThumbnails() { 15725279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 15735279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber TrackInfo *info = &mTracks.editItemAt(i); 15745279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 15755279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber const char *mime; 15763d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen CHECK(info->mMeta.findCString(kKeyMIMEType, &mime)); 15775279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 15785279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (strncasecmp(mime, "video/", 6)) { 15795279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber continue; 15805279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 15815279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 15822f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih BlockIterator iter(this, info->mTrackNum, i); 15834719fa8ae1259d6a94ba5b5ecdaa01e69f553996Bernhard Rosenkraenzer int32_t j = 0; 15845279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber int64_t thumbnailTimeUs = 0; 15855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber size_t maxBlockSize = 0; 15864719fa8ae1259d6a94ba5b5ecdaa01e69f553996Bernhard Rosenkraenzer while (!iter.eos() && j < 20) { 15875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (iter.block()->IsKey()) { 15884719fa8ae1259d6a94ba5b5ecdaa01e69f553996Bernhard Rosenkraenzer ++j; 15895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 1590d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber size_t blockSize = 0; 1591cba4ed0039c8b8fac01b3193d19fc2364f934506Tareq A. Siraj for (int k = 0; k < iter.block()->GetFrameCount(); ++k) { 1592cba4ed0039c8b8fac01b3193d19fc2364f934506Tareq A. Siraj blockSize += iter.block()->GetFrame(k).len; 1593d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } 1594d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 15955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber if (blockSize > maxBlockSize) { 15965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber maxBlockSize = blockSize; 15975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber thumbnailTimeUs = iter.blockTimeUs(); 15985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 15995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 16005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber iter.advance(); 16015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 16023d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen info->mMeta.setInt64(kKeyThumbnailTime, thumbnailTimeUs); 16035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber } 16045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber} 16055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber 16063d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstatus_t MatroskaExtractor::getMetaData(MetaDataBase &meta) { 16073d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString( 16088c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber kKeyMIMEType, 16098c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA); 1610093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 16113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen return OK; 1612093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 1613093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1614d42573cace9db2b5948e540c32beaef80f04153cAndreas Huberuint32_t MatroskaExtractor::flags() const { 1615d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber uint32_t x = CAN_PAUSE; 1616d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber if (!isLiveStreaming()) { 1617d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK; 1618d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber } 1619d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 1620d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber return x; 1621d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber} 1622d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber 1623093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberbool SniffMatroska( 162417e172b4c3c87ecaa7c87eecc42b4dc47e3e9734Dongwon Kang DataSourceBase *source, float *confidence) { 16252a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen DataSourceBaseReader reader(source); 1626093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber mkvparser::EBMLHeader ebmlHeader; 1627093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber long long pos; 1628093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber if (ebmlHeader.Parse(&reader, pos) < 0) { 1629093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return false; 1630093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber } 1631093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1632093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *confidence = 0.6; 1633093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 1634093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber return true; 1635093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} 1636093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber 163775226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen 163875226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissenextern "C" { 163975226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen// This is the only symbol that needs to be exported 164075226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen__attribute__ ((visibility ("default"))) 164175226177f20a176d50e3e53bbb34067cb49112c3Marco NelissenMediaExtractor::ExtractorDef GETEXTRACTORDEF() { 164275226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen return { 164375226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen MediaExtractor::EXTRACTORDEF_VERSION, 164475226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen UUID("abbedd92-38c4-4904-a4c1-b3f45f899980"), 164575226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen 1, 164675226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen "Matroska Extractor", 164775226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen []( 16482a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen DataSourceBase *source, 164975226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen float *confidence, 165017e172b4c3c87ecaa7c87eecc42b4dc47e3e9734Dongwon Kang void **, 165117e172b4c3c87ecaa7c87eecc42b4dc47e3e9734Dongwon Kang MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc { 165217e172b4c3c87ecaa7c87eecc42b4dc47e3e9734Dongwon Kang if (SniffMatroska(source, confidence)) { 165375226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen return []( 16542a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen DataSourceBase *source, 165517e172b4c3c87ecaa7c87eecc42b4dc47e3e9734Dongwon Kang void *) -> MediaExtractor* { 165675226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen return new MatroskaExtractor(source);}; 165775226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen } 165875226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen return NULL; 165975226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen } 166075226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen }; 166175226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen} 166275226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen 166375226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen} // extern "C" 166475226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen 1665093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber} // namespace android 1666