MatroskaExtractor.cpp revision 792e33fd19e57e0d615d401a54ab567d04f16251
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();
9674a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber    void seek(int64_t seekTimeUs, bool seekToKeyFrame);
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;
14074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber    bool mIsAudio;
1415279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    BlockIterator mBlockIter;
142b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    size_t mNALSizeLen;  // for type AVC
143093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
14450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    List<MediaBuffer *> mPendingFrames;
14550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
146093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    status_t advance();
147093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
14850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    status_t readBlock();
14950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    void clearPendingFrames();
15050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
151093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    MatroskaSource(const MatroskaSource &);
152093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    MatroskaSource &operator=(const MatroskaSource &);
153093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber};
154093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
155093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaSource::MatroskaSource(
156093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MatroskaExtractor> &extractor, size_t index)
157093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    : mExtractor(extractor),
158093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mTrackIndex(index),
159093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mType(OTHER),
16074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber      mIsAudio(false),
161d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber      mBlockIter(mExtractor.get(),
162b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                 mExtractor->mTracks.itemAt(index).mTrackNum),
163b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber      mNALSizeLen(0) {
164b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta;
165b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
166093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const char *mime;
167b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
168093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
16974a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber    mIsAudio = !strncasecmp("audio/", mime, 6);
17074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber
171093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
172093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mType = AVC;
173b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
174b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        uint32_t dummy;
175b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        const uint8_t *avcc;
176b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        size_t avccSize;
177b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        CHECK(meta->findData(
178b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                    kKeyAVCC, &dummy, (const void **)&avcc, &avccSize));
179b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
180b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        CHECK_GE(avccSize, 5u);
181b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
182b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        mNALSizeLen = 1 + (avcc[4] & 3);
183b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        LOGV("mNALSizeLen = %d", mNALSizeLen);
184093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
185093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mType = AAC;
186093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
187093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
188093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
18950c8bea8fba2fcafb14696399028bdbc094dc995Andreas HuberMatroskaSource::~MatroskaSource() {
19050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    clearPendingFrames();
19150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
19250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
193093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::start(MetaData *params) {
1945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mBlockIter.reset();
195093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
196093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
197093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
198093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
199093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::stop() {
20050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    clearPendingFrames();
20150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
202093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
203093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
204093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
205093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaSource::getFormat() {
206093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mExtractor->mTracks.itemAt(mTrackIndex).mMeta;
207093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
208093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
2095279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber////////////////////////////////////////////////////////////////////////////////
2105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas HuberBlockIterator::BlockIterator(
212d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        MatroskaExtractor *extractor, unsigned long trackNum)
213d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    : mExtractor(extractor),
2145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mTrackNum(trackNum),
2155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mCluster(NULL),
216d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber      mBlockEntry(NULL),
217d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber      mBlockEntryIndex(0) {
2185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    reset();
2195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberbool BlockIterator::eos() const {
2225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return mCluster == NULL || mCluster->EOS();
2235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2245279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::advance() {
226d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    Mutex::Autolock autoLock(mExtractor->mLock);
227d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    advance_l();
228d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber}
229d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
230d42573cace9db2b5948e540c32beaef80f04153cAndreas Hubervoid BlockIterator::advance_l() {
231d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    for (;;) {
232d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry);
233d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        LOGV("GetEntry returned %ld", res);
234d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
235d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        long long pos;
236d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        long len;
237d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        if (res < 0) {
238d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            // Need to parse this cluster some more
239d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
240d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL);
241d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
242d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            res = mCluster->Parse(pos, len);
243d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            LOGV("Parse returned %ld", res);
244d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
245d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            if (res < 0) {
246d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                // I/O error
247d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
248d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                LOGE("Cluster::Parse returned result %ld", res);
2495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
250d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                mCluster = NULL;
2515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                break;
252093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
2535279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
254d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            continue;
255d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        } else if (res == 0) {
256d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            // We're done with this cluster
257d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
258d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            const mkvparser::Cluster *nextCluster;
259d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            res = mExtractor->mSegment->ParseNext(
260d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                    mCluster, nextCluster, pos, len);
261d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            LOGV("ParseNext returned %ld", res);
262d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
263d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            if (res > 0) {
264d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                // EOF
265d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
266d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                mCluster = NULL;
267d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                break;
268d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            }
269d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
270d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            CHECK_EQ(res, 0);
271d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            CHECK(nextCluster != NULL);
272d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            CHECK(!nextCluster->EOS());
273d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
274d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            mCluster = nextCluster;
275d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
276d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            res = mCluster->Parse(pos, len);
277d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            LOGV("Parse (2) returned %ld", res);
278d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            CHECK_GE(res, 0);
279d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
280d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            mBlockEntryIndex = 0;
281d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            continue;
282093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
283093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
284d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CHECK(mBlockEntry != NULL);
285d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CHECK(mBlockEntry->GetBlock() != NULL);
286d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        ++mBlockEntryIndex;
287d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
288d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) {
2895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            break;
290093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
2915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
2925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::reset() {
295d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    Mutex::Autolock autoLock(mExtractor->mLock);
296093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
297d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mCluster = mExtractor->mSegment->GetFirst();
2982ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber    mBlockEntry = NULL;
299d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mBlockEntryIndex = 0;
300d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
301d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    do {
302d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        advance_l();
303d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    } while (!eos() && block()->GetTrackNumber() != mTrackNum);
3045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
305093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
30674a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Hubervoid BlockIterator::seek(int64_t seekTimeUs, bool seekToKeyFrame) {
307d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    Mutex::Autolock autoLock(mExtractor->mLock);
308d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
309d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll);
3102ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber    mBlockEntry = NULL;
311d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mBlockEntryIndex = 0;
3125279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
3132ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber    do {
314d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        advance_l();
3155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
3162ba7ce928b0fa8917ee202836b0963ca58613453Andreas Huber    while (!eos() && block()->GetTrackNumber() != mTrackNum);
3175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
31874a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber    if (seekToKeyFrame) {
31974a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber        while (!eos() && !mBlockEntry->GetBlock()->IsKey()) {
32074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber            advance_l();
32174a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber        }
3225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
323093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
324093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
3255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberconst mkvparser::Block *BlockIterator::block() const {
3265279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    CHECK(!eos());
3275279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
3285279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return mBlockEntry->GetBlock();
3295279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
3305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
3315279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberint64_t BlockIterator::blockTimeUs() const {
3325279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll;
3335279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
3345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
3355279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber////////////////////////////////////////////////////////////////////////////////
3365279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
337b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huberstatic unsigned U24_AT(const uint8_t *ptr) {
338b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
339b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber}
340b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
34150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatic size_t clz(uint8_t x) {
34250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    size_t numLeadingZeroes = 0;
343093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
34450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    while (!(x & 0x80)) {
34550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        ++numLeadingZeroes;
34650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        x = x << 1;
347093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
348093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
34950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    return numLeadingZeroes;
35050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
35150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
35250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Hubervoid MatroskaSource::clearPendingFrames() {
35350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    while (!mPendingFrames.empty()) {
35450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        MediaBuffer *frame = *mPendingFrames.begin();
35550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mPendingFrames.erase(mPendingFrames.begin());
35650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
35750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        frame->release();
35850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        frame = NULL;
35950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
36050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
36150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
36250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::readBlock() {
36350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    CHECK(mPendingFrames.empty());
36450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
3655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    if (mBlockIter.eos()) {
366093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return ERROR_END_OF_STREAM;
367093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
368093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
3695279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    const mkvparser::Block *block = mBlockIter.block();
37050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
3715279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    int64_t timeUs = mBlockIter.blockTimeUs();
372093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
373d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    for (int i = 0; i < block->GetFrameCount(); ++i) {
374d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        const mkvparser::Block::Frame &frame = block->GetFrame(i);
375b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
376d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        MediaBuffer *mbuf = new MediaBuffer(frame.len);
377d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        mbuf->meta_data()->setInt64(kKeyTime, timeUs);
378d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        mbuf->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey());
379093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
380d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        long n = frame.Read(mExtractor->mReader, (unsigned char *)mbuf->data());
381d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        if (n != 0) {
382d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            mPendingFrames.clear();
38350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
384d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            mBlockIter.advance();
385d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            return ERROR_IO;
38650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        }
38750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
38850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mPendingFrames.push_back(mbuf);
38950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
39050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
391d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mBlockIter.advance();
39250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
39350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    return OK;
39450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
39550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
39650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::read(
39750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
39850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    *out = NULL;
39950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
40050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    int64_t seekTimeUs;
40150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    ReadOptions::SeekMode mode;
402d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    if (options && options->getSeekTo(&seekTimeUs, &mode)
403d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            && !mExtractor->isLiveStreaming()) {
40450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        clearPendingFrames();
40574a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber
40674a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber        // Apparently keyframe indication in audio tracks is unreliable,
40774a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber        // fortunately in all our currently supported audio encodings every
40874a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber        // frame is effectively a keyframe.
40974a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber        mBlockIter.seek(seekTimeUs, !mIsAudio);
41050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
41150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
41250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberagain:
41350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    while (mPendingFrames.empty()) {
41450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        status_t err = readBlock();
41550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
41650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        if (err != OK) {
41750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            clearPendingFrames();
41850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
41950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            return err;
42050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        }
42150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
42250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
42350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    MediaBuffer *frame = *mPendingFrames.begin();
42450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    mPendingFrames.erase(mPendingFrames.begin());
42550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
42650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (mType != AVC) {
42750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        *out = frame;
42850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
42950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        return OK;
43050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
43150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
432792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    // Each input frame contains one or more NAL fragments, each fragment
433792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    // is prefixed by mNALSizeLen bytes giving the fragment length,
434792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    // followed by a corresponding number of bytes containing the fragment.
435792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    // We output all these fragments into a single large buffer separated
436792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    // by startcodes (0x00 0x00 0x00 0x01).
437792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber
438792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    const uint8_t *srcPtr =
439792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber        (const uint8_t *)frame->data() + frame->range_offset();
440792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber
441792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    size_t srcSize = frame->range_length();
442792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber
443792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    size_t dstSize = 0;
444792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    MediaBuffer *buffer = NULL;
445792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    uint8_t *dstPtr = NULL;
446792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber
447792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    for (int32_t pass = 0; pass < 2; ++pass) {
448792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber        size_t srcOffset = 0;
449792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber        size_t dstOffset = 0;
450792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber        while (srcOffset + mNALSizeLen <= srcSize) {
451792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            size_t NALsize;
452792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            switch (mNALSizeLen) {
453792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber                case 1: NALsize = srcPtr[srcOffset]; break;
454792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber                case 2: NALsize = U16_AT(srcPtr + srcOffset); break;
455792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber                case 3: NALsize = U24_AT(srcPtr + srcOffset); break;
456792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber                case 4: NALsize = U32_AT(srcPtr + srcOffset); break;
457792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber                default:
458792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber                    TRESPASS();
459792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            }
46050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
461792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            if (srcOffset + mNALSizeLen + NALsize > srcSize) {
462792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber                break;
463792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            }
46450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
465792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            if (pass == 1) {
466792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber                memcpy(&dstPtr[dstOffset], "\x00\x00\x00\x01", 4);
46750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
468792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber                memcpy(&dstPtr[dstOffset + 4],
469792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber                       &srcPtr[srcOffset + mNALSizeLen],
470792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber                       NALsize);
471792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            }
47250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
473792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            dstOffset += 4;  // 0x00 00 00 01
474792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            dstOffset += NALsize;
47550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
476792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            srcOffset += mNALSizeLen + NALsize;
477792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber        }
47850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
479792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber        if (srcOffset < srcSize) {
480792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            // There were trailing bytes or not enough data to complete
481792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            // a fragment.
48250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
483792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            frame->release();
484792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            frame = NULL;
48550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
486792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            return ERROR_MALFORMED;
487792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber        }
48850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
489792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber        if (pass == 0) {
490792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            dstSize = dstOffset;
49150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
492792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            buffer = new MediaBuffer(dstSize);
49350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
494792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            int64_t timeUs;
495792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs));
496792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            int32_t isSync;
497792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, &isSync));
49850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
499792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            buffer->meta_data()->setInt64(kKeyTime, timeUs);
500792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync);
50150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
502792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber            dstPtr = (uint8_t *)buffer->data();
503792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber        }
50450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
50550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
506792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    frame->release();
507792e33fd19e57e0d615d401a54ab567d04f16251Andreas Huber    frame = NULL;
50850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
50950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    *out = buffer;
510093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
511093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
512093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
513093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
514093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber////////////////////////////////////////////////////////////////////////////////
515093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
516093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source)
517093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    : mDataSource(source),
518093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mReader(new DataSourceReader(mDataSource)),
5195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mSegment(NULL),
5208c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber      mExtractedThumbnails(false),
5218c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber      mIsWebm(false) {
522d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    off64_t size;
523d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    mIsLiveStreaming =
524d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        (mDataSource->flags()
525d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            & (DataSource::kWantsPrefetching
526d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                | DataSource::kIsCachingDataSource))
527d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        && mDataSource->getSize(&size) != OK;
528d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
529093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mkvparser::EBMLHeader ebmlHeader;
530093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long pos;
531093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ebmlHeader.Parse(mReader, pos) < 0) {
532093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
533093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
534093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
5358c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber    if (ebmlHeader.m_docType && !strcmp("webm", ebmlHeader.m_docType)) {
5368c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber        mIsWebm = true;
5378c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber    }
5388c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber
539093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long ret =
540093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mkvparser::Segment::CreateInstance(mReader, pos, mSegment);
541093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
542093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ret) {
543093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        CHECK(mSegment == NULL);
544093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
545093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
546093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
547d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    if (isLiveStreaming()) {
548d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        ret = mSegment->ParseHeaders();
549d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CHECK_EQ(ret, 0);
550d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
551d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        long len;
552d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        ret = mSegment->LoadCluster(pos, len);
553d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        CHECK_EQ(ret, 0);
554d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    } else {
555d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        ret = mSegment->Load();
556d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    }
557093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
558093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ret < 0) {
559093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        delete mSegment;
560093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mSegment = NULL;
561093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
562093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
563093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
56474a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber#if 0
56574a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber    const mkvparser::SegmentInfo *info = mSegment->GetInfo();
56674a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber    LOGI("muxing app: %s, writing app: %s",
56774a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber         info->GetMuxingAppAsUTF8(),
56874a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber         info->GetWritingAppAsUTF8());
56974a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber#endif
57074a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber
571093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    addTracks();
572093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
573093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
574093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::~MatroskaExtractor() {
575093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete mSegment;
576093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mSegment = NULL;
577093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
578093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete mReader;
579093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mReader = NULL;
580093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
581093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
582093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersize_t MatroskaExtractor::countTracks() {
583093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mTracks.size();
584093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
585093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
586093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MediaSource> MatroskaExtractor::getTrack(size_t index) {
587093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (index >= mTracks.size()) {
588093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return NULL;
589093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
590093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
591093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return new MatroskaSource(this, index);
592093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
593093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
594093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getTrackMetaData(
595093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        size_t index, uint32_t flags) {
596093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (index >= mTracks.size()) {
597093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return NULL;
598093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
599093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
600d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails
601d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber            && !isLiveStreaming()) {
6025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        findThumbnails();
6035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        mExtractedThumbnails = true;
6045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
6055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
606093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mTracks.itemAt(index).mMeta;
607093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
608093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
609d42573cace9db2b5948e540c32beaef80f04153cAndreas Huberbool MatroskaExtractor::isLiveStreaming() const {
610d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    return mIsLiveStreaming;
611d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber}
612d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
613093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic void addESDSFromAudioSpecificInfo(
614093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MetaData> &meta, const void *asi, size_t asiSize) {
615093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    static const uint8_t kStaticESDS[] = {
616093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x03, 22,
617093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00,     // ES_ID
618093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
619093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
620093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x04, 17,
621093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x40,                       // Audio ISO/IEC 14496-3
622093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
623093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
624093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
625093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
626093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x05,
627093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        // AudioSpecificInfo (with size prefix) follows
628093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    };
629093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
63082ac8bf2da940c4439786c346f739f4a496864adAndreas Huber    // Make sure all sizes can be coded in a single byte.
63182ac8bf2da940c4439786c346f739f4a496864adAndreas Huber    CHECK(asiSize + 22 - 2 < 128);
632093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1;
633093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    uint8_t *esds = new uint8_t[esdsSize];
634093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    memcpy(esds, kStaticESDS, sizeof(kStaticESDS));
635093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    uint8_t *ptr = esds + sizeof(kStaticESDS);
636093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    *ptr++ = asiSize;
637093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    memcpy(ptr, asi, asiSize);
638093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
63982ac8bf2da940c4439786c346f739f4a496864adAndreas Huber    // Increment by codecPrivateSize less 2 bytes that are accounted for
64082ac8bf2da940c4439786c346f739f4a496864adAndreas Huber    // already in lengths of 22/17
64182ac8bf2da940c4439786c346f739f4a496864adAndreas Huber    esds[1] += asiSize - 2;
64282ac8bf2da940c4439786c346f739f4a496864adAndreas Huber    esds[6] += asiSize - 2;
64382ac8bf2da940c4439786c346f739f4a496864adAndreas Huber
644093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(kKeyESDS, 0, esds, esdsSize);
645093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
646093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete[] esds;
647093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    esds = NULL;
648093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
649093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
650093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid addVorbisCodecInfo(
651093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MetaData> &meta,
652093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const void *_codecPrivate, size_t codecPrivateSize) {
653093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    // printf("vorbis private data follows:\n");
654093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    // hexdump(_codecPrivate, codecPrivateSize);
655093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
656093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivateSize >= 3);
657093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
658093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate;
659093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[0] == 0x02);
660093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
661093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t len1 = codecPrivate[1];
662093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t len2 = codecPrivate[2];
663093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
664093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivateSize > 3 + len1 + len2);
665093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
666093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[3] == 0x01);
667093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1);
668093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
669093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[len1 + 3] == 0x03);
670093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
671093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[len1 + len2 + 3] == 0x05);
672093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(
673093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3],
674093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            codecPrivateSize - len1 - len2 - 3);
675093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
676093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
677093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid MatroskaExtractor::addTracks() {
678093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const mkvparser::Tracks *tracks = mSegment->GetTracks();
679093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
680093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    for (size_t index = 0; index < tracks->GetTracksCount(); ++index) {
681093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const mkvparser::Track *track = tracks->GetTrackByIndex(index);
682093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
68330ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber        if (track == NULL) {
68430ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber            // Apparently this is currently valid (if unexpected) behaviour
68530ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber            // of the mkv parser lib.
68630ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber            continue;
68730ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber        }
68830ae68bccd8de6f0ab2acd22a6d661ace514343eAndreas Huber
689093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const char *const codecID = track->GetCodecId();
690093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        LOGV("codec id = %s", codecID);
691093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        LOGV("codec name = %s", track->GetCodecNameAsUTF8());
692093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
693093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        size_t codecPrivateSize;
694093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const unsigned char *codecPrivate =
695ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber            track->GetCodecPrivate(codecPrivateSize);
696093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
697093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 };
698093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
699093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        sp<MetaData> meta = new MetaData;
700093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
701093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        switch (track->GetType()) {
702093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            case VIDEO_TRACK:
703093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            {
704093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                const mkvparser::VideoTrack *vtrack =
705093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    static_cast<const mkvparser::VideoTrack *>(track);
706093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
707093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
708093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
709093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize);
710093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else if (!strcmp("V_VP8", codecID)) {
711093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX);
712093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else {
713093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    continue;
714093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                }
715093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
716093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyWidth, vtrack->GetWidth());
717093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyHeight, vtrack->GetHeight());
718093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                break;
719093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
720093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
721093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            case AUDIO_TRACK:
722093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            {
723093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                const mkvparser::AudioTrack *atrack =
724093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    static_cast<const mkvparser::AudioTrack *>(track);
725093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
726093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                if (!strcmp("A_AAC", codecID)) {
727093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
728093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    CHECK(codecPrivateSize >= 2);
729093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
730093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    addESDSFromAudioSpecificInfo(
731093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                            meta, codecPrivate, codecPrivateSize);
732093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else if (!strcmp("A_VORBIS", codecID)) {
733093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS);
734093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
735093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize);
736093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else {
737093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    continue;
738093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                }
739093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
740093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeySampleRate, atrack->GetSamplingRate());
741093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyChannelCount, atrack->GetChannels());
742093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                break;
743093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
744093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
745093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            default:
746093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                continue;
747093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
748093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
749093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        long long durationNs = mSegment->GetDuration();
750093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        meta->setInt64(kKeyDuration, (durationNs + 500) / 1000);
751093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
752093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mTracks.push();
753093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1);
754093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        trackInfo->mTrackNum = track->GetNumber();
755093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        trackInfo->mMeta = meta;
756093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
757093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
758093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
7595279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid MatroskaExtractor::findThumbnails() {
7605279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
7615279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        TrackInfo *info = &mTracks.editItemAt(i);
7625279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
7635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        const char *mime;
7645279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        CHECK(info->mMeta->findCString(kKeyMIMEType, &mime));
7655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
7665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        if (strncasecmp(mime, "video/", 6)) {
7675279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            continue;
7685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        }
7695279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
770d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        BlockIterator iter(this, info->mTrackNum);
7715279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        int32_t i = 0;
7725279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        int64_t thumbnailTimeUs = 0;
7735279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        size_t maxBlockSize = 0;
7745279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        while (!iter.eos() && i < 20) {
7755279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            if (iter.block()->IsKey()) {
7765279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                ++i;
7775279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
778d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                size_t blockSize = 0;
779d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                for (int i = 0; i < iter.block()->GetFrameCount(); ++i) {
780d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                    blockSize += iter.block()->GetFrame(i).len;
781d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                }
782d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
7835279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                if (blockSize > maxBlockSize) {
7845279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                    maxBlockSize = blockSize;
7855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                    thumbnailTimeUs = iter.blockTimeUs();
7865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                }
7875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            }
7885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            iter.advance();
7895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        }
7905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
7915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
7925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
7935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
794093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getMetaData() {
795093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    sp<MetaData> meta = new MetaData;
7968c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber
7978c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber    meta->setCString(
7988c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber            kKeyMIMEType,
7998c32b164d00d3e4d73764d06956331f09693ef43Andreas Huber            mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA);
800093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
801093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return meta;
802093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
803093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
804d42573cace9db2b5948e540c32beaef80f04153cAndreas Huberuint32_t MatroskaExtractor::flags() const {
805d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    uint32_t x = CAN_PAUSE;
806d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    if (!isLiveStreaming()) {
807d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK;
808d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    }
809d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
810d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    return x;
811d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber}
812d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber
813093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberbool SniffMatroska(
8145a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
8155a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
816093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    DataSourceReader reader(source);
817093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mkvparser::EBMLHeader ebmlHeader;
818093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long pos;
819093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ebmlHeader.Parse(&reader, pos) < 0) {
820093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return false;
821093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
822093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
823093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA);
824093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    *confidence = 0.6;
825093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
826093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return true;
827093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
828093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
829093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}  // namespace android
830