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"
24a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber#include "include/NuCachedSource2.h"
251608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber#include "include/WVMExtractor.h"
265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
275778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
285778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
295778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
305778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/DataSource.h>
31918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber#include <media/stagefright/FileSource.h>
325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaBuffer.h>
335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaDefs.h>
345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
355778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaExtractor.h>
365778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaSource.h>
375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/Utils.h>
395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
405778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas HuberNuMediaExtractor::NuMediaExtractor()
43a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    : mIsWidevineExtractor(false),
44a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber      mTotalBitrate(-1ll),
45a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber      mDurationUs(-1ll) {
465778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
485778822d86b0337407514b9372562b86edfa91cdAndreas HuberNuMediaExtractor::~NuMediaExtractor() {
495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    releaseTrackSamples();
505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ((status_t)OK, info->mSource->stop());
555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mSelectedTracks.clear();
585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
60918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huberstatus_t NuMediaExtractor::setDataSource(
61918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        const char *path, const KeyedVector<String8, String8> *headers) {
62dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
63dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
64918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (mImpl != NULL) {
65918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        return -EINVAL;
66918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
67918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
681608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    sp<DataSource> dataSource =
691608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        DataSource::CreateFromURI(path, headers);
705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (dataSource == NULL) {
725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ENOENT;
735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
75a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mIsWidevineExtractor = false;
761608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    if (!strncasecmp("widevine://", path, 11)) {
771608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        String8 mimeType;
781608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        float confidence;
791608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        sp<AMessage> dummy;
801608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        bool success = SniffWVM(dataSource, &mimeType, &confidence, &dummy);
811608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
821608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        if (!success
831608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber                || strcasecmp(
841608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
851608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            return ERROR_UNSUPPORTED;
861608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        }
871608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
881608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        sp<WVMExtractor> extractor = new WVMExtractor(dataSource);
891608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        extractor->setAdaptiveStreamingMode(true);
901608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
911608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        mImpl = extractor;
92a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        mIsWidevineExtractor = true;
931608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    } else {
941608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        mImpl = MediaExtractor::Create(dataSource);
951608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    }
965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mImpl == NULL) {
985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10194c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    sp<MetaData> fileMeta = mImpl->getMetaData();
10294c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    const char *containerMime;
10394c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    if (fileMeta != NULL
10494c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber            && fileMeta->findCString(kKeyMIMEType, &containerMime)
10594c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber            && !strcasecmp(containerMime, "video/wvm")) {
10694c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        // We always want to use "cryptoPluginMode" when using the wvm
10794c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        // extractor. We can tell that it is this extractor by looking
10894c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        // at the container mime type.
10994c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        // The cryptoPluginMode ensures that the extractor will actually
11094c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        // give us data in a call to MediaSource::read(), unlike its
11194c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        // default mode that we use from AwesomePlayer.
11294c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        static_cast<WVMExtractor *>(mImpl.get())->setCryptoPluginMode(true);
1133499e2d178960ca3392855716c963eec7403a089James Dong    } else if (mImpl->getDrmFlag()) {
1143499e2d178960ca3392855716c963eec7403a089James Dong        // For all other drm content, we don't want to expose decrypted
1153499e2d178960ca3392855716c963eec7403a089James Dong        // content to Java application.
1163499e2d178960ca3392855716c963eec7403a089James Dong        mImpl.clear();
1173499e2d178960ca3392855716c963eec7403a089James Dong        mImpl = NULL;
1183499e2d178960ca3392855716c963eec7403a089James Dong        return ERROR_UNSUPPORTED;
11994c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    }
12094c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber
121a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mDataSource = dataSource;
122a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
123a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    updateDurationAndBitrate();
124a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
1255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
128918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huberstatus_t NuMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) {
129fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen
130dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
131dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
132918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (mImpl != NULL) {
133918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        return -EINVAL;
134918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
135918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
136918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    sp<FileSource> fileSource = new FileSource(dup(fd), offset, size);
137918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
138fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    status_t err = fileSource->initCheck();
139fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    if (err != OK) {
140fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen        return err;
141fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    }
142fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen
143fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    mImpl = MediaExtractor::Create(fileSource);
144fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen
145fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    if (mImpl == NULL) {
146fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen        return ERROR_UNSUPPORTED;
147fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    }
148fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen
149fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    mDataSource = fileSource;
150fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen
151fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    updateDurationAndBitrate();
152fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen
153fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    return OK;
154dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen}
155dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen
156dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissenstatus_t NuMediaExtractor::setDataSource(const sp<DataSource> &source) {
157dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen    Mutex::Autolock autoLock(mLock);
158dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen
159dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen    if (mImpl != NULL) {
160dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen        return -EINVAL;
161dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen    }
162dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen
163dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen    status_t err = source->initCheck();
164918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (err != OK) {
165918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        return err;
166918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
167918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
168dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen    mImpl = MediaExtractor::Create(source);
169918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
170918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (mImpl == NULL) {
171918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        return ERROR_UNSUPPORTED;
172918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
173918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
174dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen    mDataSource = source;
175a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
176a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    updateDurationAndBitrate();
177a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
178918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    return OK;
179918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber}
180918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
181a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Hubervoid NuMediaExtractor::updateDurationAndBitrate() {
182a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mTotalBitrate = 0ll;
183a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mDurationUs = -1ll;
184a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
185a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    for (size_t i = 0; i < mImpl->countTracks(); ++i) {
186a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        sp<MetaData> meta = mImpl->getTrackMetaData(i);
187a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
188a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        int32_t bitrate;
189a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        if (!meta->findInt32(kKeyBitRate, &bitrate)) {
190a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            const char *mime;
191a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            CHECK(meta->findCString(kKeyMIMEType, &mime));
192a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            ALOGV("track of type '%s' does not publish bitrate", mime);
193a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
194a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            mTotalBitrate = -1ll;
195a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        } else if (mTotalBitrate >= 0ll) {
196a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            mTotalBitrate += bitrate;
197a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        }
198a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
199a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        int64_t durationUs;
200a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        if (meta->findInt64(kKeyDuration, &durationUs)
201a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber                && durationUs > mDurationUs) {
202a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            mDurationUs = durationUs;
203a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        }
204a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
205a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber}
206a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
2075778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t NuMediaExtractor::countTracks() const {
208dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
209dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
2105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mImpl == NULL ? 0 : mImpl->countTracks();
2115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getTrackFormat(
2145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index, sp<AMessage> *format) const {
215dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
216dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
2175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *format = NULL;
2185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mImpl == NULL) {
2205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
2215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mImpl->countTracks()) {
2245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
2255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MetaData> meta = mImpl->getTrackMetaData(index);
2289806555d3930be43e11106281dee354820ac1c88Andreas Huber    return convertMetaDataToMessage(meta, format);
2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2315778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::selectTrack(size_t index) {
232dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
233dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mImpl == NULL) {
2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mImpl->countTracks()) {
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
2435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
2445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mTrackIndex == index) {
2465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            // This track has already been selected.
2475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
2485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaSource> source = mImpl->getTrack(index);
2525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ((status_t)OK, source->start());
2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mSelectedTracks.push();
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1);
2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSource = source;
2595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mTrackIndex = index;
2605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mFinalResult = OK;
2615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSample = NULL;
2625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSampleTimeUs = -1ll;
263ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    info->mTrackFlags = 0;
2645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const char *mime;
2665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime));
2675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
269ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        info->mTrackFlags |= kIsVorbis;
2705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
2735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2759d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::unselectTrack(size_t index) {
2769d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    Mutex::Autolock autoLock(mLock);
2779d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
2789d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (mImpl == NULL) {
2799d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        return -EINVAL;
2809d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
2819d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
2829d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (index >= mImpl->countTracks()) {
2839d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        return -ERANGE;
2849d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
2859d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
2869d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    size_t i;
2879d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    for (i = 0; i < mSelectedTracks.size(); ++i) {
2889d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
2899d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
2909d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        if (info->mTrackIndex == index) {
2919d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber            break;
2929d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        }
2939d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
2949d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
2959d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (i == mSelectedTracks.size()) {
2969d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        // Not selected.
2979d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        return OK;
2989d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
2999d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3009d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(i);
3019d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3029d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (info->mSample != NULL) {
3039d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        info->mSample->release();
3049d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        info->mSample = NULL;
3059d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3069d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        info->mSampleTimeUs = -1ll;
3079d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
3089d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3099d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    CHECK_EQ((status_t)OK, info->mSource->stop());
3109d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3119d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    mSelectedTracks.removeAt(i);
3129d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3139d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    return OK;
3149d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber}
3159d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3165778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuMediaExtractor::releaseTrackSamples() {
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mSample != NULL) {
3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSample->release();
3225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSample = NULL;
3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSampleTimeUs = -1ll;
3255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3299d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberssize_t NuMediaExtractor::fetchTrackSamples(
3309d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        int64_t seekTimeUs, MediaSource::ReadOptions::SeekMode mode) {
3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *minInfo = NULL;
3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = -1;
3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (seekTimeUs >= 0ll) {
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mFinalResult = OK;
3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (info->mSample != NULL) {
3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSample->release();
3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSample = NULL;
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSampleTimeUs = -1ll;
3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (info->mFinalResult != OK) {
3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            continue;
3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mSample == NULL) {
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            MediaSource::ReadOptions options;
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (seekTimeUs >= 0ll) {
3529d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber                options.setSeekTo(seekTimeUs, mode);
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = info->mSource->read(&info->mSample, &options);
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (err != OK) {
3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample == NULL);
3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mFinalResult = err;
360bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
361bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                if (info->mFinalResult != ERROR_END_OF_STREAM) {
362bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    ALOGW("read on track %d failed with error %d",
363bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                          info->mTrackIndex, err);
364bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                }
365bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSampleTimeUs = -1ll;
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                continue;
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample != NULL);
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample->meta_data()->findInt64(
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            kKeyTime, &info->mSampleTimeUs));
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (minInfo == NULL  || info->mSampleTimeUs < minInfo->mSampleTimeUs) {
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            minInfo = info;
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            minIndex = i;
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return minIndex;
3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3849d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::seekTo(
3859d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        int64_t timeUs, MediaSource::ReadOptions::SeekMode mode) {
386dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
387dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
3889d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    ssize_t minIndex = fetchTrackSamples(timeUs, mode);
3894835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber
3904835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber    if (minIndex < 0) {
3914835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber        return ERROR_END_OF_STREAM;
3924835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber    }
3934835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber
3944835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber    return OK;
3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::advance() {
398dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
399dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
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    info->mSample->release();
4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSample = NULL;
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSampleTimeUs = -1ll;
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
416dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
417dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t sampleSize = info->mSample->range_length();
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
428ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (info->mTrackFlags & kIsVorbis) {
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // Each sample's data is suffixed by the number of page samples
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // or -1 if not available.
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sampleSize += sizeof(int32_t);
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer->capacity() < sampleSize) {
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ENOMEM;
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const uint8_t *src =
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        (const uint8_t *)info->mSample->data()
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            + info->mSample->range_offset();
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    memcpy((uint8_t *)buffer->data(), src, info->mSample->range_length());
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
444ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (info->mTrackFlags & kIsVorbis) {
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t numPageSamples;
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!info->mSample->meta_data()->findInt32(
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    kKeyValidSamples, &numPageSamples)) {
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numPageSamples = -1;
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        memcpy((uint8_t *)buffer->data() + info->mSample->range_length(),
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber               &numPageSamples,
4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber               sizeof(numPageSamples));
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    buffer->setRange(0, sampleSize);
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTrackIndex(size_t *trackIndex) {
462dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
463dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *trackIndex = info->mTrackIndex;
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTime(int64_t *sampleTimeUs) {
477dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
478dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *sampleTimeUs = info->mSampleTimeUs;
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
491f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huberstatus_t NuMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) {
492dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
493dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
494f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber    *sampleMeta = NULL;
495f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber
496ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    ssize_t minIndex = fetchTrackSamples();
497ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
498ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (minIndex < 0) {
499ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return ERROR_END_OF_STREAM;
500ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
503f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber    *sampleMeta = info->mSample->meta_data();
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
505ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    return OK;
506ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
507ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
508a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getTotalBitrate(int64_t *bitrate) const {
509a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    if (mTotalBitrate >= 0) {
510a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *bitrate = mTotalBitrate;
511a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
512a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
513a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
514a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    off64_t size;
515a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    if (mDurationUs >= 0 && mDataSource->getSize(&size) == OK) {
516a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
517a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
518a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
519a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
520a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    return false;
521a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber}
522a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
523a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber// Returns true iff cached duration is available/applicable.
524a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getCachedDuration(
525a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        int64_t *durationUs, bool *eos) const {
526dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
527dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
528a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    int64_t bitrate;
529a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    if (mIsWidevineExtractor) {
530a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        sp<WVMExtractor> wvmExtractor =
531a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            static_cast<WVMExtractor *>(mImpl.get());
532a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
533a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        status_t finalStatus;
534a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *durationUs = wvmExtractor->getCachedDurationUs(&finalStatus);
535a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *eos = (finalStatus != OK);
536a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
537a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    } else if ((mDataSource->flags() & DataSource::kIsCachingDataSource)
538a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            && getTotalBitrate(&bitrate)) {
539a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        sp<NuCachedSource2> cachedSource =
540a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            static_cast<NuCachedSource2 *>(mDataSource.get());
541a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
542a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        status_t finalStatus;
543a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        size_t cachedDataRemaining =
544a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            cachedSource->approxDataRemaining(&finalStatus);
545a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
546a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
547a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *eos = (finalStatus != OK);
548a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
549a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
550a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
551a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    return false;
552a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber}
553a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
555