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