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