/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "MatroskaExtractor"
#include <utils/Log.h>

#include "FLACDecoder.h"
#include "MatroskaExtractor.h"
#include "common/webmids.h"

#include <media/stagefright/DataSourceBase.h>
#include <media/ExtractorUtils.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ByteUtils.h>
#include <media/stagefright/foundation/ColorUtils.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaDataUtils.h>
#include <media/stagefright/foundation/avc_utils.h>
#include <utils/String8.h>

#include <arpa/inet.h>
#include <inttypes.h>
#include <vector>

namespace android {

struct DataSourceBaseReader : public mkvparser::IMkvReader {
    explicit DataSourceBaseReader(DataSourceHelper *source)
        : mSource(source) {
    }

    virtual int Read(long long position, long length, unsigned char* buffer) {
        CHECK(position >= 0);
        CHECK(length >= 0);

        if (length == 0) {
            return 0;
        }

        ssize_t n = mSource->readAt(position, buffer, length);

        if (n <= 0) {
            return -1;
        }

        return 0;
    }

    virtual int Length(long long* total, long long* available) {
        off64_t size;
        if (mSource->getSize(&size) != OK) {
            if (total) {
                *total = -1;
            }
            if (available) {
                *available = (long long)((1ull << 63) - 1);
            }

            return 0;
        }

        if (total) {
            *total = size;
        }

        if (available) {
            *available = size;
        }

        return 0;
    }

private:
    DataSourceHelper *mSource;

    DataSourceBaseReader(const DataSourceBaseReader &);
    DataSourceBaseReader &operator=(const DataSourceBaseReader &);
};

////////////////////////////////////////////////////////////////////////////////

struct BlockIterator {
    BlockIterator(MatroskaExtractor *extractor, unsigned long trackNum, unsigned long index);

    bool eos() const;

    void advance();
    void reset();

    void seek(
            int64_t seekTimeUs, bool isAudio,
            int64_t *actualFrameTimeUs);

    const mkvparser::Block *block() const;
    int64_t blockTimeUs() const;

private:
    MatroskaExtractor *mExtractor;
    long long mTrackNum;
    unsigned long mIndex;

    const mkvparser::Cluster *mCluster;
    const mkvparser::BlockEntry *mBlockEntry;
    long mBlockEntryIndex;

    unsigned long mTrackType;
    void seekwithoutcue_l(int64_t seekTimeUs, int64_t *actualFrameTimeUs);

    void advance_l();

    BlockIterator(const BlockIterator &);
    BlockIterator &operator=(const BlockIterator &);
};

struct MatroskaSource : public MediaTrackHelper {
    MatroskaSource(MatroskaExtractor *extractor, size_t index);

    virtual media_status_t start();
    virtual media_status_t stop();

    virtual media_status_t getFormat(AMediaFormat *);

    virtual media_status_t read(
            MediaBufferHelper **buffer, const ReadOptions *options);

protected:
    virtual ~MatroskaSource();

private:
    enum Type {
        AVC,
        AAC,
        HEVC,
        MP3,
        PCM,
        VORBIS,
        OTHER
    };

    MatroskaExtractor *mExtractor;
    size_t mTrackIndex;
    Type mType;
    bool mIsAudio;
    BlockIterator mBlockIter;
    ssize_t mNALSizeLen;  // for type AVC or HEVC

    List<MediaBufferHelper *> mPendingFrames;

    int64_t mCurrentTS; // add for mp3
    uint32_t mMP3Header;

    media_status_t findMP3Header(uint32_t * header,
        const uint8_t *dataSource, int length, int *outStartPos);
    media_status_t mp3FrameRead(
            MediaBufferHelper **out, const ReadOptions *options,
            int64_t targetSampleTimeUs);

    status_t advance();

    status_t setWebmBlockCryptoInfo(MediaBufferHelper *mbuf);
    media_status_t readBlock();
    void clearPendingFrames();

    MatroskaSource(const MatroskaSource &);
    MatroskaSource &operator=(const MatroskaSource &);
};

const mkvparser::Track* MatroskaExtractor::TrackInfo::getTrack() const {
    return mExtractor->mSegment->GetTracks()->GetTrackByNumber(mTrackNum);
}

// This function does exactly the same as mkvparser::Cues::Find, except that it
// searches in our own track based vectors. We should not need this once mkvparser
// adds the same functionality.
const mkvparser::CuePoint::TrackPosition *MatroskaExtractor::TrackInfo::find(
        long long timeNs) const {
    ALOGV("mCuePoints.size %zu", mCuePoints.size());
    if (mCuePoints.empty()) {
        return NULL;
    }

    const mkvparser::CuePoint* cp = mCuePoints.itemAt(0);
    const mkvparser::Track* track = getTrack();
    if (timeNs <= cp->GetTime(mExtractor->mSegment)) {
        return cp->Find(track);
    }

    // Binary searches through relevant cues; assumes cues are ordered by timecode.
    // If we do detect out-of-order cues, return NULL.
    size_t lo = 0;
    size_t hi = mCuePoints.size();
    while (lo < hi) {
        const size_t mid = lo + (hi - lo) / 2;
        const mkvparser::CuePoint* const midCp = mCuePoints.itemAt(mid);
        const long long cueTimeNs = midCp->GetTime(mExtractor->mSegment);
        if (cueTimeNs <= timeNs) {
            lo = mid + 1;
        } else {
            hi = mid;
        }
    }

    if (lo == 0) {
        return NULL;
    }

    cp = mCuePoints.itemAt(lo - 1);
    if (cp->GetTime(mExtractor->mSegment) > timeNs) {
        return NULL;
    }

    return cp->Find(track);
}

MatroskaSource::MatroskaSource(
        MatroskaExtractor *extractor, size_t index)
    : mExtractor(extractor),
      mTrackIndex(index),
      mType(OTHER),
      mIsAudio(false),
      mBlockIter(mExtractor,
                 mExtractor->mTracks.itemAt(index).mTrackNum,
                 index),
      mNALSizeLen(-1),
      mCurrentTS(0),
      mMP3Header(0) {
    MatroskaExtractor::TrackInfo &trackInfo = mExtractor->mTracks.editItemAt(index);
    AMediaFormat *meta = trackInfo.mMeta;

    const char *mime;
    CHECK(AMediaFormat_getString(meta, AMEDIAFORMAT_KEY_MIME, &mime));

    mIsAudio = !strncasecmp("audio/", mime, 6);

    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
        mType = AVC;

        int32_t nalSizeLen = trackInfo.mNalLengthSize;
        if (nalSizeLen >= 0 && nalSizeLen <= 4) {
            mNALSizeLen = nalSizeLen;
        } else {
            ALOGE("No AVC mNALSizeLen");
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
        mType = HEVC;

        int32_t nalSizeLen = trackInfo.mNalLengthSize;
        if (nalSizeLen >= 0 && nalSizeLen <= 4) {
            mNALSizeLen = nalSizeLen;
        } else {
            ALOGE("No HEVC mNALSizeLen");
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
        mType = AAC;
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
        mType = MP3;
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
        mType = PCM;
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
        mType = VORBIS;
    }
}

MatroskaSource::~MatroskaSource() {
    clearPendingFrames();
}

media_status_t MatroskaSource::start() {
    if (mType == AVC && mNALSizeLen < 0) {
        return AMEDIA_ERROR_MALFORMED;
    }

    // allocate one small initial buffer, but leave plenty of room to grow
    mBufferGroup->init(1 /* number of buffers */, 1024 /* buffer size */, 64 /* growth limit */);
    mBlockIter.reset();

    if (mType == MP3 && mMP3Header == 0) {
        int start = -1;
        media_status_t err = findMP3Header(&mMP3Header, NULL, 0, &start);
        if (err != OK) {
            ALOGE("No mp3 header found");
            clearPendingFrames();
            return err;
        }
    }

    return AMEDIA_OK;
}

media_status_t MatroskaSource::stop() {
    clearPendingFrames();

    return AMEDIA_OK;
}

media_status_t MatroskaSource::getFormat(AMediaFormat *meta) {
    return AMediaFormat_copy(meta, mExtractor->mTracks.itemAt(mTrackIndex).mMeta);
}

////////////////////////////////////////////////////////////////////////////////

BlockIterator::BlockIterator(
        MatroskaExtractor *extractor, unsigned long trackNum, unsigned long index)
    : mExtractor(extractor),
      mTrackNum(trackNum),
      mIndex(index),
      mCluster(NULL),
      mBlockEntry(NULL),
      mBlockEntryIndex(0) {
    mTrackType = mExtractor->mSegment->GetTracks()->GetTrackByNumber(trackNum)->GetType();
    reset();
}

bool BlockIterator::eos() const {
    return mCluster == NULL || mCluster->EOS();
}

void BlockIterator::advance() {
    Mutex::Autolock autoLock(mExtractor->mLock);
    advance_l();
}

void BlockIterator::advance_l() {
    for (int i = 0;; i++) {
        if (i == 1000) {
            ALOGE("no block found after %d iterations, stopping", i);
            mCluster = NULL;
            break;
        }
        long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry);
        ALOGV("GetEntry returned %ld", res);

        long long pos;
        long len;
        if (res < 0) {
            // Need to parse this cluster some more

            CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL);

            res = mCluster->Parse(pos, len);
            ALOGV("Parse returned %ld", res);

            if (res < 0) {
                // I/O error

                ALOGE("Cluster::Parse returned result %ld", res);

                mCluster = NULL;
                break;
            }

            continue;
        } else if (res == 0) {
            // We're done with this cluster

            const mkvparser::Cluster *nextCluster;
            res = mExtractor->mSegment->ParseNext(
                    mCluster, nextCluster, pos, len);
            ALOGV("ParseNext returned %ld", res);

            if (res != 0) {
                // EOF or error

                mCluster = NULL;
                break;
            }

            CHECK_EQ(res, 0);
            CHECK(nextCluster != NULL);
            CHECK(!nextCluster->EOS());

            mCluster = nextCluster;

            res = mCluster->Parse(pos, len);
            ALOGV("Parse (2) returned %ld", res);

            if (res < 0) {
                // I/O error

                ALOGE("Cluster::Parse returned result %ld", res);

                mCluster = NULL;
                break;
            }

            mBlockEntryIndex = 0;
            continue;
        }

        CHECK(mBlockEntry != NULL);
        CHECK(mBlockEntry->GetBlock() != NULL);
        ++mBlockEntryIndex;

        if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) {
            break;
        }
    }
}

void BlockIterator::reset() {
    Mutex::Autolock autoLock(mExtractor->mLock);

    mCluster = mExtractor->mSegment->GetFirst();
    mBlockEntry = NULL;
    mBlockEntryIndex = 0;

    do {
        advance_l();
    } while (!eos() && block()->GetTrackNumber() != mTrackNum);
}

void BlockIterator::seek(
        int64_t seekTimeUs, bool isAudio,
        int64_t *actualFrameTimeUs) {
    Mutex::Autolock autoLock(mExtractor->mLock);

    *actualFrameTimeUs = -1ll;

    if (seekTimeUs > INT64_MAX / 1000ll ||
            seekTimeUs < INT64_MIN / 1000ll ||
            (mExtractor->mSeekPreRollNs > 0 &&
                    (seekTimeUs * 1000ll) < INT64_MIN + mExtractor->mSeekPreRollNs) ||
            (mExtractor->mSeekPreRollNs < 0 &&
                    (seekTimeUs * 1000ll) > INT64_MAX + mExtractor->mSeekPreRollNs)) {
        ALOGE("cannot seek to %lld", (long long) seekTimeUs);
        return;
    }

    const int64_t seekTimeNs = seekTimeUs * 1000ll - mExtractor->mSeekPreRollNs;

    mkvparser::Segment* const pSegment = mExtractor->mSegment;

    // Special case the 0 seek to avoid loading Cues when the application
    // extraneously seeks to 0 before playing.
    if (seekTimeNs <= 0) {
        ALOGV("Seek to beginning: %" PRId64, seekTimeUs);
        mCluster = pSegment->GetFirst();
        mBlockEntryIndex = 0;
        do {
            advance_l();
        } while (!eos() && block()->GetTrackNumber() != mTrackNum);
        return;
    }

    ALOGV("Seeking to: %" PRId64, seekTimeUs);

    // If the Cues have not been located then find them.
    const mkvparser::Cues* pCues = pSegment->GetCues();
    const mkvparser::SeekHead* pSH = pSegment->GetSeekHead();
    if (!pCues && pSH) {
        const size_t count = pSH->GetCount();
        const mkvparser::SeekHead::Entry* pEntry;
        ALOGV("No Cues yet");

        for (size_t index = 0; index < count; index++) {
            pEntry = pSH->GetEntry(index);

            if (pEntry->id == libwebm::kMkvCues) { // Cues ID
                long len; long long pos;
                pSegment->ParseCues(pEntry->pos, pos, len);
                pCues = pSegment->GetCues();
                ALOGV("Cues found");
                break;
            }
        }

        if (!pCues) {
            ALOGV("No Cues in file,seek without cue data");
            seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
            return;
        }
    }
    else if (!pSH) {
        ALOGV("No SeekHead, seek without cue data");
        seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
        return;
    }

    const mkvparser::CuePoint* pCP;
    mkvparser::Tracks const *pTracks = pSegment->GetTracks();
    while (!pCues->DoneParsing()) {
        pCues->LoadCuePoint();
        pCP = pCues->GetLast();
        ALOGV("pCP = %s", pCP == NULL ? "NULL" : "not NULL");
        if (pCP == NULL)
            continue;

        size_t trackCount = mExtractor->mTracks.size();
        for (size_t index = 0; index < trackCount; ++index) {
            MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(index);
            const mkvparser::Track *pTrack = pTracks->GetTrackByNumber(track.mTrackNum);
            if (pTrack && pTrack->GetType() == 1 && pCP->Find(pTrack)) { // VIDEO_TRACK
                track.mCuePoints.push_back(pCP);
            }
        }

        if (pCP->GetTime(pSegment) >= seekTimeNs) {
            ALOGV("Parsed past relevant Cue");
            break;
        }
    }

    const mkvparser::CuePoint::TrackPosition *pTP = NULL;
    const mkvparser::Track *thisTrack = pTracks->GetTrackByNumber(mTrackNum);
    if (thisTrack->GetType() == 1) { // video
        MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(mIndex);
        pTP = track.find(seekTimeNs);
    } else {
        // The Cue index is built around video keyframes
        unsigned long int trackCount = pTracks->GetTracksCount();
        for (size_t index = 0; index < trackCount; ++index) {
            const mkvparser::Track *pTrack = pTracks->GetTrackByIndex(index);
            if (pTrack && pTrack->GetType() == 1 && pCues->Find(seekTimeNs, pTrack, pCP, pTP)) {
                ALOGV("Video track located at %zu", index);
                break;
            }
        }
    }


    // Always *search* based on the video track, but finalize based on mTrackNum
    if (!pTP) {
        ALOGE("Did not locate the video track for seeking");
        seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
        return;
    }

    mCluster = pSegment->FindOrPreloadCluster(pTP->m_pos);

    CHECK(mCluster);
    CHECK(!mCluster->EOS());

    // mBlockEntryIndex starts at 0 but m_block starts at 1
    CHECK_GT(pTP->m_block, 0);
    mBlockEntryIndex = pTP->m_block - 1;

    for (;;) {
        advance_l();

        if (eos()) break;

        if (isAudio || block()->IsKey()) {
            // Accept the first key frame
            int64_t frameTimeUs = (block()->GetTime(mCluster) + 500LL) / 1000LL;
            if (thisTrack->GetType() == 1 || frameTimeUs >= seekTimeUs) {
                *actualFrameTimeUs = frameTimeUs;
                ALOGV("Requested seek point: %" PRId64 " actual: %" PRId64,
                      seekTimeUs, *actualFrameTimeUs);
                break;
            }
        }
    }
}

const mkvparser::Block *BlockIterator::block() const {
    CHECK(!eos());

    return mBlockEntry->GetBlock();
}

int64_t BlockIterator::blockTimeUs() const {
    if (mCluster == NULL || mBlockEntry == NULL) {
        return -1;
    }
    return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll;
}

void BlockIterator::seekwithoutcue_l(int64_t seekTimeUs, int64_t *actualFrameTimeUs) {
    mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll);
    const long status = mCluster->GetFirst(mBlockEntry);
    if (status < 0) {  // error
        ALOGE("get last blockenry failed!");
        mCluster = NULL;
        return;
    }
    mBlockEntryIndex = 0;
    while (!eos() && ((block()->GetTrackNumber() != mTrackNum) || (blockTimeUs() < seekTimeUs))) {
        advance_l();
    }

    // video track will seek to the next key frame.
    if (mTrackType == 1) {
        while (!eos() && ((block()->GetTrackNumber() != mTrackNum) ||
                      !mBlockEntry->GetBlock()->IsKey())) {
            advance_l();
        }
    }
    *actualFrameTimeUs = blockTimeUs();
     ALOGV("seekTimeUs:%lld, actualFrameTimeUs:%lld, tracknum:%lld",
              (long long)seekTimeUs, (long long)*actualFrameTimeUs, (long long)mTrackNum);
}

////////////////////////////////////////////////////////////////////////////////

static unsigned U24_AT(const uint8_t *ptr) {
    return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
}

static AString uriDebugString(const char *uri) {
    // find scheme
    AString scheme;
    for (size_t i = 0; i < strlen(uri); i++) {
        const char c = uri[i];
        if (!isascii(c)) {
            break;
        } else if (isalpha(c)) {
            continue;
        } else if (i == 0) {
            // first character must be a letter
            break;
        } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
            continue;
        } else if (c != ':') {
            break;
        }
        scheme = AString(uri, 0, i);
        scheme.append("://<suppressed>");
        return scheme;
    }
    return AString("<no-scheme URI suppressed>");
}

void MatroskaSource::clearPendingFrames() {
    while (!mPendingFrames.empty()) {
        MediaBufferHelper *frame = *mPendingFrames.begin();
        mPendingFrames.erase(mPendingFrames.begin());

        frame->release();
        frame = NULL;
    }
}

status_t MatroskaSource::setWebmBlockCryptoInfo(MediaBufferHelper *mbuf) {
    if (mbuf->range_length() < 1 || mbuf->range_length() - 1 > INT32_MAX) {
        // 1-byte signal
        return ERROR_MALFORMED;
    }

    const uint8_t *data = (const uint8_t *)mbuf->data() + mbuf->range_offset();
    bool encrypted = data[0] & 0x1;
    bool partitioned = data[0] & 0x2;
    if (encrypted && mbuf->range_length() < 9) {
        // 1-byte signal + 8-byte IV
        return ERROR_MALFORMED;
    }

    AMediaFormat *meta = mbuf->meta_data();
    if (encrypted) {
        uint8_t ctrCounter[16] = { 0 };
        const uint8_t *keyId;
        size_t keyIdSize;
        AMediaFormat *trackMeta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta;
        AMediaFormat_getBuffer(trackMeta, AMEDIAFORMAT_KEY_CRYPTO_KEY,
                (void**)&keyId, &keyIdSize);
        AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_KEY, keyId, keyIdSize);
        memcpy(ctrCounter, data + 1, 8);
        AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_IV, ctrCounter, 16);
        if (partitioned) {
            /*  0                   1                   2                   3
             *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
             * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             * |  Signal Byte  |                                               |
             * +-+-+-+-+-+-+-+-+             IV                                |
             * |                                                               |
             * |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             * |               | num_partition |     Partition 0 offset ->     |
             * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
             * |     -> Partition 0 offset     |              ...              |
             * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
             * |             ...               |     Partition n-1 offset ->   |
             * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
             * |     -> Partition n-1 offset   |                               |
             * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
             * |                    Clear/encrypted sample data                |
             * |                                                               |
             * |                                                               |
             * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             */
            if (mbuf->range_length() < 10) {
                return ERROR_MALFORMED;
            }
            uint8_t numPartitions = data[9];
            if (mbuf->range_length() - 10 < numPartitions * sizeof(uint32_t)) {
                return ERROR_MALFORMED;
            }
            std::vector<uint32_t> plainSizes, encryptedSizes;
            uint32_t prev = 0;
            uint32_t frameOffset = 10 + numPartitions * sizeof(uint32_t);
            const uint32_t *partitions = reinterpret_cast<const uint32_t*>(data + 10);
            for (uint32_t i = 0; i <= numPartitions; ++i) {
                uint32_t p_i = i < numPartitions
                        ? ntohl(partitions[i])
                        : (mbuf->range_length() - frameOffset);
                if (p_i < prev) {
                    return ERROR_MALFORMED;
                }
                uint32_t size = p_i - prev;
                prev = p_i;
                if (i % 2) {
                    encryptedSizes.push_back(size);
                } else {
                    plainSizes.push_back(size);
                }
            }
            if (plainSizes.size() > encryptedSizes.size()) {
                encryptedSizes.push_back(0);
            }
            uint32_t sizeofPlainSizes = sizeof(uint32_t) * plainSizes.size();
            uint32_t sizeofEncryptedSizes = sizeof(uint32_t) * encryptedSizes.size();
            AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
                    plainSizes.data(), sizeofPlainSizes);
            AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
                    encryptedSizes.data(), sizeofEncryptedSizes);
            mbuf->set_range(frameOffset, mbuf->range_length() - frameOffset);
        } else {
            /*
             *  0                   1                   2                   3
             *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
             *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             *  |  Signal Byte  |                                               |
             *  +-+-+-+-+-+-+-+-+             IV                                |
             *  |                                                               |
             *  |               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             *  |               |                                               |
             *  |-+-+-+-+-+-+-+-+                                               |
             *  :               Bytes 1..N of encrypted frame                   :
             *  |                                                               |
             *  |                                                               |
             *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             */
            int32_t plainSizes[] = { 0 };
            int32_t encryptedSizes[] = { static_cast<int32_t>(mbuf->range_length() - 9) };
            AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
                    plainSizes, sizeof(plainSizes));
            AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
                    encryptedSizes, sizeof(encryptedSizes));
            mbuf->set_range(9, mbuf->range_length() - 9);
        }
    } else {
        /*
         *  0                   1                   2                   3
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         *  |  Signal Byte  |                                               |
         *  +-+-+-+-+-+-+-+-+                                               |
         *  :               Bytes 1..N of unencrypted frame                 :
         *  |                                                               |
         *  |                                                               |
         *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        int32_t plainSizes[] = { static_cast<int32_t>(mbuf->range_length() - 1) };
        int32_t encryptedSizes[] = { 0 };
        AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
                plainSizes, sizeof(plainSizes));
        AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
                encryptedSizes, sizeof(encryptedSizes));
        mbuf->set_range(1, mbuf->range_length() - 1);
    }

    return OK;
}

media_status_t MatroskaSource::readBlock() {
    CHECK(mPendingFrames.empty());

    if (mBlockIter.eos()) {
        return AMEDIA_ERROR_END_OF_STREAM;
    }

    const mkvparser::Block *block = mBlockIter.block();

    int64_t timeUs = mBlockIter.blockTimeUs();

    for (int i = 0; i < block->GetFrameCount(); ++i) {
        MatroskaExtractor::TrackInfo *trackInfo = &mExtractor->mTracks.editItemAt(mTrackIndex);
        const mkvparser::Block::Frame &frame = block->GetFrame(i);
        size_t len = frame.len;
        if (SIZE_MAX - len < trackInfo->mHeaderLen) {
            return AMEDIA_ERROR_MALFORMED;
        }

        len += trackInfo->mHeaderLen;
        MediaBufferHelper *mbuf;
        mBufferGroup->acquire_buffer(&mbuf, false /* nonblocking */, len /* requested size */);
        mbuf->set_range(0, len);
        uint8_t *data = static_cast<uint8_t *>(mbuf->data());
        if (trackInfo->mHeader) {
            memcpy(data, trackInfo->mHeader, trackInfo->mHeaderLen);
        }

        AMediaFormat *meta = mbuf->meta_data();
        AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
        AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, block->IsKey());

        if (mType == VORBIS) {
            int32_t sampleRate;
            if (!AMediaFormat_getInt32(trackInfo->mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE,
                                       &sampleRate)) {
                mbuf->release();
                return AMEDIA_ERROR_MALFORMED;
            }
            int64_t durationUs;
            if (!AMediaFormat_getInt64(trackInfo->mMeta, AMEDIAFORMAT_KEY_DURATION,
                                       &durationUs)) {
                mbuf->release();
                return AMEDIA_ERROR_MALFORMED;
            }
            // TODO: Explore if this can be handled similar to MPEG4 extractor where padding is
            // signalled instead of VALID_SAMPLES
            // Remaining valid samples in Vorbis track
            if (durationUs > timeUs) {
                int32_t validSamples = ((durationUs - timeUs) * sampleRate) / 1000000ll;
                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, validSamples);
            }
        }

        status_t err = frame.Read(mExtractor->mReader, data + trackInfo->mHeaderLen);
        if (err == OK
                && mExtractor->mIsWebm
                && trackInfo->mEncrypted) {
            err = setWebmBlockCryptoInfo(mbuf);
        }

        if (err != OK) {
            clearPendingFrames();

            mBlockIter.advance();
            mbuf->release();
            return AMEDIA_ERROR_UNKNOWN;
        }

        mPendingFrames.push_back(mbuf);
    }

    mBlockIter.advance();

    return AMEDIA_OK;
}

//the value of kMP3HeaderMask is from MP3Extractor
static const uint32_t kMP3HeaderMask = 0xfffe0c00;

media_status_t MatroskaSource::findMP3Header(uint32_t * header,
        const uint8_t *dataSource, int length, int *outStartPos) {
    if (NULL == header) {
        ALOGE("header is null!");
        return AMEDIA_ERROR_END_OF_STREAM;
    }

    //to find header start position
    if (0 != *header) {
        if (NULL == dataSource) {
            *outStartPos = -1;
            return AMEDIA_OK;
        }
        uint32_t tmpCode = 0;
        for (int i = 0; i < length; i++) {
            tmpCode = (tmpCode << 8) + dataSource[i];
            if ((tmpCode & kMP3HeaderMask) == (*header & kMP3HeaderMask)) {
                *outStartPos = i - 3;
                return AMEDIA_OK;
            }
        }
        *outStartPos = -1;
        return AMEDIA_OK;
    }

    //to find mp3 header
    uint32_t code = 0;
    while (0 == *header) {
        while (mPendingFrames.empty()) {
            media_status_t err = readBlock();
            if (err != OK) {
                clearPendingFrames();
                return err;
            }
        }
        MediaBufferHelper *frame = *mPendingFrames.begin();
        size_t size = frame->range_length();
        size_t offset = frame->range_offset();
        size_t i;
        size_t frame_size;
        for (i = 0; i < size; i++) {
            ALOGV("data[%zu]=%x", i, *((uint8_t*)frame->data() + offset + i));
            code = (code << 8) + *((uint8_t*)frame->data() + offset + i);
            if (GetMPEGAudioFrameSize(code, &frame_size, NULL, NULL, NULL)) {
                *header = code;
                mBlockIter.reset();
                clearPendingFrames();
                return AMEDIA_OK;
            }
        }
    }

    return AMEDIA_ERROR_END_OF_STREAM;
}

media_status_t MatroskaSource::mp3FrameRead(
        MediaBufferHelper **out, const ReadOptions *options,
        int64_t targetSampleTimeUs) {
    MediaBufferHelper *frame = *mPendingFrames.begin();
    int64_t seekTimeUs;
    ReadOptions::SeekMode mode;
    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
        CHECK(AMediaFormat_getInt64(frame->meta_data(),
                    AMEDIAFORMAT_KEY_TIME_US, &mCurrentTS));
        if (mCurrentTS < 0) {
            mCurrentTS = 0;
            AMediaFormat_setInt64(frame->meta_data(),
                    AMEDIAFORMAT_KEY_TIME_US, mCurrentTS);
        }
    }

    int32_t start = -1;
    while (start < 0) {
        //find header start position
        findMP3Header(&mMP3Header,
            (const uint8_t*)frame->data() + frame->range_offset(),
            frame->range_length(), &start);
        ALOGV("start=%d, frame->range_length() = %zu, frame->range_offset() =%zu",
                      start, frame->range_length(), frame->range_offset());
        if (start >= 0)
            break;
        frame->release();
        mPendingFrames.erase(mPendingFrames.begin());
        while (mPendingFrames.empty()) {
            media_status_t err = readBlock();
            if (err != OK) {
                clearPendingFrames();
                return err;
            }
        }
        frame = *mPendingFrames.begin();
    }

    frame->set_range(frame->range_offset() + start, frame->range_length() - start);

    uint32_t header = *(uint32_t*)((uint8_t*)frame->data() + frame->range_offset());
    header = ((header >> 24) & 0xff) | ((header >> 8) & 0xff00) |
                    ((header << 8) & 0xff0000) | ((header << 24) & 0xff000000);
    size_t frame_size;
    int out_sampling_rate;
    int out_channels;
    int out_bitrate;
    if (!GetMPEGAudioFrameSize(header, &frame_size,
                               &out_sampling_rate, &out_channels, &out_bitrate)) {
        ALOGE("MP3 Header read fail!!");
        return AMEDIA_ERROR_UNSUPPORTED;
    }

    MediaBufferHelper *buffer;
    mBufferGroup->acquire_buffer(&buffer, false /* nonblocking */, frame_size /* requested size */);
    buffer->set_range(0, frame_size);

    uint8_t *data = static_cast<uint8_t *>(buffer->data());
    ALOGV("MP3 frame %zu frame->range_length() %zu", frame_size, frame->range_length());

    if (frame_size > frame->range_length()) {
        memcpy(data, (uint8_t*)(frame->data()) + frame->range_offset(), frame->range_length());
        size_t sumSize = 0;
        sumSize += frame->range_length();
        size_t needSize = frame_size - frame->range_length();
        frame->release();
        mPendingFrames.erase(mPendingFrames.begin());
        while (mPendingFrames.empty()) {
            media_status_t err = readBlock();
            if (err != OK) {
                buffer->release();
                clearPendingFrames();
                return err;
            }
        }
        frame = *mPendingFrames.begin();
        size_t offset = frame->range_offset();
        size_t size = frame->range_length();

        // the next buffer frame is not enough to fullfill mp3 frame,
        // we have to read until mp3 frame is completed.
        while (size < needSize) {
            memcpy(data + sumSize, (uint8_t*)(frame->data()) + offset, size);
            needSize -= size;
            sumSize += size;
            frame->release();
            mPendingFrames.erase(mPendingFrames.begin());
            while (mPendingFrames.empty()) {
                media_status_t err = readBlock();
                if (err != OK) {
                    buffer->release();
                    clearPendingFrames();
                    return err;
                }
            }
            frame = *mPendingFrames.begin();
            offset = frame->range_offset();
            size = frame->range_length();
        }
        memcpy(data + sumSize, (uint8_t*)(frame->data()) + offset, needSize);
        frame->set_range(offset + needSize, size - needSize);
     } else {
        size_t offset = frame->range_offset();
        size_t size = frame->range_length();
        memcpy(data, (uint8_t*)(frame->data()) + offset, frame_size);
        frame->set_range(offset + frame_size, size - frame_size);
    }
    if (frame->range_length() < 4) {
        frame->release();
        frame = NULL;
        mPendingFrames.erase(mPendingFrames.begin());
    }
    ALOGV("MatroskaSource::read MP3 frame kKeyTime=%lld,kKeyTargetTime=%lld",
                    (long long)mCurrentTS, (long long)targetSampleTimeUs);
    AMediaFormat_setInt64(buffer->meta_data(),
            AMEDIAFORMAT_KEY_TIME_US, mCurrentTS);
    mCurrentTS += (int64_t)frame_size * 8000ll / out_bitrate;

    if (targetSampleTimeUs >= 0ll)
        AMediaFormat_setInt64(buffer->meta_data(),
                AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
    *out = buffer;
    ALOGV("MatroskaSource::read MP3, keyTime=%lld for next frame", (long long)mCurrentTS);
    return AMEDIA_OK;
}

media_status_t MatroskaSource::read(
        MediaBufferHelper **out, const ReadOptions *options) {
    *out = NULL;

    int64_t targetSampleTimeUs = -1ll;

    int64_t seekTimeUs;
    ReadOptions::SeekMode mode;
    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
        if (mode == ReadOptions::SEEK_FRAME_INDEX) {
            return AMEDIA_ERROR_UNSUPPORTED;
        }

        if (!mExtractor->isLiveStreaming()) {
            clearPendingFrames();

            // The audio we want is located by using the Cues to seek the video
            // stream to find the target Cluster then iterating to finalize for
            // audio.
            int64_t actualFrameTimeUs;
            mBlockIter.seek(seekTimeUs, mIsAudio, &actualFrameTimeUs);
            if (mode == ReadOptions::SEEK_CLOSEST) {
                targetSampleTimeUs = actualFrameTimeUs;
            }
        }
    }

    while (mPendingFrames.empty()) {
        media_status_t err = readBlock();

        if (err != OK) {
            clearPendingFrames();

            return err;
        }
    }

    if (mType == MP3) {
        return mp3FrameRead(out, options, targetSampleTimeUs);
    }

    MediaBufferHelper *frame = *mPendingFrames.begin();
    mPendingFrames.erase(mPendingFrames.begin());

    if ((mType != AVC && mType != HEVC) || mNALSizeLen == 0) {
        if (targetSampleTimeUs >= 0ll) {
            AMediaFormat_setInt64(frame->meta_data(),
                    AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
        }

        if (mType == PCM) {
            int32_t bitPerFrame = 16;
            int32_t bigEndian = 0;
            AMediaFormat *meta = AMediaFormat_new();
            if (getFormat(meta) == AMEDIA_OK && meta != NULL) {
                AMediaFormat_getInt32(meta,
                                AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, &bitPerFrame);
                AMediaFormat_getInt32(meta,
                                AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN, &bigEndian);
            }
            AMediaFormat_delete(meta);
            if (bigEndian == 1 && bitPerFrame == 16) {
                // Big-endian -> little-endian
                uint16_t *dstData = (uint16_t *)frame->data() + frame->range_offset();
                uint16_t *srcData = (uint16_t *)frame->data() + frame->range_offset();
                for (size_t i = 0; i < frame->range_length() / 2; i++) {
                    dstData[i] = ntohs(srcData[i]);
                }
            }
        }

        *out = frame;

        return AMEDIA_OK;
    }

    // Each input frame contains one or more NAL fragments, each fragment
    // is prefixed by mNALSizeLen bytes giving the fragment length,
    // followed by a corresponding number of bytes containing the fragment.
    // We output all these fragments into a single large buffer separated
    // by startcodes (0x00 0x00 0x00 0x01).
    //
    // When mNALSizeLen is 0, we assume the data is already in the format
    // desired.

    const uint8_t *srcPtr =
        (const uint8_t *)frame->data() + frame->range_offset();

    size_t srcSize = frame->range_length();

    size_t dstSize = 0;
    MediaBufferHelper *buffer = NULL;
    uint8_t *dstPtr = NULL;

    for (int32_t pass = 0; pass < 2; ++pass) {
        size_t srcOffset = 0;
        size_t dstOffset = 0;
        while (srcOffset + mNALSizeLen <= srcSize) {
            size_t NALsize;
            switch (mNALSizeLen) {
                case 1: NALsize = srcPtr[srcOffset]; break;
                case 2: NALsize = U16_AT(srcPtr + srcOffset); break;
                case 3: NALsize = U24_AT(srcPtr + srcOffset); break;
                case 4: NALsize = U32_AT(srcPtr + srcOffset); break;
                default:
                    TRESPASS();
            }

            if (srcOffset + mNALSizeLen + NALsize <= srcOffset + mNALSizeLen) {
                frame->release();
                frame = NULL;

                return AMEDIA_ERROR_MALFORMED;
            } else if (srcOffset + mNALSizeLen + NALsize > srcSize) {
                break;
            }

            if (pass == 1) {
                memcpy(&dstPtr[dstOffset], "\x00\x00\x00\x01", 4);

                if (frame != buffer) {
                    memcpy(&dstPtr[dstOffset + 4],
                           &srcPtr[srcOffset + mNALSizeLen],
                           NALsize);
                }
            }

            dstOffset += 4;  // 0x00 00 00 01
            dstOffset += NALsize;

            srcOffset += mNALSizeLen + NALsize;
        }

        if (srcOffset < srcSize) {
            // There were trailing bytes or not enough data to complete
            // a fragment.

            frame->release();
            frame = NULL;

            return AMEDIA_ERROR_MALFORMED;
        }

        if (pass == 0) {
            dstSize = dstOffset;

            if (dstSize == srcSize && mNALSizeLen == 4) {
                // In this special case we can re-use the input buffer by substituting
                // each 4-byte nal size with a 4-byte start code
                buffer = frame;
            } else {
                mBufferGroup->acquire_buffer(
                        &buffer, false /* nonblocking */, dstSize /* requested size */);
                buffer->set_range(0, dstSize);
            }

            AMediaFormat *frameMeta = frame->meta_data();
            int64_t timeUs;
            CHECK(AMediaFormat_getInt64(frameMeta, AMEDIAFORMAT_KEY_TIME_US, &timeUs));
            int32_t isSync;
            CHECK(AMediaFormat_getInt32(frameMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, &isSync));

            AMediaFormat *bufMeta = buffer->meta_data();
            AMediaFormat_setInt64(bufMeta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
            AMediaFormat_setInt32(bufMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, isSync);

            dstPtr = (uint8_t *)buffer->data();
        }
    }

    if (frame != buffer) {
        frame->release();
        frame = NULL;
    }

    if (targetSampleTimeUs >= 0ll) {
        AMediaFormat_setInt64(buffer->meta_data(),
                AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
    }

    *out = buffer;

    return AMEDIA_OK;
}

////////////////////////////////////////////////////////////////////////////////

enum WaveID {
    MKV_RIFF_WAVE_FORMAT_PCM = 0x0001,
    MKV_RIFF_WAVE_FORMAT_ADPCM_ms = 0x0002,
    MKV_RIFF_WAVE_FORMAT_ADPCM_ima_wav = 0x0011,
    MKV_RIFF_WAVE_FORMAT_MPEGL12 = 0x0050,
    MKV_RIFF_WAVE_FORMAT_MPEGL3 = 0x0055,
    MKV_RIFF_WAVE_FORMAT_WMAV1 = 0x0160,
    MKV_RIFF_WAVE_FORMAT_WMAV2 = 0x0161,
};

static const char *MKVWave2MIME(uint16_t id) {
    switch (id) {
        case  MKV_RIFF_WAVE_FORMAT_MPEGL12:
            return MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II;

        case  MKV_RIFF_WAVE_FORMAT_MPEGL3:
            return MEDIA_MIMETYPE_AUDIO_MPEG;

        case MKV_RIFF_WAVE_FORMAT_PCM:
            return MEDIA_MIMETYPE_AUDIO_RAW;

        case MKV_RIFF_WAVE_FORMAT_ADPCM_ms:
            return MEDIA_MIMETYPE_AUDIO_MS_ADPCM;
        case MKV_RIFF_WAVE_FORMAT_ADPCM_ima_wav:
            return MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM;

        case MKV_RIFF_WAVE_FORMAT_WMAV1:
        case MKV_RIFF_WAVE_FORMAT_WMAV2:
            return MEDIA_MIMETYPE_AUDIO_WMA;
        default:
            ALOGW("unknown wave %x", id);
            return "";
    };
}

static bool isMkvAudioCsdSizeOK(const char* mime, size_t csdSize) {
    if ((!strcmp(mime, MEDIA_MIMETYPE_AUDIO_MS_ADPCM) && csdSize < 50) ||
        (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM) && csdSize < 20) ||
        (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_WMA) && csdSize < 28) ||
        (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG) && csdSize < 30)) {
        return false;
    }
    return true;
}

// trans all FOURCC  to lower char
static uint32_t FourCCtoLower(uint32_t fourcc) {
    uint8_t ch_1 = tolower((fourcc >> 24) & 0xff);
    uint8_t ch_2 = tolower((fourcc >> 16) & 0xff);
    uint8_t ch_3 = tolower((fourcc >> 8) & 0xff);
    uint8_t ch_4 = tolower((fourcc) & 0xff);
    uint32_t fourcc_out = ch_1 << 24 | ch_2 << 16 | ch_3 << 8 | ch_4;

    return fourcc_out;
}

static const char *MKVFourCC2MIME(uint32_t fourcc) {
    ALOGV("MKVFourCC2MIME fourcc 0x%8.8x", fourcc);
    uint32_t lowerFourcc = FourCCtoLower(fourcc);
    switch (lowerFourcc) {
        case FOURCC("mp4v"):
            return MEDIA_MIMETYPE_VIDEO_MPEG4;

        case FOURCC("s263"):
        case FOURCC("h263"):
            return MEDIA_MIMETYPE_VIDEO_H263;

        case FOURCC("avc1"):
        case FOURCC("h264"):
            return MEDIA_MIMETYPE_VIDEO_AVC;

        case FOURCC("mpg2"):
            return MEDIA_MIMETYPE_VIDEO_MPEG2;

        case FOURCC("xvid"):
            return MEDIA_MIMETYPE_VIDEO_XVID;

        case FOURCC("divx"):
        case FOURCC("dx50"):
            return MEDIA_MIMETYPE_VIDEO_DIVX;

        case FOURCC("div3"):
        case FOURCC("div4"):
            return MEDIA_MIMETYPE_VIDEO_DIVX3;

        case FOURCC("mjpg"):
        case FOURCC("mppg"):
            return MEDIA_MIMETYPE_VIDEO_MJPEG;

        default:
            char fourccString[5];
            MakeFourCCString(fourcc, fourccString);
            ALOGW("mkv unsupport fourcc %s", fourccString);
            return "";
    }
}


MatroskaExtractor::MatroskaExtractor(DataSourceHelper *source)
    : mDataSource(source),
      mReader(new DataSourceBaseReader(mDataSource)),
      mSegment(NULL),
      mExtractedThumbnails(false),
      mIsWebm(false),
      mSeekPreRollNs(0) {
    off64_t size;
    mIsLiveStreaming =
        (mDataSource->flags()
            & (DataSourceBase::kWantsPrefetching
                | DataSourceBase::kIsCachingDataSource))
        && mDataSource->getSize(&size) != OK;

    mkvparser::EBMLHeader ebmlHeader;
    long long pos;
    if (ebmlHeader.Parse(mReader, pos) < 0) {
        return;
    }

    if (ebmlHeader.m_docType && !strcmp("webm", ebmlHeader.m_docType)) {
        mIsWebm = true;
    }

    long long ret =
        mkvparser::Segment::CreateInstance(mReader, pos, mSegment);

    if (ret) {
        CHECK(mSegment == NULL);
        return;
    }

    if (mIsLiveStreaming) {
        // from mkvparser::Segment::Load(), but stop at first cluster
        ret = mSegment->ParseHeaders();
        if (ret == 0) {
            long len;
            ret = mSegment->LoadCluster(pos, len);
            if (ret >= 1) {
                // no more clusters
                ret = 0;
            }
        } else if (ret > 0) {
            ret = mkvparser::E_BUFFER_NOT_FULL;
        }
    } else {
        ret = mSegment->ParseHeaders();
        if (ret < 0) {
            ALOGE("Segment parse header return fail %lld", ret);
            delete mSegment;
            mSegment = NULL;
            return;
        } else if (ret == 0) {
            const mkvparser::Cues* mCues = mSegment->GetCues();
            const mkvparser::SeekHead* mSH = mSegment->GetSeekHead();
            if ((mCues == NULL) && (mSH != NULL)) {
                size_t count = mSH->GetCount();
                const mkvparser::SeekHead::Entry* mEntry;
                for (size_t index = 0; index < count; index++) {
                    mEntry = mSH->GetEntry(index);
                    if (mEntry->id == libwebm::kMkvCues) { // Cues ID
                        long len;
                        long long pos;
                        mSegment->ParseCues(mEntry->pos, pos, len);
                        mCues = mSegment->GetCues();
                        ALOGV("find cue data by seekhead");
                        break;
                    }
                }
            }

            if (mCues) {
                long len;
                ret = mSegment->LoadCluster(pos, len);
                ALOGV("has Cue data, Cluster num=%ld", mSegment->GetCount());
            } else  {
                long status_Load = mSegment->Load();
                ALOGW("no Cue data,Segment Load status:%ld",status_Load);
            }
        } else if (ret > 0) {
            ret = mkvparser::E_BUFFER_NOT_FULL;
        }
    }

    if (ret < 0) {
        char uri[1024];
        if(!mDataSource->getUri(uri, sizeof(uri))) {
            uri[0] = '\0';
        }
        ALOGW("Corrupt %s source: %s", mIsWebm ? "webm" : "matroska",
                uriDebugString(uri).c_str());
        delete mSegment;
        mSegment = NULL;
        return;
    }

#if 0
    const mkvparser::SegmentInfo *info = mSegment->GetInfo();
    ALOGI("muxing app: %s, writing app: %s",
         info->GetMuxingAppAsUTF8(),
         info->GetWritingAppAsUTF8());
#endif

    addTracks();
}

MatroskaExtractor::~MatroskaExtractor() {
    delete mSegment;
    mSegment = NULL;

    delete mReader;
    mReader = NULL;

    delete mDataSource;

    for (size_t i = 0; i < mTracks.size(); ++i) {
        TrackInfo *info = &mTracks.editItemAt(i);
        if (info->mMeta) {
            AMediaFormat_delete(info->mMeta);
        }
    }
}

size_t MatroskaExtractor::countTracks() {
    return mTracks.size();
}

MediaTrackHelper *MatroskaExtractor::getTrack(size_t index) {
    if (index >= mTracks.size()) {
        return NULL;
    }

    return new MatroskaSource(this, index);
}

media_status_t MatroskaExtractor::getTrackMetaData(
        AMediaFormat *meta,
        size_t index, uint32_t flags) {
    if (index >= mTracks.size()) {
        return AMEDIA_ERROR_UNKNOWN;
    }

    if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails
            && !isLiveStreaming()) {
        findThumbnails();
        mExtractedThumbnails = true;
    }

    return AMediaFormat_copy(meta, mTracks.itemAt(index).mMeta);
}

bool MatroskaExtractor::isLiveStreaming() const {
    return mIsLiveStreaming;
}

static int bytesForSize(size_t size) {
    // use at most 28 bits (4 times 7)
    CHECK(size <= 0xfffffff);

    if (size > 0x1fffff) {
        return 4;
    } else if (size > 0x3fff) {
        return 3;
    } else if (size > 0x7f) {
        return 2;
    }
    return 1;
}

static void storeSize(uint8_t *data, size_t &idx, size_t size) {
    int numBytes = bytesForSize(size);
    idx += numBytes;

    data += idx;
    size_t next = 0;
    while (numBytes--) {
        *--data = (size & 0x7f) | next;
        size >>= 7;
        next = 0x80;
    }
}

static void addESDSFromCodecPrivate(
        AMediaFormat *meta,
        bool isAudio, const void *priv, size_t privSize) {

    int privSizeBytesRequired = bytesForSize(privSize);
    int esdsSize2 = 14 + privSizeBytesRequired + privSize;
    int esdsSize2BytesRequired = bytesForSize(esdsSize2);
    int esdsSize1 = 4 + esdsSize2BytesRequired + esdsSize2;
    int esdsSize1BytesRequired = bytesForSize(esdsSize1);
    size_t esdsSize = 1 + esdsSize1BytesRequired + esdsSize1;
    uint8_t *esds = new uint8_t[esdsSize];

    size_t idx = 0;
    esds[idx++] = 0x03;
    storeSize(esds, idx, esdsSize1);
    esds[idx++] = 0x00; // ES_ID
    esds[idx++] = 0x00; // ES_ID
    esds[idx++] = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
    esds[idx++] = 0x04;
    storeSize(esds, idx, esdsSize2);
    esds[idx++] = isAudio ? 0x40   // Audio ISO/IEC 14496-3
                          : 0x20;  // Visual ISO/IEC 14496-2
    for (int i = 0; i < 12; i++) {
        esds[idx++] = 0x00;
    }
    esds[idx++] = 0x05;
    storeSize(esds, idx, privSize);
    memcpy(esds + idx, priv, privSize);

    AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, priv, privSize);

    delete[] esds;
    esds = NULL;
}

status_t addVorbisCodecInfo(
        AMediaFormat *meta,
        const void *_codecPrivate, size_t codecPrivateSize) {
    // hexdump(_codecPrivate, codecPrivateSize);

    if (codecPrivateSize < 1) {
        return ERROR_MALFORMED;
    }

    const uint8_t *codecPrivate = (const uint8_t *)_codecPrivate;

    if (codecPrivate[0] != 0x02) {
        return ERROR_MALFORMED;
    }

    // codecInfo starts with two lengths, len1 and len2, that are
    // "Xiph-style-lacing encoded"...

    size_t offset = 1;
    size_t len1 = 0;
    while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) {
        if (len1 > (SIZE_MAX - 0xff)) {
            return ERROR_MALFORMED; // would overflow
        }
        len1 += 0xff;
        ++offset;
    }
    if (offset >= codecPrivateSize) {
        return ERROR_MALFORMED;
    }
    if (len1 > (SIZE_MAX - codecPrivate[offset])) {
        return ERROR_MALFORMED; // would overflow
    }
    len1 += codecPrivate[offset++];

    size_t len2 = 0;
    while (offset < codecPrivateSize && codecPrivate[offset] == 0xff) {
        if (len2 > (SIZE_MAX - 0xff)) {
            return ERROR_MALFORMED; // would overflow
        }
        len2 += 0xff;
        ++offset;
    }
    if (offset >= codecPrivateSize) {
        return ERROR_MALFORMED;
    }
    if (len2 > (SIZE_MAX - codecPrivate[offset])) {
        return ERROR_MALFORMED; // would overflow
    }
    len2 += codecPrivate[offset++];

    if (len1 > SIZE_MAX - len2 || offset > SIZE_MAX - (len1 + len2) ||
            codecPrivateSize < offset + len1 + len2) {
        return ERROR_MALFORMED;
    }

    if (codecPrivate[offset] != 0x01) {
        return ERROR_MALFORMED;
    }
    // formerly kKeyVorbisInfo
    AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, &codecPrivate[offset], len1);

    offset += len1;
    if (codecPrivate[offset] != 0x03) {
        return ERROR_MALFORMED;
    }

    offset += len2;
    if (codecPrivate[offset] != 0x05) {
        return ERROR_MALFORMED;
    }

    // formerly kKeyVorbisBooks
    AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_1,
            &codecPrivate[offset], codecPrivateSize - offset);

    return OK;
}

static status_t addFlacMetadata(
        AMediaFormat *meta,
        const void *codecPrivate, size_t codecPrivateSize) {
    // hexdump(codecPrivate, codecPrivateSize);

    // formerly kKeyFlacMetadata
    AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);

    int32_t maxInputSize = 64 << 10;
    FLACDecoder *flacDecoder = FLACDecoder::Create();
    if (flacDecoder != NULL
            && flacDecoder->parseMetadata((const uint8_t*)codecPrivate, codecPrivateSize) == OK) {
        FLAC__StreamMetadata_StreamInfo streamInfo = flacDecoder->getStreamInfo();
        maxInputSize = streamInfo.max_framesize;
        if (maxInputSize == 0) {
            // In case max framesize is not available, use raw data size as max framesize,
            // assuming there is no expansion.
            if (streamInfo.max_blocksize != 0
                    && streamInfo.channels != 0
                    && ((streamInfo.bits_per_sample + 7) / 8) >
                        INT32_MAX / streamInfo.max_blocksize / streamInfo.channels) {
                delete flacDecoder;
                return ERROR_MALFORMED;
            }
            maxInputSize = ((streamInfo.bits_per_sample + 7) / 8)
                * streamInfo.max_blocksize * streamInfo.channels;
        }
    }
    AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, maxInputSize);

    delete flacDecoder;
    return OK;
}

status_t MatroskaExtractor::synthesizeAVCC(TrackInfo *trackInfo, size_t index) {
    BlockIterator iter(this, trackInfo->mTrackNum, index);
    if (iter.eos()) {
        return ERROR_MALFORMED;
    }

    const mkvparser::Block *block = iter.block();
    if (block->GetFrameCount() <= 0) {
        return ERROR_MALFORMED;
    }

    const mkvparser::Block::Frame &frame = block->GetFrame(0);
    auto tmpData = heapbuffer<unsigned char>(frame.len);
    long n = frame.Read(mReader, tmpData.get());
    if (n != 0) {
        return ERROR_MALFORMED;
    }

    if (!MakeAVCCodecSpecificData(trackInfo->mMeta, tmpData.get(), frame.len)) {
        return ERROR_MALFORMED;
    }

    // Override the synthesized nal length size, which is arbitrary
    trackInfo->mNalLengthSize = 0;
    return OK;
}

status_t MatroskaExtractor::synthesizeMPEG2(TrackInfo *trackInfo, size_t index) {
    ALOGV("synthesizeMPEG2");
    BlockIterator iter(this, trackInfo->mTrackNum, index);
    if (iter.eos()) {
        return ERROR_MALFORMED;
    }

    const mkvparser::Block *block = iter.block();
    if (block->GetFrameCount() <= 0) {
        return ERROR_MALFORMED;
    }

    const mkvparser::Block::Frame &frame = block->GetFrame(0);
    auto tmpData = heapbuffer<unsigned char>(frame.len);
    long n = frame.Read(mReader, tmpData.get());
    if (n != 0) {
        return ERROR_MALFORMED;
    }

    size_t header_start = 0;
    size_t header_lenth = 0;
    for (header_start = 0; header_start < frame.len - 4; header_start++) {
        if (ntohl(0x000001b3) == *(uint32_t*)((uint8_t*)tmpData.get() + header_start)) {
            break;
        }
    }
    bool isComplete_csd = false;
    for (header_lenth = 0; header_lenth < frame.len - 4 - header_start; header_lenth++) {
        if (ntohl(0x000001b8) == *(uint32_t*)((uint8_t*)tmpData.get()
                                + header_start + header_lenth)) {
            isComplete_csd = true;
            break;
        }
    }
    if (!isComplete_csd) {
        ALOGE("can't parse complete csd for MPEG2!");
        return ERROR_MALFORMED;
    }
    addESDSFromCodecPrivate(trackInfo->mMeta, false,
                              (uint8_t*)(tmpData.get()) + header_start, header_lenth);

    return OK;

}

status_t MatroskaExtractor::synthesizeMPEG4(TrackInfo *trackInfo, size_t index) {
    ALOGV("synthesizeMPEG4");
    BlockIterator iter(this, trackInfo->mTrackNum, index);
    if (iter.eos()) {
        return ERROR_MALFORMED;
    }

    const mkvparser::Block *block = iter.block();
    if (block->GetFrameCount() <= 0) {
        return ERROR_MALFORMED;
    }

    const mkvparser::Block::Frame &frame = block->GetFrame(0);
    auto tmpData = heapbuffer<unsigned char>(frame.len);
    long n = frame.Read(mReader, tmpData.get());
    if (n != 0) {
        return ERROR_MALFORMED;
    }

     size_t vosend;
     bool isComplete_csd = false;
     for (vosend = 0; (long)vosend < frame.len - 4; vosend++) {
         if (ntohl(0x000001b6) == *(uint32_t*)((uint8_t*)tmpData.get() + vosend)) {
             isComplete_csd = true;
             break;  // Send VOS until VOP
         }
     }
     if (!isComplete_csd) {
         ALOGE("can't parse complete csd for MPEG4!");
         return ERROR_MALFORMED;
     }
     addESDSFromCodecPrivate(trackInfo->mMeta, false, tmpData.get(), vosend);

    return OK;

}


static inline bool isValidInt32ColourValue(long long value) {
    return value != mkvparser::Colour::kValueNotPresent
            && value >= INT32_MIN
            && value <= INT32_MAX;
}

static inline bool isValidUint16ColourValue(long long value) {
    return value != mkvparser::Colour::kValueNotPresent
            && value >= 0
            && value <= UINT16_MAX;
}

static inline bool isValidPrimary(const mkvparser::PrimaryChromaticity *primary) {
    return primary != NULL && primary->x >= 0 && primary->x <= 1
             && primary->y >= 0 && primary->y <= 1;
}

void MatroskaExtractor::getColorInformation(
        const mkvparser::VideoTrack *vtrack, AMediaFormat *meta) {
    const mkvparser::Colour *color = vtrack->GetColour();
    if (color == NULL) {
        return;
    }

    // Color Aspects
    {
        int32_t primaries = 2; // ISO unspecified
        int32_t isotransfer = 2; // ISO unspecified
        int32_t coeffs = 2; // ISO unspecified
        bool fullRange = false; // default
        bool rangeSpecified = false;

        if (isValidInt32ColourValue(color->primaries)) {
            primaries = color->primaries;
        }
        if (isValidInt32ColourValue(color->transfer_characteristics)) {
            isotransfer = color->transfer_characteristics;
        }
        if (isValidInt32ColourValue(color->matrix_coefficients)) {
            coeffs = color->matrix_coefficients;
        }
        if (color->range != mkvparser::Colour::kValueNotPresent
                && color->range != 0 /* MKV unspecified */) {
            // We only support MKV broadcast range (== limited) and full range.
            // We treat all other value as the default limited range.
            fullRange = color->range == 2 /* MKV fullRange */;
            rangeSpecified = true;
        }

        int32_t range = 0;
        int32_t standard = 0;
        int32_t transfer = 0;
        ColorUtils::convertIsoColorAspectsToPlatformAspects(
                primaries, isotransfer, coeffs, fullRange,
                &range, &standard, &transfer);
        if (range != 0) {
            AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_COLOR_RANGE, range);
        }
        if (standard != 0) {
            AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_COLOR_STANDARD, standard);
        }
        if (transfer != 0) {
            AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_COLOR_TRANSFER, transfer);
        }
    }

    // HDR Static Info
    {
        HDRStaticInfo info, nullInfo; // nullInfo is a fully unspecified static info
        memset(&info, 0, sizeof(info));
        memset(&nullInfo, 0, sizeof(nullInfo));
        if (isValidUint16ColourValue(color->max_cll)) {
            info.sType1.mMaxContentLightLevel = color->max_cll;
        }
        if (isValidUint16ColourValue(color->max_fall)) {
            info.sType1.mMaxFrameAverageLightLevel = color->max_fall;
        }
        const mkvparser::MasteringMetadata *mastering = color->mastering_metadata;
        if (mastering != NULL) {
            // Convert matroska values to HDRStaticInfo equivalent values for each fully specified
            // group. See CTA-681.3 section 3.2.1 for more info.
            if (mastering->luminance_max >= 0.5 && mastering->luminance_max < 65535.5) {
                info.sType1.mMaxDisplayLuminance = (uint16_t)(mastering->luminance_max + 0.5);
            }
            if (mastering->luminance_min >= 0.00005 && mastering->luminance_min < 6.55355) {
                // HDRStaticInfo Type1 stores min luminance scaled 10000:1
                info.sType1.mMinDisplayLuminance =
                    (uint16_t)(10000 * mastering->luminance_min + 0.5);
            }
            // HDRStaticInfo Type1 stores primaries scaled 50000:1
            if (isValidPrimary(mastering->white_point)) {
                info.sType1.mW.x = (uint16_t)(50000 * mastering->white_point->x + 0.5);
                info.sType1.mW.y = (uint16_t)(50000 * mastering->white_point->y + 0.5);
            }
            if (isValidPrimary(mastering->r) && isValidPrimary(mastering->g)
                    && isValidPrimary(mastering->b)) {
                info.sType1.mR.x = (uint16_t)(50000 * mastering->r->x + 0.5);
                info.sType1.mR.y = (uint16_t)(50000 * mastering->r->y + 0.5);
                info.sType1.mG.x = (uint16_t)(50000 * mastering->g->x + 0.5);
                info.sType1.mG.y = (uint16_t)(50000 * mastering->g->y + 0.5);
                info.sType1.mB.x = (uint16_t)(50000 * mastering->b->x + 0.5);
                info.sType1.mB.y = (uint16_t)(50000 * mastering->b->y + 0.5);
            }
        }
        // Only advertise static info if at least one of the groups have been specified.
        if (memcmp(&info, &nullInfo, sizeof(info)) != 0) {
            info.mID = HDRStaticInfo::kType1;
            ColorUtils::setHDRStaticInfoIntoAMediaFormat(info, meta);
        }
    }
}

status_t MatroskaExtractor::initTrackInfo(
        const mkvparser::Track *track, AMediaFormat *meta, TrackInfo *trackInfo) {
    trackInfo->mTrackNum = track->GetNumber();
    trackInfo->mMeta = meta;
    trackInfo->mExtractor = this;
    trackInfo->mEncrypted = false;
    trackInfo->mHeader = NULL;
    trackInfo->mHeaderLen = 0;
    trackInfo->mNalLengthSize = -1;

    for(size_t i = 0; i < track->GetContentEncodingCount(); i++) {
        const mkvparser::ContentEncoding *encoding = track->GetContentEncodingByIndex(i);
        for(size_t j = 0; j < encoding->GetEncryptionCount(); j++) {
            const mkvparser::ContentEncoding::ContentEncryption *encryption;
            encryption = encoding->GetEncryptionByIndex(j);
            AMediaFormat_setBuffer(trackInfo->mMeta,
                    AMEDIAFORMAT_KEY_CRYPTO_KEY, encryption->key_id, encryption->key_id_len);
            trackInfo->mEncrypted = true;
            break;
        }

        for(size_t j = 0; j < encoding->GetCompressionCount(); j++) {
            const mkvparser::ContentEncoding::ContentCompression *compression;
            compression = encoding->GetCompressionByIndex(j);
            ALOGV("compression algo %llu settings_len %lld",
                compression->algo, compression->settings_len);
            if (compression->algo == 3
                    && compression->settings
                    && compression->settings_len > 0) {
                trackInfo->mHeader = compression->settings;
                trackInfo->mHeaderLen = compression->settings_len;
            }
        }
    }

    return OK;
}

void MatroskaExtractor::addTracks() {
    const mkvparser::Tracks *tracks = mSegment->GetTracks();

    AMediaFormat *meta = nullptr;

    for (size_t index = 0; index < tracks->GetTracksCount(); ++index) {
        const mkvparser::Track *track = tracks->GetTrackByIndex(index);

        if (track == NULL) {
            // Apparently this is currently valid (if unexpected) behaviour
            // of the mkv parser lib.
            continue;
        }

        const char *const codecID = track->GetCodecId();
        ALOGV("codec id = %s", codecID);
        ALOGV("codec name = %s", track->GetCodecNameAsUTF8());

        if (codecID == NULL) {
            ALOGW("unknown codecID is not supported.");
            continue;
        }

        size_t codecPrivateSize;
        const unsigned char *codecPrivate =
            track->GetCodecPrivate(codecPrivateSize);

        enum { VIDEO_TRACK = 1, AUDIO_TRACK = 2 };

        if (meta) {
            AMediaFormat_clear(meta);
        } else {
            meta = AMediaFormat_new();
        }

        status_t err = OK;
        int32_t nalSize = -1;

        bool isSetCsdFrom1stFrame = false;

        switch (track->GetType()) {
            case VIDEO_TRACK:
            {
                const mkvparser::VideoTrack *vtrack =
                    static_cast<const mkvparser::VideoTrack *>(track);

                if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AVC);
                    AMediaFormat_setBuffer(meta,
                           AMEDIAFORMAT_KEY_CSD_AVC, codecPrivate, codecPrivateSize);
                    if (codecPrivateSize > 4) {
                        nalSize = 1 + (codecPrivate[4] & 3);
                    }
                } else if (!strcmp("V_MPEGH/ISO/HEVC", codecID)) {
                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_HEVC);
                    if (codecPrivateSize > 0) {
                        AMediaFormat_setBuffer(meta,
                               AMEDIAFORMAT_KEY_CSD_HEVC, codecPrivate, codecPrivateSize);
                        if (codecPrivateSize > 14 + 7) {
                            nalSize = 1 + (codecPrivate[14 + 7] & 3);
                        }
                    } else {
                        ALOGW("HEVC is detected, but does not have configuration.");
                        continue;
                    }
                } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) {
                    AMediaFormat_setString(meta,
                            AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MPEG4);
                    if (codecPrivateSize > 0) {
                        addESDSFromCodecPrivate(
                                meta, false, codecPrivate, codecPrivateSize);
                    } else {
                        ALOGW("%s is detected, but does not have configuration.",
                                codecID);
                        isSetCsdFrom1stFrame = true;
                    }
                } else if (!strcmp("V_VP8", codecID)) {
                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_VP8);
                } else if (!strcmp("V_VP9", codecID)) {
                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_VP9);
                    if (codecPrivateSize > 0) {
                      // 'csd-0' for VP9 is the Blob of Codec Private data as
                      // specified in http://www.webmproject.org/vp9/profiles/.
                      AMediaFormat_setBuffer(meta,
                             AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
                    }
                } else if (!strcmp("V_AV1", codecID)) {
                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AV1);
                    if (codecPrivateSize > 0) {
                        // 'csd-0' for AV1 is the Blob of Codec Private data as
                        // specified in https://aomediacodec.github.io/av1-isobmff/.
                        AMediaFormat_setBuffer(
                                meta, AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
                    }
                } else if (!strcmp("V_MPEG2", codecID) || !strcmp("V_MPEG1", codecID)) {
                        AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME,
                                MEDIA_MIMETYPE_VIDEO_MPEG2);
                        if (codecPrivate != NULL) {
                            addESDSFromCodecPrivate(meta, false, codecPrivate, codecPrivateSize);
                        } else {
                            ALOGW("No specific codec private data, find it from the first frame");
                            isSetCsdFrom1stFrame = true;
                        }
                } else if (!strcmp("V_MJPEG", codecID)) {
                        AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME,
                                MEDIA_MIMETYPE_VIDEO_MJPEG);
                } else if (!strcmp("V_MS/VFW/FOURCC", codecID)) {
                    if (NULL == codecPrivate ||codecPrivateSize < 20) {
                        ALOGE("V_MS/VFW/FOURCC has no valid private data(%p),codecPrivateSize:%zu",
                                 codecPrivate, codecPrivateSize);
                        continue;
                    } else {
                        uint32_t fourcc = *(uint32_t *)(codecPrivate + 16);
                        fourcc = ntohl(fourcc);
                        const char* mime = MKVFourCC2MIME(fourcc);
                        ALOGV("V_MS/VFW/FOURCC type is %s", mime);
                        if (!strncasecmp("video/", mime, 6)) {
                            AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, mime);
                        } else {
                            ALOGE("V_MS/VFW/FOURCC continue,unsupport video type=%s,fourcc=0x%08x.",
                                 mime, fourcc);
                            continue;
                        }
                        if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) ||
                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_XVID) ||
                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_DIVX) ||
                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_DIVX3) ||
                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2) ||
                            !strcmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) {
                            isSetCsdFrom1stFrame = true;
                        } else {
                            ALOGW("FourCC have unsupport codec, type=%s,fourcc=0x%08x.",
                                  mime, fourcc);
                            continue;
                        }
                    }
                } else {
                    ALOGW("%s is not supported.", codecID);
                    continue;
                }

                const long long width = vtrack->GetWidth();
                const long long height = vtrack->GetHeight();
                if (width <= 0 || width > INT32_MAX) {
                    ALOGW("track width exceeds int32_t, %lld", width);
                    continue;
                }
                if (height <= 0 || height > INT32_MAX) {
                    ALOGW("track height exceeds int32_t, %lld", height);
                    continue;
                }
                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_WIDTH, (int32_t)width);
                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_HEIGHT, (int32_t)height);

                // setting display width/height is optional
                const long long displayUnit = vtrack->GetDisplayUnit();
                const long long displayWidth = vtrack->GetDisplayWidth();
                const long long displayHeight = vtrack->GetDisplayHeight();
                if (displayWidth > 0 && displayWidth <= INT32_MAX
                        && displayHeight > 0 && displayHeight <= INT32_MAX) {
                    switch (displayUnit) {
                    case 0: // pixels
                        AMediaFormat_setInt32(meta,
                                AMEDIAFORMAT_KEY_DISPLAY_WIDTH, (int32_t)displayWidth);
                        AMediaFormat_setInt32(meta,
                                AMEDIAFORMAT_KEY_DISPLAY_HEIGHT, (int32_t)displayHeight);
                        break;
                    case 1: // centimeters
                    case 2: // inches
                    case 3: // aspect ratio
                    {
                        // Physical layout size is treated the same as aspect ratio.
                        // Note: displayWidth and displayHeight are never zero as they are
                        // checked in the if above.
                        const long long computedWidth =
                                std::max(width, height * displayWidth / displayHeight);
                        const long long computedHeight =
                                std::max(height, width * displayHeight / displayWidth);
                        if (computedWidth <= INT32_MAX && computedHeight <= INT32_MAX) {
                            AMediaFormat_setInt32(meta,
                                    AMEDIAFORMAT_KEY_DISPLAY_WIDTH, (int32_t)computedWidth);
                            AMediaFormat_setInt32(meta,
                                    AMEDIAFORMAT_KEY_DISPLAY_HEIGHT, (int32_t)computedHeight);
                        }
                        break;
                    }
                    default: // unknown display units, perhaps future version of spec.
                        break;
                    }
                }

                getColorInformation(vtrack, meta);

                break;
            }

            case AUDIO_TRACK:
            {
                const mkvparser::AudioTrack *atrack =
                    static_cast<const mkvparser::AudioTrack *>(track);

                if (!strcmp("A_AAC", codecID)) {
                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AAC);
                    if (codecPrivateSize < 2) {
                        ALOGW("Incomplete AAC Codec Info %zu byte", codecPrivateSize);
                        continue;
                    }
                    addESDSFromCodecPrivate(
                            meta, true, codecPrivate, codecPrivateSize);
                } else if (!strcmp("A_VORBIS", codecID)) {
                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_VORBIS);

                    err = addVorbisCodecInfo(
                            meta, codecPrivate, codecPrivateSize);
                } else if (!strcmp("A_OPUS", codecID)) {
                    AMediaFormat_setString(meta,
                            AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_OPUS);
                    AMediaFormat_setBuffer(meta,
                            AMEDIAFORMAT_KEY_CSD_0, codecPrivate, codecPrivateSize);
                    int64_t codecDelay = track->GetCodecDelay();
                    AMediaFormat_setBuffer(meta,
                            AMEDIAFORMAT_KEY_CSD_1, &codecDelay, sizeof(codecDelay));
                    mSeekPreRollNs = track->GetSeekPreRoll();
                    AMediaFormat_setBuffer(meta,
                            AMEDIAFORMAT_KEY_CSD_2, &mSeekPreRollNs, sizeof(mSeekPreRollNs));
                } else if (!strcmp("A_MPEG/L3", codecID)) {
                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG);
                } else if (!strcmp("A_FLAC", codecID)) {
                    AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_FLAC);
                    err = addFlacMetadata(meta, codecPrivate, codecPrivateSize);
                } else if (!strcmp("A_MPEG/L2", codecID)) {
                    AMediaFormat_setString(meta,
                            AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II);
                } else if (!strcmp("A_PCM/INT/LIT", codecID) ||
                         !strcmp("A_PCM/INT/BIG", codecID)) {
                    AMediaFormat_setString(meta,
                            AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_RAW);
                    int32_t bigEndian = !strcmp("A_PCM/INT/BIG", codecID) ? 1: 0;
                    AMediaFormat_setInt32(meta,
                            AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN, bigEndian);
                } else if ((!strcmp("A_MS/ACM", codecID))) {
                    if ((NULL == codecPrivate) || (codecPrivateSize < 18)) {
                        ALOGW("unsupported audio: A_MS/ACM has no valid private data: %s, size: %zu",
                               codecPrivate == NULL ? "null" : "non-null", codecPrivateSize);
                        continue;
                    } else {
                        uint16_t ID = *(uint16_t *)codecPrivate;
                        const char* mime = MKVWave2MIME(ID);
                        ALOGV("A_MS/ACM type is %s", mime);
                        if (!strncasecmp("audio/", mime, 6) &&
                                isMkvAudioCsdSizeOK(mime, codecPrivateSize)) {
                            AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, mime);
                        } else {
                            ALOGE("A_MS/ACM continue, unsupported audio type=%s, csdSize:%zu",
                                mime, codecPrivateSize);
                            continue;
                        }
                        if (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_WMA)) {
                            addESDSFromCodecPrivate(meta, true, codecPrivate, codecPrivateSize);
                        } else if (!strcmp(mime, MEDIA_MIMETYPE_AUDIO_MS_ADPCM) ||
                                    !strcmp(mime, MEDIA_MIMETYPE_AUDIO_DVI_IMA_ADPCM)) {
                            uint32_t blockAlign = *(uint16_t*)(codecPrivate + 12);
                            addESDSFromCodecPrivate(meta, true, &blockAlign, sizeof(blockAlign));
                        }
                    }
                } else {
                    ALOGW("%s is not supported.", codecID);
                    continue;
                }

                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, atrack->GetSamplingRate());
                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, atrack->GetChannels());
                AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, atrack->GetBitDepth());
                break;
            }

            default:
                continue;
        }

        const char *language = track->GetLanguage();
        if (language != NULL) {
           char lang[4];
           strncpy(lang, language, 3);
           lang[3] = '\0';
           AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_LANGUAGE, lang);
        }

        if (err != OK) {
            ALOGE("skipping track, codec specific data was malformed.");
            continue;
        }

        long long durationNs = mSegment->GetDuration();
        AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_DURATION, (durationNs + 500) / 1000);

        const char *mimetype = "";
        if (!AMediaFormat_getString(meta, AMEDIAFORMAT_KEY_MIME, &mimetype)) {
            // do not add this track to the track list
            ALOGW("ignoring track with unknown mime");
            continue;
        }

        mTracks.push();
        size_t n = mTracks.size() - 1;
        TrackInfo *trackInfo = &mTracks.editItemAt(n);
        initTrackInfo(track, meta, trackInfo);
        trackInfo->mNalLengthSize = nalSize;

        if ((!strcmp("V_MPEG4/ISO/AVC", codecID) && codecPrivateSize == 0) ||
            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_AVC) && isSetCsdFrom1stFrame)) {
            // Attempt to recover from AVC track without codec private data
            err = synthesizeAVCC(trackInfo, n);
            if (err != OK) {
                mTracks.pop();
                continue;
            }
        } else if ((!strcmp("V_MPEG2", codecID) && codecPrivateSize == 0) ||
            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG2) && isSetCsdFrom1stFrame)) {
            // Attempt to recover from MPEG2 track without codec private data
            err = synthesizeMPEG2(trackInfo, n);
            if (err != OK) {
                mTracks.pop();
                continue;
            }
        } else if ((!strcmp("V_MPEG4/ISO/ASP", codecID) && codecPrivateSize == 0) ||
            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG4) && isSetCsdFrom1stFrame) ||
            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_XVID) && isSetCsdFrom1stFrame) ||
            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_DIVX) && isSetCsdFrom1stFrame) ||
            (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_DIVX3) && isSetCsdFrom1stFrame)) {
            // Attempt to recover from MPEG4 track without codec private data
            err = synthesizeMPEG4(trackInfo, n);
            if (err != OK) {
                mTracks.pop();
                continue;
            }
        }
        // the TrackInfo owns the metadata now
        meta = nullptr;
    }
    if (meta) {
        AMediaFormat_delete(meta);
    }
}

void MatroskaExtractor::findThumbnails() {
    for (size_t i = 0; i < mTracks.size(); ++i) {
        TrackInfo *info = &mTracks.editItemAt(i);

        const char *mime;
        CHECK(AMediaFormat_getString(info->mMeta, AMEDIAFORMAT_KEY_MIME, &mime));

        if (strncasecmp(mime, "video/", 6)) {
            continue;
        }

        BlockIterator iter(this, info->mTrackNum, i);
        int32_t j = 0;
        int64_t thumbnailTimeUs = 0;
        size_t maxBlockSize = 0;
        while (!iter.eos() && j < 20) {
            if (iter.block()->IsKey()) {
                ++j;

                size_t blockSize = 0;
                for (int k = 0; k < iter.block()->GetFrameCount(); ++k) {
                    blockSize += iter.block()->GetFrame(k).len;
                }

                if (blockSize > maxBlockSize) {
                    maxBlockSize = blockSize;
                    thumbnailTimeUs = iter.blockTimeUs();
                }
            }
            iter.advance();
        }
        AMediaFormat_setInt64(info->mMeta,
                AMEDIAFORMAT_KEY_THUMBNAIL_TIME, thumbnailTimeUs);
    }
}

media_status_t MatroskaExtractor::getMetaData(AMediaFormat *meta) {
    AMediaFormat_setString(meta,
            AMEDIAFORMAT_KEY_MIME, mIsWebm ? "video/webm" : MEDIA_MIMETYPE_CONTAINER_MATROSKA);

    return AMEDIA_OK;
}

uint32_t MatroskaExtractor::flags() const {
    uint32_t x = CAN_PAUSE;
    if (!isLiveStreaming()) {
        x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK;
    }

    return x;
}

bool SniffMatroska(
        DataSourceHelper *source, float *confidence) {
    DataSourceBaseReader reader(source);
    mkvparser::EBMLHeader ebmlHeader;
    long long pos;
    if (ebmlHeader.Parse(&reader, pos) < 0) {
        return false;
    }

    *confidence = 0.6;

    return true;
}

static const char *extensions[] = {
    "mka",
    "mkv",
    "webm",
    NULL
};

extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
ExtractorDef GETEXTRACTORDEF() {
    return {
        EXTRACTORDEF_VERSION,
        UUID("abbedd92-38c4-4904-a4c1-b3f45f899980"),
        1,
        "Matroska Extractor",
        {
            .v3 = {
                [](
                    CDataSource *source,
                    float *confidence,
                    void **,
                    FreeMetaFunc *) -> CreatorFunc {
                    DataSourceHelper helper(source);
                    if (SniffMatroska(&helper, confidence)) {
                        return [](
                                CDataSource *source,
                                void *) -> CMediaExtractor* {
                            return wrap(new MatroskaExtractor(new DataSourceHelper(source)));};
                    }
                    return NULL;
                },
                extensions
            }
        }
    };
}

} // extern "C"

}  // namespace android
