MatroskaExtractor.cpp revision 50c8bea8fba2fcafb14696399028bdbc094dc995
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) {
63093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            return -1;
64093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
65093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
66093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        if (total) {
67093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            *total = size;
68093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
69093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
70093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        if (available) {
71093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            *available = size;
72093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
73093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
74093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return 0;
75093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
76093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
77093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate:
78093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    sp<DataSource> mSource;
79093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
80093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    DataSourceReader(const DataSourceReader &);
81093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    DataSourceReader &operator=(const DataSourceReader &);
82093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber};
83093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
84093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber////////////////////////////////////////////////////////////////////////////////
85093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberstruct BlockIterator {
875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    BlockIterator(mkvparser::Segment *segment, unsigned long trackNum);
885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    bool eos() const;
905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    void advance();
925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    void reset();
935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    void seek(int64_t seekTimeUs);
945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    const mkvparser::Block *block() const;
965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    int64_t blockTimeUs() const;
975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberprivate:
995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mkvparser::Segment *mSegment;
1005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    unsigned long mTrackNum;
1015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
1025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mkvparser::Cluster *mCluster;
1035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    const mkvparser::BlockEntry *mBlockEntry;
1045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
1055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    BlockIterator(const BlockIterator &);
1065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    BlockIterator &operator=(const BlockIterator &);
1075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber};
1085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
109093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstruct MatroskaSource : public MediaSource {
110093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    MatroskaSource(
111093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            const sp<MatroskaExtractor> &extractor, size_t index);
112093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
113093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    virtual status_t start(MetaData *params);
114093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    virtual status_t stop();
115093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
116093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    virtual sp<MetaData> getFormat();
117093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
118093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    virtual status_t read(
119093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            MediaBuffer **buffer, const ReadOptions *options);
120093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
12150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberprotected:
12250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    virtual ~MatroskaSource();
12350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
124093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate:
125093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    enum Type {
126093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        AVC,
127093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        AAC,
128093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        OTHER
129093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    };
130093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
131093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    sp<MatroskaExtractor> mExtractor;
132093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t mTrackIndex;
133093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    Type mType;
1345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    BlockIterator mBlockIter;
135b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    size_t mNALSizeLen;  // for type AVC
136093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
13750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    List<MediaBuffer *> mPendingFrames;
13850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
139093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    status_t advance();
140093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
14150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    status_t readBlock();
14250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    void clearPendingFrames();
14350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
144093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    MatroskaSource(const MatroskaSource &);
145093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    MatroskaSource &operator=(const MatroskaSource &);
146093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber};
147093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
148093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaSource::MatroskaSource(
149093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MatroskaExtractor> &extractor, size_t index)
150093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    : mExtractor(extractor),
151093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mTrackIndex(index),
152093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mType(OTHER),
1535279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mBlockIter(mExtractor->mSegment,
154b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                 mExtractor->mTracks.itemAt(index).mTrackNum),
155b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber      mNALSizeLen(0) {
156b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta;
157b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
158093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const char *mime;
159b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
160093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
161093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
162093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mType = AVC;
163b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
164b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        uint32_t dummy;
165b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        const uint8_t *avcc;
166b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        size_t avccSize;
167b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        CHECK(meta->findData(
168b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                    kKeyAVCC, &dummy, (const void **)&avcc, &avccSize));
169b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
170b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        CHECK_GE(avccSize, 5u);
171b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
172b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        mNALSizeLen = 1 + (avcc[4] & 3);
173b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        LOGV("mNALSizeLen = %d", mNALSizeLen);
174093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
175093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mType = AAC;
176093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
177093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
178093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
17950c8bea8fba2fcafb14696399028bdbc094dc995Andreas HuberMatroskaSource::~MatroskaSource() {
18050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    clearPendingFrames();
18150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
18250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
183093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::start(MetaData *params) {
1845279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mBlockIter.reset();
185093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
186093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
187093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
188093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
189093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::stop() {
19050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    clearPendingFrames();
19150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
192093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
193093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
194093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
195093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaSource::getFormat() {
196093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mExtractor->mTracks.itemAt(mTrackIndex).mMeta;
197093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
198093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
1995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber////////////////////////////////////////////////////////////////////////////////
2005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas HuberBlockIterator::BlockIterator(
2025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        mkvparser::Segment *segment, unsigned long trackNum)
2035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    : mSegment(segment),
2045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mTrackNum(trackNum),
2055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mCluster(NULL),
2065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mBlockEntry(NULL) {
2075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    reset();
2085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2095279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberbool BlockIterator::eos() const {
2115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return mCluster == NULL || mCluster->EOS();
2125279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2135279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::advance() {
2155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    while (!eos()) {
2165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        if (mBlockEntry != NULL) {
2175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            mBlockEntry = mCluster->GetNext(mBlockEntry);
2185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        } else if (mCluster != NULL) {
2195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            mCluster = mSegment->GetNext(mCluster);
2205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            if (eos()) {
2225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                break;
223093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
2245279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
225093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            mBlockEntry = mCluster->GetFirst();
226093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
227093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
2285279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        if (mBlockEntry != NULL
2295279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                && mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) {
2305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            break;
231093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
2325279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
2335279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2355279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::reset() {
2365279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mCluster = mSegment->GetFirst();
2375279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mBlockEntry = mCluster->GetFirst();
238093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
2395279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    while (!eos() && block()->GetTrackNumber() != mTrackNum) {
2405279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        advance();
241093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
2425279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
243093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
2445279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::seek(int64_t seekTimeUs) {
245ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber    mCluster = mSegment->FindCluster(seekTimeUs * 1000ll);
2465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mBlockEntry = mCluster != NULL ? mCluster->GetFirst() : NULL;
2475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2485279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    while (!eos() && block()->GetTrackNumber() != mTrackNum) {
2495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        advance();
2505279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
2515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2525279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    while (!eos() && !mBlockEntry->GetBlock()->IsKey()) {
2535279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        advance();
2545279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
255093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
256093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
2575279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberconst mkvparser::Block *BlockIterator::block() const {
2585279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    CHECK(!eos());
2595279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2605279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return mBlockEntry->GetBlock();
2615279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2625279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberint64_t BlockIterator::blockTimeUs() const {
2645279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll;
2655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2675279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber////////////////////////////////////////////////////////////////////////////////
2685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
269b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huberstatic unsigned U24_AT(const uint8_t *ptr) {
270b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
271b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber}
272b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
27350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatic size_t clz(uint8_t x) {
27450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    size_t numLeadingZeroes = 0;
275093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
27650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    while (!(x & 0x80)) {
27750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        ++numLeadingZeroes;
27850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        x = x << 1;
279093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
280093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
28150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    return numLeadingZeroes;
28250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
28350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
28450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Hubervoid MatroskaSource::clearPendingFrames() {
28550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    while (!mPendingFrames.empty()) {
28650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        MediaBuffer *frame = *mPendingFrames.begin();
28750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mPendingFrames.erase(mPendingFrames.begin());
28850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
28950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        frame->release();
29050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        frame = NULL;
29150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
29250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
29350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
29450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber#define BAIL(err) \
29550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    do {                        \
29650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        if (bigbuf) {           \
29750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            bigbuf->release();  \
29850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            bigbuf = NULL;      \
29950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        }                       \
30050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                                \
30150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        return err;             \
30250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    } while (0)
30350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
30450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::readBlock() {
30550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    CHECK(mPendingFrames.empty());
30650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
3075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    if (mBlockIter.eos()) {
308093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return ERROR_END_OF_STREAM;
309093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
310093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
3115279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    const mkvparser::Block *block = mBlockIter.block();
31250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
313093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t size = block->GetSize();
3145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    int64_t timeUs = mBlockIter.blockTimeUs();
31550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    int32_t isSync = block->IsKey();
316093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
31750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    MediaBuffer *bigbuf = new MediaBuffer(size);
318093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
319093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long res = block->Read(
32050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            mExtractor->mReader, (unsigned char *)bigbuf->data());
321093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
322093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (res != 0) {
32350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        bigbuf->release();
32450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        bigbuf = NULL;
32550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
326093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return ERROR_END_OF_STREAM;
327093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
328093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
32950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    mBlockIter.advance();
33050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
33150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    bigbuf->meta_data()->setInt64(kKeyTime, timeUs);
33250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    bigbuf->meta_data()->setInt32(kKeyIsSyncFrame, isSync);
33350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
33450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    unsigned lacing = (block->Flags() >> 1) & 3;
33550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
33650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (lacing == 0) {
33750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mPendingFrames.push_back(bigbuf);
33850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        return OK;
33950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
340093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
34150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    LOGV("lacing = %u, size = %d", lacing, size);
342093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
34350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    const uint8_t *data = (const uint8_t *)bigbuf->data();
34450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // hexdump(data, size);
345093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
34650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (size == 0) {
34750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        BAIL(ERROR_MALFORMED);
34850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
34950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
35050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    unsigned numFrames = (unsigned)data[0] + 1;
35150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    ++data;
35250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    --size;
35350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
35450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    Vector<uint64_t> frameSizes;
35550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
35650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    switch (lacing) {
35750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        case 1:  // Xiph
35850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        {
35950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            for (size_t i = 0; i < numFrames - 1; ++i) {
36050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                size_t frameSize = 0;
36150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                uint8_t byte;
36250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                do {
36350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    if (size == 0) {
36450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                        BAIL(ERROR_MALFORMED);
36550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    }
36650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    byte = data[0];
36750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    ++data;
36850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    --size;
36950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
37050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    frameSize += byte;
37150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                } while (byte == 0xff);
37250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
37350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                frameSizes.push(frameSize);
37450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            }
37550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
37650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            break;
377b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        }
378b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
37950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        case 2:  // fixed-size
38050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        {
38150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            if ((size % numFrames) != 0) {
38250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                BAIL(ERROR_MALFORMED);
38350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            }
38450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
38550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            size_t frameSize = size / numFrames;
38650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            for (size_t i = 0; i < numFrames - 1; ++i) {
38750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                frameSizes.push(frameSize);
38850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            }
38950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
39050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            break;
391b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        }
392b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
39350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        case 3:  // EBML
39450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        {
39550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            uint64_t lastFrameSize = 0;
39650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            for (size_t i = 0; i < numFrames - 1; ++i) {
39750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                uint8_t byte;
398093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
39950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                if (size == 0) {
40050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    BAIL(ERROR_MALFORMED);
40150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                }
40250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                byte = data[0];
40350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                ++data;
40450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                --size;
405093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
40650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                size_t numLeadingZeroes = clz(byte);
407b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
40850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                uint64_t frameSize = byte & ~(0x80 >> numLeadingZeroes);
40950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                for (size_t j = 0; j < numLeadingZeroes; ++j) {
41050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    if (size == 0) {
41150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                        BAIL(ERROR_MALFORMED);
41250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    }
413b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
41450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    frameSize = frameSize << 8;
41550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    frameSize |= data[0];
41650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    ++data;
41750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    --size;
41850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                }
41950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
42050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                if (i == 0) {
42150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    frameSizes.push(frameSize);
42250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                } else {
42350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    size_t shift =
42450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                        7 - numLeadingZeroes + 8 * numLeadingZeroes;
425b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
42650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    int64_t delta =
42750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                        (int64_t)frameSize - (1ll << (shift - 1)) + 1;
428b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
42950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    frameSize = lastFrameSize + delta;
43050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
43150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                    frameSizes.push(frameSize);
43250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                }
43350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
43450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                lastFrameSize = frameSize;
43550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            }
43650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            break;
437b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        }
438b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
43950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        default:
44050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            TRESPASS();
441093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
442093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
443093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#if 0
44450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    AString out;
44550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    for (size_t i = 0; i < frameSizes.size(); ++i) {
44650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        if (i > 0) {
44750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            out.append(", ");
44850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        }
44950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        out.append(StringPrintf("%llu", frameSizes.itemAt(i)));
45050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
45150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    LOGV("sizes = [%s]", out.c_str());
452093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#endif
453093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
45450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    for (size_t i = 0; i < frameSizes.size(); ++i) {
45550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        uint64_t frameSize = frameSizes.itemAt(i);
45650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
45750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        if (size < frameSize) {
45850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            BAIL(ERROR_MALFORMED);
45950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        }
46050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
46150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        MediaBuffer *mbuf = new MediaBuffer(frameSize);
46250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mbuf->meta_data()->setInt64(kKeyTime, timeUs);
46350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mbuf->meta_data()->setInt32(kKeyIsSyncFrame, isSync);
46450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        memcpy(mbuf->data(), data, frameSize);
46550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mPendingFrames.push_back(mbuf);
46650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
46750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        data += frameSize;
46850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        size -= frameSize;
46950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
47050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
47150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    size_t offset = bigbuf->range_length() - size;
47250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    bigbuf->set_range(offset, size);
47350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
47450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    mPendingFrames.push_back(bigbuf);
47550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
47650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    return OK;
47750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
47850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
47950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber#undef BAIL
48050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
48150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberstatus_t MatroskaSource::read(
48250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
48350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    *out = NULL;
48450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
48550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    int64_t seekTimeUs;
48650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    ReadOptions::SeekMode mode;
48750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
48850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        clearPendingFrames();
48950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        mBlockIter.seek(seekTimeUs);
49050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
49150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
49250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huberagain:
49350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    while (mPendingFrames.empty()) {
49450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        status_t err = readBlock();
49550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
49650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        if (err != OK) {
49750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            clearPendingFrames();
49850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
49950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            return err;
50050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        }
50150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
50250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
50350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    MediaBuffer *frame = *mPendingFrames.begin();
50450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    mPendingFrames.erase(mPendingFrames.begin());
50550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
50650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    size_t size = frame->range_length();
50750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
50850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (mType != AVC) {
50950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        *out = frame;
51050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
51150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        return OK;
51250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
51350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
51450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (size < mNALSizeLen) {
51550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        frame->release();
51650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        frame = NULL;
51750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
51850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        return ERROR_MALFORMED;
51950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
52050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
52150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // In the case of AVC content, each NAL unit is prefixed by
52250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // mNALSizeLen bytes of length. We want to prefix the data with
52350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // a four-byte 0x00000001 startcode instead of the length prefix.
52450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // mNALSizeLen ranges from 1 through 4 bytes, so add an extra
52550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // 3 bytes of padding to the buffer start.
52650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    static const size_t kPadding = 3;
52750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
52850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    MediaBuffer *buffer = new MediaBuffer(size + kPadding);
52950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
53050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    int64_t timeUs;
53150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs));
53250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    int32_t isSync;
53350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, &isSync));
53450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
53550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    buffer->meta_data()->setInt64(kKeyTime, timeUs);
53650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync);
53750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
53850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    memcpy((uint8_t *)buffer->data() + kPadding,
53950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber           (const uint8_t *)frame->data() + frame->range_offset(),
54050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber           size);
54150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
54250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    buffer->set_range(kPadding, size);
54350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
54450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    frame->release();
54550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    frame = NULL;
54650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
54750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    uint8_t *data = (uint8_t *)buffer->data();
54850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
54950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    size_t NALsize;
55050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    switch (mNALSizeLen) {
55150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        case 1: NALsize = data[kPadding]; break;
55250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        case 2: NALsize = U16_AT(&data[kPadding]); break;
55350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        case 3: NALsize = U24_AT(&data[kPadding]); break;
55450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        case 4: NALsize = U32_AT(&data[kPadding]); break;
55550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        default:
55650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber            TRESPASS();
55750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
55850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
55950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (size < NALsize + mNALSizeLen) {
56050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        buffer->release();
56150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        buffer = NULL;
56250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
56350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        return ERROR_MALFORMED;
56450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
56550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
56650c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    if (size > NALsize + mNALSizeLen) {
56750c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        LOGW("discarding %d bytes of data.", size - NALsize - mNALSizeLen);
56850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    }
56950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
57050c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    // actual data starts at &data[kPadding + mNALSizeLen]
57150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
57250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    memcpy(&data[mNALSizeLen - 1], "\x00\x00\x00\x01", 4);
57350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    buffer->set_range(mNALSizeLen - 1, NALsize + 4);
57450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
57550c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    *out = buffer;
576093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
577093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
578093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
579093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
580093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber////////////////////////////////////////////////////////////////////////////////
581093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
582093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source)
583093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    : mDataSource(source),
584093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mReader(new DataSourceReader(mDataSource)),
5855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mSegment(NULL),
5865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mExtractedThumbnails(false) {
587093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mkvparser::EBMLHeader ebmlHeader;
588093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long pos;
589093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ebmlHeader.Parse(mReader, pos) < 0) {
590093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
591093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
592093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
593093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long ret =
594093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mkvparser::Segment::CreateInstance(mReader, pos, mSegment);
595093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
596093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ret) {
597093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        CHECK(mSegment == NULL);
598093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
599093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
600093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
601093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    ret = mSegment->Load();
602093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
603093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ret < 0) {
604093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        delete mSegment;
605093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mSegment = NULL;
606093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
607093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
608093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
609093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    addTracks();
610093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
611093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
612093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::~MatroskaExtractor() {
613093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete mSegment;
614093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mSegment = NULL;
615093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
616093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete mReader;
617093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mReader = NULL;
618093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
619093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
620093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersize_t MatroskaExtractor::countTracks() {
621093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mTracks.size();
622093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
623093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
624093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MediaSource> MatroskaExtractor::getTrack(size_t index) {
625093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (index >= mTracks.size()) {
626093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return NULL;
627093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
628093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
629093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return new MatroskaSource(this, index);
630093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
631093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
632093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getTrackMetaData(
633093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        size_t index, uint32_t flags) {
634093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (index >= mTracks.size()) {
635093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return NULL;
636093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
637093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
6385279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails) {
6395279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        findThumbnails();
6405279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        mExtractedThumbnails = true;
6415279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
6425279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
643093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mTracks.itemAt(index).mMeta;
644093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
645093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
646093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic void addESDSFromAudioSpecificInfo(
647093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MetaData> &meta, const void *asi, size_t asiSize) {
648093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    static const uint8_t kStaticESDS[] = {
649093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x03, 22,
650093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00,     // ES_ID
651093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
652093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
653093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x04, 17,
654093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x40,                       // Audio ISO/IEC 14496-3
655093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
656093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
657093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
658093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
659093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x05,
660093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        // AudioSpecificInfo (with size prefix) follows
661093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    };
662093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
663093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(asiSize < 128);
664093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1;
665093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    uint8_t *esds = new uint8_t[esdsSize];
666093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    memcpy(esds, kStaticESDS, sizeof(kStaticESDS));
667093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    uint8_t *ptr = esds + sizeof(kStaticESDS);
668093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    *ptr++ = asiSize;
669093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    memcpy(ptr, asi, asiSize);
670093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
671093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(kKeyESDS, 0, esds, esdsSize);
672093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
673093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete[] esds;
674093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    esds = NULL;
675093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
676093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
677093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid addVorbisCodecInfo(
678093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MetaData> &meta,
679093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const void *_codecPrivate, size_t codecPrivateSize) {
680093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    // printf("vorbis private data follows:\n");
681093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    // hexdump(_codecPrivate, codecPrivateSize);
682093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
683093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivateSize >= 3);
684093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
685093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate;
686093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[0] == 0x02);
687093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
688093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t len1 = codecPrivate[1];
689093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t len2 = codecPrivate[2];
690093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
691093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivateSize > 3 + len1 + len2);
692093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
693093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[3] == 0x01);
694093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1);
695093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
696093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[len1 + 3] == 0x03);
697093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
698093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[len1 + len2 + 3] == 0x05);
699093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(
700093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3],
701093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            codecPrivateSize - len1 - len2 - 3);
702093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
703093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
704093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid MatroskaExtractor::addTracks() {
705093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const mkvparser::Tracks *tracks = mSegment->GetTracks();
706093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
707093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    for (size_t index = 0; index < tracks->GetTracksCount(); ++index) {
708093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const mkvparser::Track *track = tracks->GetTrackByIndex(index);
709093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
710093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const char *const codecID = track->GetCodecId();
711093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        LOGV("codec id = %s", codecID);
712093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        LOGV("codec name = %s", track->GetCodecNameAsUTF8());
713093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
714093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        size_t codecPrivateSize;
715093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const unsigned char *codecPrivate =
716ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber            track->GetCodecPrivate(codecPrivateSize);
717093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
718093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 };
719093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
720093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        sp<MetaData> meta = new MetaData;
721093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
722093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        switch (track->GetType()) {
723093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            case VIDEO_TRACK:
724093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            {
725093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                const mkvparser::VideoTrack *vtrack =
726093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    static_cast<const mkvparser::VideoTrack *>(track);
727093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
728093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
729093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
730093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize);
731093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else if (!strcmp("V_VP8", codecID)) {
732093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX);
733093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else {
734093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    continue;
735093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                }
736093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
737093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyWidth, vtrack->GetWidth());
738093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyHeight, vtrack->GetHeight());
739093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                break;
740093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
741093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
742093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            case AUDIO_TRACK:
743093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            {
744093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                const mkvparser::AudioTrack *atrack =
745093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    static_cast<const mkvparser::AudioTrack *>(track);
746093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
747093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                if (!strcmp("A_AAC", codecID)) {
748093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
749093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    CHECK(codecPrivateSize >= 2);
750093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
751093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    addESDSFromAudioSpecificInfo(
752093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                            meta, codecPrivate, codecPrivateSize);
753093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else if (!strcmp("A_VORBIS", codecID)) {
754093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS);
755093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
756093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize);
757093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else {
758093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    continue;
759093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                }
760093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
761093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeySampleRate, atrack->GetSamplingRate());
762093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyChannelCount, atrack->GetChannels());
763093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                break;
764093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
765093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
766093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            default:
767093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                continue;
768093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
769093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
770093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        long long durationNs = mSegment->GetDuration();
771093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        meta->setInt64(kKeyDuration, (durationNs + 500) / 1000);
772093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
773093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mTracks.push();
774093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1);
775093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        trackInfo->mTrackNum = track->GetNumber();
776093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        trackInfo->mMeta = meta;
777093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
778093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
779093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
7805279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid MatroskaExtractor::findThumbnails() {
7815279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
7825279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        TrackInfo *info = &mTracks.editItemAt(i);
7835279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
7845279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        const char *mime;
7855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        CHECK(info->mMeta->findCString(kKeyMIMEType, &mime));
7865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
7875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        if (strncasecmp(mime, "video/", 6)) {
7885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            continue;
7895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        }
7905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
7915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        BlockIterator iter(mSegment, info->mTrackNum);
7925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        int32_t i = 0;
7935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        int64_t thumbnailTimeUs = 0;
7945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        size_t maxBlockSize = 0;
7955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        while (!iter.eos() && i < 20) {
7965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            if (iter.block()->IsKey()) {
7975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                ++i;
7985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
7995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                size_t blockSize = iter.block()->GetSize();
8005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                if (blockSize > maxBlockSize) {
8015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                    maxBlockSize = blockSize;
8025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                    thumbnailTimeUs = iter.blockTimeUs();
8035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                }
8045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            }
8055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            iter.advance();
8065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        }
8075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
8085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
8095279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
8105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
811093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getMetaData() {
812093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    sp<MetaData> meta = new MetaData;
813093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MATROSKA);
814093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
815093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return meta;
816093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
817093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
818093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberbool SniffMatroska(
8195a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
8205a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
821093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    DataSourceReader reader(source);
822093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mkvparser::EBMLHeader ebmlHeader;
823093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long pos;
824093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ebmlHeader.Parse(&reader, pos) < 0) {
825093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return false;
826093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
827093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
828093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA);
829093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    *confidence = 0.6;
830093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
831093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return true;
832093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
833093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
834093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}  // namespace android
835