MatroskaExtractor.cpp revision 2ba7ce928b0fa8917ee202836b0963ca58613453
1093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber/*
2093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Copyright (C) 2010 The Android Open Source Project
3093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *
4093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * you may not use this file except in compliance with the License.
6093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * You may obtain a copy of the License at
7093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *
8093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber *
10093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * Unless required by applicable law or agreed to in writing, software
11093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * See the License for the specific language governing permissions and
14093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * limitations under the License.
15093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber */
16093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
17093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber//#define LOG_NDEBUG 0
18093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#define LOG_TAG "MatroskaExtractor"
19093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <utils/Log.h>
20093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
21093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "MatroskaExtractor.h"
22093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
23093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "mkvparser.hpp"
24093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
25b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include <media/stagefright/foundation/ADebug.h>
26b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include <media/stagefright/foundation/hexdump.h>
27093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/DataSource.h>
28093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaBuffer.h>
29093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaDefs.h>
30093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaErrors.h>
31093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MediaSource.h>
32093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <media/stagefright/MetaData.h>
33b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber#include <media/stagefright/Utils.h>
34093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include <utils/String8.h>
35093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
36093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubernamespace android {
37093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
38093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstruct DataSourceReader : public mkvparser::IMkvReader {
39093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    DataSourceReader(const sp<DataSource> &source)
40093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        : mSource(source) {
41093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
42093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
43093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    virtual int Read(long long position, long length, unsigned char* buffer) {
44093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        CHECK(position >= 0);
45093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        CHECK(length >= 0);
46093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
47093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        if (length == 0) {
48093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            return 0;
49093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
50093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
51093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        ssize_t n = mSource->readAt(position, buffer, length);
52093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
53093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        if (n <= 0) {
54093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            return -1;
55093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
56093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
57093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return 0;
58093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
59093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
60093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    virtual int Length(long long* total, long long* available) {
61c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t size;
62093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        if (mSource->getSize(&size) != OK) {
63d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            *total = -1;
64d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            *available = (long long)((1ull << 63) - 1);
65d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
66d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            return 0;
67093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
68093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
69093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        if (total) {
70093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            *total = size;
71093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
72093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
73093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        if (available) {
74093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            *available = size;
75093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
76093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
77093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return 0;
78093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
79093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
80093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate:
81093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    sp<DataSource> mSource;
82093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
83093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    DataSourceReader(const DataSourceReader &);
84093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    DataSourceReader &operator=(const DataSourceReader &);
85093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber};
86093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
87093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber////////////////////////////////////////////////////////////////////////////////
88093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberstruct BlockIterator {
90d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    BlockIterator(MatroskaExtractor *extractor, unsigned long trackNum);
915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    bool eos() const;
935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    void advance();
955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    void reset();
965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    void seek(int64_t seekTimeUs);
975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    const mkvparser::Block *block() const;
995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    int64_t blockTimeUs() const;
1005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
1015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberprivate:
102d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    MatroskaExtractor *mExtractor;
1035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    unsigned long mTrackNum;
1045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
105d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    const mkvparser::Cluster *mCluster;
1065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    const mkvparser::BlockEntry *mBlockEntry;
107d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    long mBlockEntryIndex;
108d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
109d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    void advance_l();
1105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
1115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    BlockIterator(const BlockIterator &);
1125279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    BlockIterator &operator=(const BlockIterator &);
1135279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber};
1145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
115093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstruct MatroskaSource : public MediaSource {
116093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    MatroskaSource(
117093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            const sp<MatroskaExtractor> &extractor, size_t index);
118093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
119093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    virtual status_t start(MetaData *params);
120093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    virtual status_t stop();
121093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
122093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    virtual sp<MetaData> getFormat();
123093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
124093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    virtual status_t read(
125093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            MediaBuffer **buffer, const ReadOptions *options);
126093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
12750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberprotected:
12850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    virtual ~MatroskaSource();
12950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
130093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate:
131093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    enum Type {
132093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        AVC,
133093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        AAC,
134093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        OTHER
135093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    };
136093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
137093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    sp<MatroskaExtractor> mExtractor;
138093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t mTrackIndex;
139093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    Type mType;
1405279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    BlockIterator mBlockIter;
141b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    size_t mNALSizeLen;  // for type AVC
142093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
14350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    List<MediaBuffer *> mPendingFrames;
14450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
145093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    status_t advance();
146093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
14750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    status_t readBlock();
14850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    void clearPendingFrames();
14950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
150093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    MatroskaSource(const MatroskaSource &);
151093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    MatroskaSource &operator=(const MatroskaSource &);
152093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber};
153093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
154093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaSource::MatroskaSource(
155093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MatroskaExtractor> &extractor, size_t index)
156093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    : mExtractor(extractor),
157093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mTrackIndex(index),
158093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mType(OTHER),
159d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber      mBlockIter(mExtractor.get(),
160b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                 mExtractor->mTracks.itemAt(index).mTrackNum),
161b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber      mNALSizeLen(0) {
162b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta;
163b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
164093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const char *mime;
165b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
166093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
167093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
168093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mType = AVC;
169b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
170b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        uint32_t dummy;
171b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        const uint8_t *avcc;
172b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        size_t avccSize;
173b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        CHECK(meta->findData(
174b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                    kKeyAVCC, &dummy, (const void **)&avcc, &avccSize));
175b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
176b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        CHECK_GE(avccSize, 5u);
177b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
178b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        mNALSizeLen = 1 + (avcc[4] & 3);
179b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        LOGV("mNALSizeLen = %d", mNALSizeLen);
180093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
181093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mType = AAC;
182093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
183093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
184093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
18550c8bea8fba2fcafb14696399028bdbc094dc995Andreas HuberMatroskaSource::~MatroskaSource() {
18650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    clearPendingFrames();
18750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
18850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
189093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::start(MetaData *params) {
1905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mBlockIter.reset();
191093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
192093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
193093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
194093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
195093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::stop() {
19650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    clearPendingFrames();
19750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
198093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
199093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
200093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
201093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaSource::getFormat() {
202093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mExtractor->mTracks.itemAt(mTrackIndex).mMeta;
203093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
204093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
2055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber////////////////////////////////////////////////////////////////////////////////
2065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas HuberBlockIterator::BlockIterator(
208d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        MatroskaExtractor *extractor, unsigned long trackNum)
209d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    : mExtractor(extractor),
2105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mTrackNum(trackNum),
2115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mCluster(NULL),
212d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber      mBlockEntry(NULL),
213d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber      mBlockEntryIndex(0) {
2145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    reset();
2155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberbool BlockIterator::eos() const {
2185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return mCluster == NULL || mCluster->EOS();
2195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::advance() {
222d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    Mutex::Autolock autoLock(mExtractor->mLock);
223d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    advance_l();
224d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber}
225d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
226d42573cace9db2b5948e540c32beaef80f04153cAndreas Hubervoid BlockIterator::advance_l() {
227d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    for (;;) {
228d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry);
229d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        LOGV("GetEntry returned %ld", res);
230d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
231d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        long long pos;
232d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        long len;
233d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        if (res < 0) {
234d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            // Need to parse this cluster some more
235d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
236d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL);
237d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
238d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            res = mCluster->Parse(pos, len);
239d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            LOGV("Parse returned %ld", res);
240d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
241d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            if (res < 0) {
242d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                // I/O error
243d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
244d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                LOGE("Cluster::Parse returned result %ld", res);
2455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
246d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                mCluster = NULL;
2475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                break;
248093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
2495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
250d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            continue;
251d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        } else if (res == 0) {
252d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            // We're done with this cluster
253d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
254d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            const mkvparser::Cluster *nextCluster;
255d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            res = mExtractor->mSegment->ParseNext(
256d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                    mCluster, nextCluster, pos, len);
257d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            LOGV("ParseNext returned %ld", res);
258d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
259d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            if (res > 0) {
260d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                // EOF
261d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
262d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                mCluster = NULL;
263d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                break;
264d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            }
265d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
266d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            CHECK_EQ(res, 0);
267d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            CHECK(nextCluster != NULL);
268d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            CHECK(!nextCluster->EOS());
269d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
270d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            mCluster = nextCluster;
271d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
272d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            res = mCluster->Parse(pos, len);
273d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            LOGV("Parse (2) returned %ld", res);
274d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            CHECK_GE(res, 0);
275d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
276d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            mBlockEntryIndex = 0;
277d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            continue;
278093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
279093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
280d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CHECK(mBlockEntry != NULL);
281d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CHECK(mBlockEntry->GetBlock() != NULL);
282d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        ++mBlockEntryIndex;
283d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
284d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) {
2855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            break;
286093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
2875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
2885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::reset() {
291d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    Mutex::Autolock autoLock(mExtractor->mLock);
292093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
293d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mCluster = mExtractor->mSegment->GetFirst();
2942ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber    mBlockEntry = NULL;
295d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mBlockEntryIndex = 0;
296d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
297d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    do {
298d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        advance_l();
299d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    } while (!eos() && block()->GetTrackNumber() != mTrackNum);
3005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
301093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
3025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::seek(int64_t seekTimeUs) {
303d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    Mutex::Autolock autoLock(mExtractor->mLock);
304d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
305d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll);
3062ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber    mBlockEntry = NULL;
307d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mBlockEntryIndex = 0;
3085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
3092ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber    do {
310d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        advance_l();
3115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
3122ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber    while (!eos() && block()->GetTrackNumber() != mTrackNum);
3135279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
3145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    while (!eos() && !mBlockEntry->GetBlock()->IsKey()) {
315d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        advance_l();
3165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
317093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
318093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
3195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberconst mkvparser::Block *BlockIterator::block() const {
3205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    CHECK(!eos());
3215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
3225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return mBlockEntry->GetBlock();
3235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
3245279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
3255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberint64_t BlockIterator::blockTimeUs() const {
3265279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll;
3275279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
3285279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
3295279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber////////////////////////////////////////////////////////////////////////////////
3305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
331b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huberstatic unsigned U24_AT(const uint8_t *ptr) {
332b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
333b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber}
334b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
33550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatic size_t clz(uint8_t x) {
33650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    size_t numLeadingZeroes = 0;
337093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
33850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    while (!(x & 0x80)) {
33950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        ++numLeadingZeroes;
34050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        x = x << 1;
341093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
342093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
34350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    return numLeadingZeroes;
34450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
34550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
34650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Hubervoid MatroskaSource::clearPendingFrames() {
34750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    while (!mPendingFrames.empty()) {
34850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        MediaBuffer *frame = *mPendingFrames.begin();
34950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mPendingFrames.erase(mPendingFrames.begin());
35050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
35150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        frame->release();
35250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        frame = NULL;
35350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
35450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
35550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
35650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::readBlock() {
35750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    CHECK(mPendingFrames.empty());
35850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
3595279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    if (mBlockIter.eos()) {
360093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return ERROR_END_OF_STREAM;
361093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
362093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
3635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    const mkvparser::Block *block = mBlockIter.block();
36450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
3655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    int64_t timeUs = mBlockIter.blockTimeUs();
366093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
367d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    for (int i = 0; i < block->GetFrameCount(); ++i) {
368d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        const mkvparser::Block::Frame &frame = block->GetFrame(i);
369b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
370d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        MediaBuffer *mbuf = new MediaBuffer(frame.len);
371d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        mbuf->meta_data()->setInt64(kKeyTime, timeUs);
372d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        mbuf->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey());
373093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
374d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        long n = frame.Read(mExtractor->mReader, (unsigned char *)mbuf->data());
375d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        if (n != 0) {
376d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            mPendingFrames.clear();
37750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
378d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            mBlockIter.advance();
379d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            return ERROR_IO;
38050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        }
38150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
38250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mPendingFrames.push_back(mbuf);
38350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
38450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
385d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mBlockIter.advance();
38650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
38750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    return OK;
38850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
38950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
39050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::read(
39150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
39250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    *out = NULL;
39350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
39450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    int64_t seekTimeUs;
39550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    ReadOptions::SeekMode mode;
396d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    if (options && options->getSeekTo(&seekTimeUs, &mode)
397d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            && !mExtractor->isLiveStreaming()) {
39850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        clearPendingFrames();
39950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mBlockIter.seek(seekTimeUs);
40050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
40150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
40250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberagain:
40350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    while (mPendingFrames.empty()) {
40450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        status_t err = readBlock();
40550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
40650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        if (err != OK) {
40750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            clearPendingFrames();
40850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
40950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            return err;
41050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        }
41150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
41250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
41350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    MediaBuffer *frame = *mPendingFrames.begin();
41450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    mPendingFrames.erase(mPendingFrames.begin());
41550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
41650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    size_t size = frame->range_length();
41750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
41850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (mType != AVC) {
41950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        *out = frame;
42050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
42150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        return OK;
42250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
42350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
42450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (size < mNALSizeLen) {
42550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        frame->release();
42650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        frame = NULL;
42750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
42850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        return ERROR_MALFORMED;
42950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
43050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
43150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // In the case of AVC content, each NAL unit is prefixed by
43250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // mNALSizeLen bytes of length. We want to prefix the data with
43350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // a four-byte 0x00000001 startcode instead of the length prefix.
43450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // mNALSizeLen ranges from 1 through 4 bytes, so add an extra
43550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // 3 bytes of padding to the buffer start.
43650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    static const size_t kPadding = 3;
43750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
43850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    MediaBuffer *buffer = new MediaBuffer(size + kPadding);
43950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
44050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    int64_t timeUs;
44150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs));
44250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    int32_t isSync;
44350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, &isSync));
44450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
44550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    buffer->meta_data()->setInt64(kKeyTime, timeUs);
44650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync);
44750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
44850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    memcpy((uint8_t *)buffer->data() + kPadding,
44950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber           (const uint8_t *)frame->data() + frame->range_offset(),
45050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber           size);
45150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
45250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    buffer->set_range(kPadding, size);
45350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
45450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    frame->release();
45550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    frame = NULL;
45650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
45750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    uint8_t *data = (uint8_t *)buffer->data();
45850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
45950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    size_t NALsize;
46050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    switch (mNALSizeLen) {
46150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        case 1: NALsize = data[kPadding]; break;
46250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        case 2: NALsize = U16_AT(&data[kPadding]); break;
46350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        case 3: NALsize = U24_AT(&data[kPadding]); break;
46450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        case 4: NALsize = U32_AT(&data[kPadding]); break;
46550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        default:
46650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            TRESPASS();
46750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
46850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
46950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (size < NALsize + mNALSizeLen) {
47050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        buffer->release();
47150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        buffer = NULL;
47250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
47350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        return ERROR_MALFORMED;
47450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
47550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
47650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (size > NALsize + mNALSizeLen) {
47750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        LOGW("discarding %d bytes of data.", size - NALsize - mNALSizeLen);
47850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
47950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
48050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // actual data starts at &data[kPadding + mNALSizeLen]
48150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
48250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    memcpy(&data[mNALSizeLen - 1], "\x00\x00\x00\x01", 4);
48350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    buffer->set_range(mNALSizeLen - 1, NALsize + 4);
48450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
48550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    *out = buffer;
486093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
487093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
488093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
489093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
490093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber////////////////////////////////////////////////////////////////////////////////
491093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
492093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source)
493093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    : mDataSource(source),
494093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mReader(new DataSourceReader(mDataSource)),
4955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mSegment(NULL),
4965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mExtractedThumbnails(false) {
497d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    off64_t size;
498d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mIsLiveStreaming =
499d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        (mDataSource->flags()
500d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            & (DataSource::kWantsPrefetching
501d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                | DataSource::kIsCachingDataSource))
502d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        && mDataSource->getSize(&size) != OK;
503d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
504093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mkvparser::EBMLHeader ebmlHeader;
505093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long pos;
506093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ebmlHeader.Parse(mReader, pos) < 0) {
507093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
508093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
509093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
510093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long ret =
511093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mkvparser::Segment::CreateInstance(mReader, pos, mSegment);
512093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
513093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ret) {
514093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        CHECK(mSegment == NULL);
515093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
516093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
517093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
518d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    if (isLiveStreaming()) {
519d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        ret = mSegment->ParseHeaders();
520d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CHECK_EQ(ret, 0);
521d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
522d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        long len;
523d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        ret = mSegment->LoadCluster(pos, len);
524d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CHECK_EQ(ret, 0);
525d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    } else {
526d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        ret = mSegment->Load();
527d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    }
528093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
529093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ret < 0) {
530093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        delete mSegment;
531093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mSegment = NULL;
532093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
533093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
534093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
535093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    addTracks();
536093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
537093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
538093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::~MatroskaExtractor() {
539093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete mSegment;
540093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mSegment = NULL;
541093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
542093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete mReader;
543093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mReader = NULL;
544093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
545093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
546093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersize_t MatroskaExtractor::countTracks() {
547093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mTracks.size();
548093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
549093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
550093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MediaSource> MatroskaExtractor::getTrack(size_t index) {
551093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (index >= mTracks.size()) {
552093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return NULL;
553093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
554093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
555093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return new MatroskaSource(this, index);
556093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
557093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
558093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getTrackMetaData(
559093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        size_t index, uint32_t flags) {
560093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (index >= mTracks.size()) {
561093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return NULL;
562093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
563093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
564d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails
565d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            && !isLiveStreaming()) {
5665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        findThumbnails();
5675279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        mExtractedThumbnails = true;
5685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
5695279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
570093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mTracks.itemAt(index).mMeta;
571093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
572093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
573d42573cace9db2b5948e540c32beaef80f04153cAndreas Huberbool MatroskaExtractor::isLiveStreaming() const {
574d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    return mIsLiveStreaming;
575d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber}
576d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
577093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic void addESDSFromAudioSpecificInfo(
578093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MetaData> &meta, const void *asi, size_t asiSize) {
579093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    static const uint8_t kStaticESDS[] = {
580093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x03, 22,
581093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00,     // ES_ID
582093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
583093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
584093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x04, 17,
585093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x40,                       // Audio ISO/IEC 14496-3
586093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
587093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
588093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
589093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
590093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x05,
591093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        // AudioSpecificInfo (with size prefix) follows
592093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    };
593093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
594093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(asiSize < 128);
595093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1;
596093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    uint8_t *esds = new uint8_t[esdsSize];
597093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    memcpy(esds, kStaticESDS, sizeof(kStaticESDS));
598093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    uint8_t *ptr = esds + sizeof(kStaticESDS);
599093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    *ptr++ = asiSize;
600093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    memcpy(ptr, asi, asiSize);
601093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
602093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(kKeyESDS, 0, esds, esdsSize);
603093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
604093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete[] esds;
605093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    esds = NULL;
606093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
607093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
608093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid addVorbisCodecInfo(
609093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MetaData> &meta,
610093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const void *_codecPrivate, size_t codecPrivateSize) {
611093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    // printf("vorbis private data follows:\n");
612093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    // hexdump(_codecPrivate, codecPrivateSize);
613093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
614093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivateSize >= 3);
615093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
616093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate;
617093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[0] == 0x02);
618093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
619093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t len1 = codecPrivate[1];
620093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t len2 = codecPrivate[2];
621093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
622093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivateSize > 3 + len1 + len2);
623093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
624093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[3] == 0x01);
625093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1);
626093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
627093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[len1 + 3] == 0x03);
628093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
629093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[len1 + len2 + 3] == 0x05);
630093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(
631093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3],
632093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            codecPrivateSize - len1 - len2 - 3);
633093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
634093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
635093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid MatroskaExtractor::addTracks() {
636093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const mkvparser::Tracks *tracks = mSegment->GetTracks();
637093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
638093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    for (size_t index = 0; index < tracks->GetTracksCount(); ++index) {
639093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const mkvparser::Track *track = tracks->GetTrackByIndex(index);
640093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
64130ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber        if (track == NULL) {
64230ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber            // Apparently this is currently valid (if unexpected) behaviour
64330ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber            // of the mkv parser lib.
64430ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber            continue;
64530ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber        }
64630ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber
647093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const char *const codecID = track->GetCodecId();
648093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        LOGV("codec id = %s", codecID);
649093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        LOGV("codec name = %s", track->GetCodecNameAsUTF8());
650093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
651093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        size_t codecPrivateSize;
652093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const unsigned char *codecPrivate =
653ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber            track->GetCodecPrivate(codecPrivateSize);
654093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
655093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 };
656093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
657093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        sp<MetaData> meta = new MetaData;
658093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
659093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        switch (track->GetType()) {
660093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            case VIDEO_TRACK:
661093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            {
662093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                const mkvparser::VideoTrack *vtrack =
663093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    static_cast<const mkvparser::VideoTrack *>(track);
664093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
665093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
666093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
667093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize);
668093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else if (!strcmp("V_VP8", codecID)) {
669093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX);
670093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else {
671093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    continue;
672093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                }
673093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
674093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyWidth, vtrack->GetWidth());
675093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyHeight, vtrack->GetHeight());
676093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                break;
677093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
678093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
679093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            case AUDIO_TRACK:
680093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            {
681093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                const mkvparser::AudioTrack *atrack =
682093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    static_cast<const mkvparser::AudioTrack *>(track);
683093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
684093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                if (!strcmp("A_AAC", codecID)) {
685093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
686093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    CHECK(codecPrivateSize >= 2);
687093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
688093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    addESDSFromAudioSpecificInfo(
689093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                            meta, codecPrivate, codecPrivateSize);
690093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else if (!strcmp("A_VORBIS", codecID)) {
691093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS);
692093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
693093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize);
694093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else {
695093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    continue;
696093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                }
697093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
698093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeySampleRate, atrack->GetSamplingRate());
699093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyChannelCount, atrack->GetChannels());
700093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                break;
701093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
702093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
703093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            default:
704093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                continue;
705093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
706093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
707093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        long long durationNs = mSegment->GetDuration();
708093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        meta->setInt64(kKeyDuration, (durationNs + 500) / 1000);
709093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
710093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mTracks.push();
711093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1);
712093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        trackInfo->mTrackNum = track->GetNumber();
713093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        trackInfo->mMeta = meta;
714093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
715093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
716093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
7175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid MatroskaExtractor::findThumbnails() {
7185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
7195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        TrackInfo *info = &mTracks.editItemAt(i);
7205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
7215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        const char *mime;
7225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        CHECK(info->mMeta->findCString(kKeyMIMEType, &mime));
7235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
7245279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        if (strncasecmp(mime, "video/", 6)) {
7255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            continue;
7265279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        }
7275279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
728d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        BlockIterator iter(this, info->mTrackNum);
7295279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        int32_t i = 0;
7305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        int64_t thumbnailTimeUs = 0;
7315279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        size_t maxBlockSize = 0;
7325279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        while (!iter.eos() && i < 20) {
7335279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            if (iter.block()->IsKey()) {
7345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                ++i;
7355279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
736d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                size_t blockSize = 0;
737d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                for (int i = 0; i < iter.block()->GetFrameCount(); ++i) {
738d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                    blockSize += iter.block()->GetFrame(i).len;
739d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                }
740d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
7415279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                if (blockSize > maxBlockSize) {
7425279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                    maxBlockSize = blockSize;
7435279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                    thumbnailTimeUs = iter.blockTimeUs();
7445279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                }
7455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            }
7465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            iter.advance();
7475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        }
7485279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
7495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
7505279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
7515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
752093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getMetaData() {
753093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    sp<MetaData> meta = new MetaData;
754093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MATROSKA);
755093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
756093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return meta;
757093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
758093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
759d42573cace9db2b5948e540c32beaef80f04153cAndreas Huberuint32_t MatroskaExtractor::flags() const {
760d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    uint32_t x = CAN_PAUSE;
761d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    if (!isLiveStreaming()) {
762d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK;
763d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    }
764d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
765d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    return x;
766d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber}
767d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
768093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberbool SniffMatroska(
7695a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
7705a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
771093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    DataSourceReader reader(source);
772093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mkvparser::EBMLHeader ebmlHeader;
773093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long pos;
774093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ebmlHeader.Parse(&reader, pos) < 0) {
775093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return false;
776093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
777093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
778093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA);
779093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    *confidence = 0.6;
780093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
781093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return true;
782093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
783093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
784093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}  // namespace android
785