NuMediaExtractor.cpp revision ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6
15778822d86b0337407514b9372562b86edfa91cdAndreas Huber/*
25778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Copyright 2012, The Android Open Source Project
35778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
45778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
55778822d86b0337407514b9372562b86edfa91cdAndreas Huber * you may not use this file except in compliance with the License.
65778822d86b0337407514b9372562b86edfa91cdAndreas Huber * You may obtain a copy of the License at
75778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
85778822d86b0337407514b9372562b86edfa91cdAndreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
95778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
105778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Unless required by applicable law or agreed to in writing, software
115778822d86b0337407514b9372562b86edfa91cdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
125778822d86b0337407514b9372562b86edfa91cdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135778822d86b0337407514b9372562b86edfa91cdAndreas Huber * See the License for the specific language governing permissions and
145778822d86b0337407514b9372562b86edfa91cdAndreas Huber * limitations under the License.
155778822d86b0337407514b9372562b86edfa91cdAndreas Huber */
165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
175778822d86b0337407514b9372562b86edfa91cdAndreas Huber//#define LOG_NDEBUG 0
185778822d86b0337407514b9372562b86edfa91cdAndreas Huber#define LOG_TAG "NuMediaExtractor"
195778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <utils/Log.h>
205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
215778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NuMediaExtractor.h>
225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
235778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "include/ESDS.h"
245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
255778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
265778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
275778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
285778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/DataSource.h>
295778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaBuffer.h>
305778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaDefs.h>
315778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaExtractor.h>
335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaSource.h>
345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
355778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/Utils.h>
365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
375778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
395778822d86b0337407514b9372562b86edfa91cdAndreas HuberNuMediaExtractor::NuMediaExtractor() {
405778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
425778822d86b0337407514b9372562b86edfa91cdAndreas HuberNuMediaExtractor::~NuMediaExtractor() {
435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    releaseTrackSamples();
445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ((status_t)OK, info->mSource->stop());
495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mSelectedTracks.clear();
525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::setDataSource(const char *path) {
555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<DataSource> dataSource = DataSource::CreateFromURI(path);
565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (dataSource == NULL) {
585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ENOENT;
595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mImpl = MediaExtractor::Create(dataSource);
625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mImpl == NULL) {
645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
705778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t NuMediaExtractor::countTracks() const {
715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mImpl == NULL ? 0 : mImpl->countTracks();
725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getTrackFormat(
755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index, sp<AMessage> *format) const {
765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *format = NULL;
775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mImpl == NULL) {
795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mImpl->countTracks()) {
835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MetaData> meta = mImpl->getTrackMetaData(index);
875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const char *mime;
895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage;
925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("mime", mime);
935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strncasecmp("video/", mime, 6)) {
955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t width, height;
965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(meta->findInt32(kKeyWidth, &width));
975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(meta->findInt32(kKeyHeight, &height));
985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("width", width);
1005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("height", height);
1015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
1025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(!strncasecmp("audio/", mime, 6));
1035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t numChannels, sampleRate;
1055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
1065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
1075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("channel-count", numChannels);
1095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("sample-rate", sampleRate);
110ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
111ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        int32_t isADTS;
112ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        if (meta->findInt32(kKeyIsADTS, &isADTS)) {
113ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            msg->setInt32("is-adts", true);
114ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
1155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t maxInputSize;
1185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
1195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("max-input-size", maxInputSize);
1205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t type;
1235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const void *data;
1245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
1255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
1265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // Parse the AVCDecoderConfigurationRecord
1275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const uint8_t *ptr = (const uint8_t *)data;
1295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(size >= 7);
1315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
1325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint8_t profile = ptr[1];
1335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint8_t level = ptr[3];
1345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // There is decodable content out there that fails the following
1365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // assertion, let's be lenient for now...
1375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
1385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t lengthSize = 1 + (ptr[4] & 3);
1405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
1425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // violates it...
1435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // CHECK((ptr[5] >> 5) == 7);  // reserved
1445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t numSeqParameterSets = ptr[5] & 31;
1465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ptr += 6;
1485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size -= 6;
1495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<ABuffer> buffer = new ABuffer(1024);
1515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->setRange(0, 0);
1525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        for (size_t i = 0; i < numSeqParameterSets; ++i) {
1545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(size >= 2);
1555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t length = U16_AT(ptr);
1565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ptr += 2;
1585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size -= 2;
1595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(size >= length);
1615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
1635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
1645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            buffer->setRange(0, buffer->size() + 4 + length);
1655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ptr += length;
1675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size -= length;
1685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt32("csd", true);
1715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt64("timeUs", 0);
1725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1732d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        msg->setBuffer("csd-0", buffer);
1745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer = new ABuffer(1024);
1765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->setRange(0, 0);
1775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(size >= 1);
1795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t numPictureParameterSets = *ptr;
1805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++ptr;
1815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        --size;
1825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        for (size_t i = 0; i < numPictureParameterSets; ++i) {
1845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(size >= 2);
1855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t length = U16_AT(ptr);
1865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ptr += 2;
1885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size -= 2;
1895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(size >= length);
1915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
1935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
1945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            buffer->setRange(0, buffer->size() + 4 + length);
1955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ptr += length;
1975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size -= length;
1985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt32("csd", true);
2015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt64("timeUs", 0);
2022d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        msg->setBuffer("csd-1", buffer);
2035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
2045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ESDS esds((const char *)data, size);
2055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(esds.InitCheck(), (status_t)OK);
2065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const void *codec_specific_data;
2085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t codec_specific_data_size;
2095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        esds.getCodecSpecificInfo(
2105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &codec_specific_data, &codec_specific_data_size);
2115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);
2135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        memcpy(buffer->data(), codec_specific_data,
2155778822d86b0337407514b9372562b86edfa91cdAndreas Huber               codec_specific_data_size);
2165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt32("csd", true);
2185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt64("timeUs", 0);
2192d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        msg->setBuffer("csd-0", buffer);
2205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
2215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<ABuffer> buffer = new ABuffer(size);
2225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        memcpy(buffer->data(), data, size);
2235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt32("csd", true);
2255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt64("timeUs", 0);
2262d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        msg->setBuffer("csd-0", buffer);
2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return -EINVAL;
2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer = new ABuffer(size);
2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        memcpy(buffer->data(), data, size);
2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt32("csd", true);
2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt64("timeUs", 0);
2372d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        msg->setBuffer("csd-1", buffer);
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
240ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (meta->findData(kKeyEMM, &type, &data, &size)) {
241ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        sp<ABuffer> emm = new ABuffer(size);
242ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        memcpy(emm->data(), data, size);
243ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
244ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        msg->setBuffer("emm", emm);
245ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
246ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
247ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (meta->findData(kKeyECM, &type, &data, &size)) {
248ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        sp<ABuffer> ecm = new ABuffer(size);
249ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        memcpy(ecm->data(), data, size);
250ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
251ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        msg->setBuffer("ecm", ecm);
252ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
253ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *format = msg;
2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::selectTrack(size_t index) {
2605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mImpl == NULL) {
2615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
2625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mImpl->countTracks()) {
2655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
2665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
2695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
2705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mTrackIndex == index) {
2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            // This track has already been selected.
2735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
2745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaSource> source = mImpl->getTrack(index);
2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ((status_t)OK, source->start());
2805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mSelectedTracks.push();
2825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1);
2835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSource = source;
2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mTrackIndex = index;
2865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mFinalResult = OK;
2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSample = NULL;
2885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSampleTimeUs = -1ll;
289ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    info->mSampleFlags = 0;
290ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    info->mTrackFlags = 0;
2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const char *mime;
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime));
2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
296ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        info->mTrackFlags |= kIsVorbis;
2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3025778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuMediaExtractor::releaseTrackSamples() {
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mSample != NULL) {
3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSample->release();
3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSample = NULL;
3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSampleTimeUs = -1ll;
311ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            info->mSampleFlags = 0;
3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t NuMediaExtractor::fetchTrackSamples(int64_t seekTimeUs) {
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *minInfo = NULL;
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = -1;
3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
3225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (seekTimeUs >= 0ll) {
3245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mFinalResult = OK;
3255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (info->mSample != NULL) {
3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSample->release();
3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSample = NULL;
3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSampleTimeUs = -1ll;
330ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info->mSampleFlags = 0;
3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (info->mFinalResult != OK) {
3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            continue;
3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mSample == NULL) {
3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            MediaSource::ReadOptions options;
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (seekTimeUs >= 0ll) {
3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                options.setSeekTo(seekTimeUs);
3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = info->mSource->read(&info->mSample, &options);
3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (err != OK) {
3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample == NULL);
3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mFinalResult = err;
3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSampleTimeUs = -1ll;
348ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info->mSampleFlags = 0;
3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                continue;
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample != NULL);
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample->meta_data()->findInt64(
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            kKeyTime, &info->mSampleTimeUs));
354ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
355ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info->mSampleFlags = 0;
356ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
357ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                int32_t val;
358ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (info->mSample->meta_data()->findInt32(
359ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            kKeyIsSyncFrame, &val) && val != 0) {
360ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info->mSampleFlags |= SAMPLE_FLAG_SYNC;
361ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
362ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
363ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (info->mSample->meta_data()->findInt32(
364ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            kKeyScrambling, &val) && val != 0) {
365ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info->mSampleFlags |= SAMPLE_FLAG_ENCRYPTED;
366ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (minInfo == NULL  || info->mSampleTimeUs < minInfo->mSampleTimeUs) {
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            minInfo = info;
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            minIndex = i;
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return minIndex;
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3795778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::seekTo(int64_t timeUs) {
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return fetchTrackSamples(timeUs);
3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3835778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::advance() {
3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSample->release();
3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSample = NULL;
3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSampleTimeUs = -1ll;
3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
4015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t sampleSize = info->mSample->range_length();
4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
410ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (info->mTrackFlags & kIsVorbis) {
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // Each sample's data is suffixed by the number of page samples
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // or -1 if not available.
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sampleSize += sizeof(int32_t);
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer->capacity() < sampleSize) {
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ENOMEM;
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const uint8_t *src =
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        (const uint8_t *)info->mSample->data()
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            + info->mSample->range_offset();
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    memcpy((uint8_t *)buffer->data(), src, info->mSample->range_length());
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
426ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (info->mTrackFlags & kIsVorbis) {
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t numPageSamples;
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!info->mSample->meta_data()->findInt32(
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    kKeyValidSamples, &numPageSamples)) {
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numPageSamples = -1;
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        memcpy((uint8_t *)buffer->data() + info->mSample->range_length(),
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber               &numPageSamples,
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber               sizeof(numPageSamples));
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    buffer->setRange(0, sampleSize);
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTrackIndex(size_t *trackIndex) {
4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *trackIndex = info->mTrackIndex;
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTime(int64_t *sampleTimeUs) {
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *sampleTimeUs = info->mSampleTimeUs;
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
469ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t NuMediaExtractor::getSampleFlags(uint32_t *sampleFlags) {
470ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    ssize_t minIndex = fetchTrackSamples();
471ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
472ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (minIndex < 0) {
473ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return ERROR_END_OF_STREAM;
474ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
475ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
476ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
477ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    *sampleFlags = info->mSampleFlags;
478ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
479ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    return OK;
480ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
481ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
483