MatroskaExtractor.cpp revision b10f3669a9b73cd024662c2b70f5155bc0c2cd21
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) {
61093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        off_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
121093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberprivate:
122093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    enum Type {
123093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        AVC,
124093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        AAC,
125093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        OTHER
126093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    };
127093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
128093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    sp<MatroskaExtractor> mExtractor;
129093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t mTrackIndex;
130093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    Type mType;
1315279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    BlockIterator mBlockIter;
132b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    size_t mNALSizeLen;  // for type AVC
133093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
134093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    status_t advance();
135093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
136093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    MatroskaSource(const MatroskaSource &);
137093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    MatroskaSource &operator=(const MatroskaSource &);
138093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber};
139093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
140093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaSource::MatroskaSource(
141093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MatroskaExtractor> &extractor, size_t index)
142093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    : mExtractor(extractor),
143093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mTrackIndex(index),
144093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mType(OTHER),
1455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mBlockIter(mExtractor->mSegment,
146b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                 mExtractor->mTracks.itemAt(index).mTrackNum),
147b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber      mNALSizeLen(0) {
148b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta;
149b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
150093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const char *mime;
151b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
152093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
153093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
154093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mType = AVC;
155b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
156b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        uint32_t dummy;
157b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        const uint8_t *avcc;
158b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        size_t avccSize;
159b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        CHECK(meta->findData(
160b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                    kKeyAVCC, &dummy, (const void **)&avcc, &avccSize));
161b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
162b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        CHECK_GE(avccSize, 5u);
163b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
164b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        mNALSizeLen = 1 + (avcc[4] & 3);
165b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        LOGV("mNALSizeLen = %d", mNALSizeLen);
166093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
167093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mType = AAC;
168093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
169093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
170093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
171093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::start(MetaData *params) {
1725279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mBlockIter.reset();
173093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
174093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
175093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
176093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
177093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::stop() {
178093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
179093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
180093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
181093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaSource::getFormat() {
182093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mExtractor->mTracks.itemAt(mTrackIndex).mMeta;
183093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
184093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
1855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber////////////////////////////////////////////////////////////////////////////////
1865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
1875279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas HuberBlockIterator::BlockIterator(
1885279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        mkvparser::Segment *segment, unsigned long trackNum)
1895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    : mSegment(segment),
1905279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mTrackNum(trackNum),
1915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mCluster(NULL),
1925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mBlockEntry(NULL) {
1935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    reset();
1945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
1955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
1965279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberbool BlockIterator::eos() const {
1975279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return mCluster == NULL || mCluster->EOS();
1985279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
1995279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::advance() {
2015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    while (!eos()) {
2025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        if (mBlockEntry != NULL) {
2035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            mBlockEntry = mCluster->GetNext(mBlockEntry);
2045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        } else if (mCluster != NULL) {
2055279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            mCluster = mSegment->GetNext(mCluster);
2065279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2075279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            if (eos()) {
2085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                break;
209093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
2105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
211093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            mBlockEntry = mCluster->GetFirst();
212093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
213093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
2145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        if (mBlockEntry != NULL
2155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                && mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) {
2165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            break;
217093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
2185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
2195279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2205279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2215279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::reset() {
2225279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mCluster = mSegment->GetFirst();
2235279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mBlockEntry = mCluster->GetFirst();
224093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
2255279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    while (!eos() && block()->GetTrackNumber() != mTrackNum) {
2265279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        advance();
227093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
2285279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
229093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
2305279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid BlockIterator::seek(int64_t seekTimeUs) {
231ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber    mCluster = mSegment->FindCluster(seekTimeUs * 1000ll);
2325279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mBlockEntry = mCluster != NULL ? mCluster->GetFirst() : NULL;
2335279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2345279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    while (!eos() && block()->GetTrackNumber() != mTrackNum) {
2355279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        advance();
2365279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
2375279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2385279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    while (!eos() && !mBlockEntry->GetBlock()->IsKey()) {
2395279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        advance();
2405279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
241093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
242093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
2435279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberconst mkvparser::Block *BlockIterator::block() const {
2445279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    CHECK(!eos());
2455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return mBlockEntry->GetBlock();
2475279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2485279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2495279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberint64_t BlockIterator::blockTimeUs() const {
2505279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll;
2515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
2525279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
2535279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber////////////////////////////////////////////////////////////////////////////////
2545279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
255b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huberstatic unsigned U24_AT(const uint8_t *ptr) {
256b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
257b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber}
258b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
259093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatus_t MatroskaSource::read(
260093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        MediaBuffer **out, const ReadOptions *options) {
261093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    *out = NULL;
262093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
263093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    int64_t seekTimeUs;
264abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
265abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
2665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        mBlockIter.seek(seekTimeUs);
267093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
268093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
269b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huberagain:
2705279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    if (mBlockIter.eos()) {
271093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return ERROR_END_OF_STREAM;
272093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
273093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
2745279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    const mkvparser::Block *block = mBlockIter.block();
275093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t size = block->GetSize();
2765279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    int64_t timeUs = mBlockIter.blockTimeUs();
277093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
278b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    // In the case of AVC content, each NAL unit is prefixed by
279b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    // mNALSizeLen bytes of length. We want to prefix the data with
280b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    // a four-byte 0x00000001 startcode instead of the length prefix.
281b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    // mNALSizeLen ranges from 1 through 4 bytes, so add an extra
282b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    // 3 bytes of padding to the buffer start.
283b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    static const size_t kPadding = 3;
284b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
285b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    MediaBuffer *buffer = new MediaBuffer(size + kPadding);
2865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    buffer->meta_data()->setInt64(kKeyTime, timeUs);
2878bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    buffer->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey());
288093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
289093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long res = block->Read(
290b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            mExtractor->mReader, (unsigned char *)buffer->data() + kPadding);
291093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
292093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (res != 0) {
293093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return ERROR_END_OF_STREAM;
294093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
295093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
296b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber    buffer->set_range(kPadding, size);
297093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
298093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (mType == AVC) {
299b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        CHECK_GE(size, mNALSizeLen);
300093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
301093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        uint8_t *data = (uint8_t *)buffer->data();
302093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
303b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        size_t NALsize;
304b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        switch (mNALSizeLen) {
305b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            case 1: NALsize = data[kPadding]; break;
306b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            case 2: NALsize = U16_AT(&data[kPadding]); break;
307b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            case 3: NALsize = U24_AT(&data[kPadding]); break;
308b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            case 4: NALsize = U32_AT(&data[kPadding]); break;
309b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            default:
310b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                TRESPASS();
311b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        }
312b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
313b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        CHECK_GE(size, NALsize + mNALSizeLen);
314b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        if (size > NALsize + mNALSizeLen) {
315b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            LOGW("discarding %d bytes of data.", size - NALsize - mNALSizeLen);
316b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        }
317b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
318b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        // actual data starts at &data[kPadding + mNALSizeLen]
319093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
320b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        memcpy(&data[mNALSizeLen - 1], "\x00\x00\x00\x01", 4);
321b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        buffer->set_range(mNALSizeLen - 1, NALsize + 4);
322093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    } else if (mType == AAC) {
323093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        // There's strange junk at the beginning...
324093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
325b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        const uint8_t *data = (const uint8_t *)buffer->data() + kPadding;
326b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
327b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        // hexdump(data, size);
328b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
329093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        size_t offset = 0;
330093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        while (offset < size && data[offset] != 0x21) {
331093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            ++offset;
332093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
333b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
334b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        if (size == offset) {
335b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            buffer->release();
336b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
337b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            mBlockIter.advance();
338b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            goto again;
339b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        }
340b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber
341b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        buffer->set_range(kPadding + offset, size - offset);
342093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
343093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
344093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    *out = buffer;
345093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
346093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#if 0
347093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    hexdump((const uint8_t *)buffer->data() + buffer->range_offset(),
348093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            buffer->range_length());
349093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#endif
350093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
3515279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    mBlockIter.advance();
352093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
353093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return OK;
354093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
355093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
356093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber////////////////////////////////////////////////////////////////////////////////
357093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
358093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source)
359093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    : mDataSource(source),
360093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber      mReader(new DataSourceReader(mDataSource)),
3615279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mSegment(NULL),
3625279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber      mExtractedThumbnails(false) {
363093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mkvparser::EBMLHeader ebmlHeader;
364093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long pos;
365093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ebmlHeader.Parse(mReader, pos) < 0) {
366093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
367093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
368093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
369093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long ret =
370093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mkvparser::Segment::CreateInstance(mReader, pos, mSegment);
371093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
372093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ret) {
373093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        CHECK(mSegment == NULL);
374093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
375093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
376093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
377093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    ret = mSegment->Load();
378093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
379093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ret < 0) {
380093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        delete mSegment;
381093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mSegment = NULL;
382093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return;
383093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
384093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
385093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    addTracks();
386093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
387093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
388093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberMatroskaExtractor::~MatroskaExtractor() {
389093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete mSegment;
390093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mSegment = NULL;
391093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
392093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete mReader;
393093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mReader = NULL;
394093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
395093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
396093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersize_t MatroskaExtractor::countTracks() {
397093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mTracks.size();
398093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
399093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
400093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MediaSource> MatroskaExtractor::getTrack(size_t index) {
401093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (index >= mTracks.size()) {
402093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return NULL;
403093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
404093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
405093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return new MatroskaSource(this, index);
406093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
407093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
408093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getTrackMetaData(
409093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        size_t index, uint32_t flags) {
410093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (index >= mTracks.size()) {
411093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return NULL;
412093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
413093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
4145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails) {
4155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        findThumbnails();
4165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        mExtractedThumbnails = true;
4175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
4185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
419093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return mTracks.itemAt(index).mMeta;
420093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
421093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
422093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic void addESDSFromAudioSpecificInfo(
423093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MetaData> &meta, const void *asi, size_t asiSize) {
424093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    static const uint8_t kStaticESDS[] = {
425093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x03, 22,
426093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00,     // ES_ID
427093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
428093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
429093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x04, 17,
430093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x40,                       // Audio ISO/IEC 14496-3
431093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
432093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
433093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x00, 0x00, 0x00, 0x00,
434093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
435093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        0x05,
436093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        // AudioSpecificInfo (with size prefix) follows
437093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    };
438093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
439093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(asiSize < 128);
440093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1;
441093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    uint8_t *esds = new uint8_t[esdsSize];
442093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    memcpy(esds, kStaticESDS, sizeof(kStaticESDS));
443093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    uint8_t *ptr = esds + sizeof(kStaticESDS);
444093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    *ptr++ = asiSize;
445093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    memcpy(ptr, asi, asiSize);
446093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
447093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(kKeyESDS, 0, esds, esdsSize);
448093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
449093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    delete[] esds;
450093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    esds = NULL;
451093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
452093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
453093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid addVorbisCodecInfo(
454093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const sp<MetaData> &meta,
455093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const void *_codecPrivate, size_t codecPrivateSize) {
456093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    // printf("vorbis private data follows:\n");
457093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    // hexdump(_codecPrivate, codecPrivateSize);
458093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
459093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivateSize >= 3);
460093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
461093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate;
462093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[0] == 0x02);
463093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
464093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t len1 = codecPrivate[1];
465093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    size_t len2 = codecPrivate[2];
466093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
467093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivateSize > 3 + len1 + len2);
468093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
469093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[3] == 0x01);
470093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(kKeyVorbisInfo, 0, &codecPrivate[3], len1);
471093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
472093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[len1 + 3] == 0x03);
473093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
474093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    CHECK(codecPrivate[len1 + len2 + 3] == 0x05);
475093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setData(
476093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            kKeyVorbisBooks, 0, &codecPrivate[len1 + len2 + 3],
477093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            codecPrivateSize - len1 - len2 - 3);
478093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
479093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
480093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubervoid MatroskaExtractor::addTracks() {
481093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const mkvparser::Tracks *tracks = mSegment->GetTracks();
482093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
483093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    for (size_t index = 0; index < tracks->GetTracksCount(); ++index) {
484093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const mkvparser::Track *track = tracks->GetTrackByIndex(index);
485093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
486093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const char *const codecID = track->GetCodecId();
487093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        LOGV("codec id = %s", codecID);
488093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        LOGV("codec name = %s", track->GetCodecNameAsUTF8());
489093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
490093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        size_t codecPrivateSize;
491093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        const unsigned char *codecPrivate =
492ff1df9951d09f1a1a8ae2dbc42b82b0f9c164e5eAndreas Huber            track->GetCodecPrivate(codecPrivateSize);
493093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
494093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 };
495093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
496093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        sp<MetaData> meta = new MetaData;
497093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
498093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        switch (track->GetType()) {
499093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            case VIDEO_TRACK:
500093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            {
501093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                const mkvparser::VideoTrack *vtrack =
502093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    static_cast<const mkvparser::VideoTrack *>(track);
503093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
504093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
505093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
506093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize);
507093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else if (!strcmp("V_VP8", codecID)) {
508093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VPX);
509093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else {
510093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    continue;
511093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                }
512093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
513093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyWidth, vtrack->GetWidth());
514093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyHeight, vtrack->GetHeight());
515093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                break;
516093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
517093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
518093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            case AUDIO_TRACK:
519093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            {
520093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                const mkvparser::AudioTrack *atrack =
521093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    static_cast<const mkvparser::AudioTrack *>(track);
522093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
523093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                if (!strcmp("A_AAC", codecID)) {
524093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
525093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    CHECK(codecPrivateSize >= 2);
526093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
527093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    addESDSFromAudioSpecificInfo(
528093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                            meta, codecPrivate, codecPrivateSize);
529093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else if (!strcmp("A_VORBIS", codecID)) {
530093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS);
531093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
532093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    addVorbisCodecInfo(meta, codecPrivate, codecPrivateSize);
533093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                } else {
534093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    continue;
535093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                }
536093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
537093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeySampleRate, atrack->GetSamplingRate());
538093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                meta->setInt32(kKeyChannelCount, atrack->GetChannels());
539093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                break;
540093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
541093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
542093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            default:
543093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                continue;
544093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
545093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
546093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        long long durationNs = mSegment->GetDuration();
547093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        meta->setInt64(kKeyDuration, (durationNs + 500) / 1000);
548093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
549093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        mTracks.push();
550093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        TrackInfo *trackInfo = &mTracks.editItemAt(mTracks.size() - 1);
551093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        trackInfo->mTrackNum = track->GetNumber();
552093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        trackInfo->mMeta = meta;
553093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
554093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
555093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
5565279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Hubervoid MatroskaExtractor::findThumbnails() {
5575279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
5585279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        TrackInfo *info = &mTracks.editItemAt(i);
5595279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
5605279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        const char *mime;
5615279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        CHECK(info->mMeta->findCString(kKeyMIMEType, &mime));
5625279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
5635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        if (strncasecmp(mime, "video/", 6)) {
5645279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            continue;
5655279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        }
5665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
5675279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        BlockIterator iter(mSegment, info->mTrackNum);
5685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        int32_t i = 0;
5695279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        int64_t thumbnailTimeUs = 0;
5705279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        size_t maxBlockSize = 0;
5715279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        while (!iter.eos() && i < 20) {
5725279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            if (iter.block()->IsKey()) {
5735279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                ++i;
5745279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
5755279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                size_t blockSize = iter.block()->GetSize();
5765279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                if (blockSize > maxBlockSize) {
5775279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                    maxBlockSize = blockSize;
5785279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                    thumbnailTimeUs = iter.blockTimeUs();
5795279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                }
5805279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            }
5815279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            iter.advance();
5825279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        }
5835279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        info->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
5845279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
5855279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber}
5865279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
587093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Hubersp<MetaData> MatroskaExtractor::getMetaData() {
588093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    sp<MetaData> meta = new MetaData;
589093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MATROSKA);
590093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
591093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return meta;
592093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
593093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
594093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberbool SniffMatroska(
5955a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
5965a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
597093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    DataSourceReader reader(source);
598093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mkvparser::EBMLHeader ebmlHeader;
599093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    long long pos;
600093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    if (ebmlHeader.Parse(&reader, pos) < 0) {
601093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        return false;
602093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
603093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
604093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MATROSKA);
605093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    *confidence = 0.6;
606093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
607093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return true;
608093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
609093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
610093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}  // namespace android
611