NuMediaExtractor.cpp revision 94c1c8c99b70f2fdab87e131812eb253271e5500
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);
11394c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    }
11494c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber
115a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mDataSource = dataSource;
116a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
117a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    updateDurationAndBitrate();
118a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
1195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1205778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
122918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huberstatus_t NuMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) {
123dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
124dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
125918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (mImpl != NULL) {
126918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        return -EINVAL;
127918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
128918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
129918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    sp<FileSource> fileSource = new FileSource(dup(fd), offset, size);
130918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
131918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    status_t err = fileSource->initCheck();
132918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (err != OK) {
133918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        return err;
134918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
135918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
136918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    mImpl = MediaExtractor::Create(fileSource);
137918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
138918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (mImpl == NULL) {
139918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        return ERROR_UNSUPPORTED;
140918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
141918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
142a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mDataSource = fileSource;
143a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
144a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    updateDurationAndBitrate();
145a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
146918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    return OK;
147918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber}
148918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
149a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Hubervoid NuMediaExtractor::updateDurationAndBitrate() {
150a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mTotalBitrate = 0ll;
151a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mDurationUs = -1ll;
152a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
153a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    for (size_t i = 0; i < mImpl->countTracks(); ++i) {
154a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        sp<MetaData> meta = mImpl->getTrackMetaData(i);
155a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
156a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        int32_t bitrate;
157a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        if (!meta->findInt32(kKeyBitRate, &bitrate)) {
158a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            const char *mime;
159a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            CHECK(meta->findCString(kKeyMIMEType, &mime));
160a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            ALOGV("track of type '%s' does not publish bitrate", mime);
161a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
162a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            mTotalBitrate = -1ll;
163a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        } else if (mTotalBitrate >= 0ll) {
164a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            mTotalBitrate += bitrate;
165a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        }
166a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
167a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        int64_t durationUs;
168a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        if (meta->findInt64(kKeyDuration, &durationUs)
169a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber                && durationUs > mDurationUs) {
170a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            mDurationUs = durationUs;
171a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        }
172a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
173a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber}
174a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
1755778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t NuMediaExtractor::countTracks() const {
176dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
177dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
1785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mImpl == NULL ? 0 : mImpl->countTracks();
1795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getTrackFormat(
1825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index, sp<AMessage> *format) const {
183dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
184dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
1855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *format = NULL;
1865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mImpl == NULL) {
1885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
1895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mImpl->countTracks()) {
1925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
1935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MetaData> meta = mImpl->getTrackMetaData(index);
1965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const char *mime;
1985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
1995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage;
2015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("mime", mime);
2025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
203918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    int64_t durationUs;
204918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (meta->findInt64(kKeyDuration, &durationUs)) {
205918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        msg->setInt64("durationUs", durationUs);
206918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
207918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
2085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strncasecmp("video/", mime, 6)) {
2095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t width, height;
2105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(meta->findInt32(kKeyWidth, &width));
2115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(meta->findInt32(kKeyHeight, &height));
2125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("width", width);
2145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("height", height);
215e370bb62b89d2f2980f519392010ea08a24c558eAndreas Huber    } else if (!strncasecmp("audio/", mime, 6)) {
2165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t numChannels, sampleRate;
2175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
2185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
2195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("channel-count", numChannels);
2215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("sample-rate", sampleRate);
222ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
223ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        int32_t isADTS;
224ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        if (meta->findInt32(kKeyIsADTS, &isADTS)) {
225ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            msg->setInt32("is-adts", true);
226ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t maxInputSize;
2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("max-input-size", maxInputSize);
2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t type;
2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const void *data;
2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // Parse the AVCDecoderConfigurationRecord
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const uint8_t *ptr = (const uint8_t *)data;
2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(size >= 7);
2435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
2445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint8_t profile = ptr[1];
2455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint8_t level = ptr[3];
2465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // There is decodable content out there that fails the following
2485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // assertion, let's be lenient for now...
2495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
2505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t lengthSize = 1 + (ptr[4] & 3);
2525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // violates it...
2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // CHECK((ptr[5] >> 5) == 7);  // reserved
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t numSeqParameterSets = ptr[5] & 31;
2585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ptr += 6;
2605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size -= 6;
2615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<ABuffer> buffer = new ABuffer(1024);
2635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->setRange(0, 0);
2645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        for (size_t i = 0; i < numSeqParameterSets; ++i) {
2665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(size >= 2);
2675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t length = U16_AT(ptr);
2685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ptr += 2;
2705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size -= 2;
2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(size >= length);
2735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
2755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
2765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            buffer->setRange(0, buffer->size() + 4 + length);
2775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ptr += length;
2795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size -= length;
2805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt32("csd", true);
2835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt64("timeUs", 0);
2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2852d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        msg->setBuffer("csd-0", buffer);
2865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer = new ABuffer(1024);
2885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->setRange(0, 0);
2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(size >= 1);
2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t numPictureParameterSets = *ptr;
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++ptr;
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        --size;
2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        for (size_t i = 0; i < numPictureParameterSets; ++i) {
2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(size >= 2);
2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t length = U16_AT(ptr);
2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ptr += 2;
3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size -= 2;
3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(size >= length);
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            buffer->setRange(0, buffer->size() + 4 + length);
3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ptr += length;
3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size -= length;
3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt32("csd", true);
3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt64("timeUs", 0);
3142d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        msg->setBuffer("csd-1", buffer);
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ESDS esds((const char *)data, size);
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(esds.InitCheck(), (status_t)OK);
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const void *codec_specific_data;
3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t codec_specific_data_size;
3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        esds.getCodecSpecificInfo(
3225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &codec_specific_data, &codec_specific_data_size);
3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);
3255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        memcpy(buffer->data(), codec_specific_data,
3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber               codec_specific_data_size);
3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt32("csd", true);
3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt64("timeUs", 0);
3312d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        msg->setBuffer("csd-0", buffer);
3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<ABuffer> buffer = new ABuffer(size);
3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        memcpy(buffer->data(), data, size);
3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt32("csd", true);
3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt64("timeUs", 0);
3382d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        msg->setBuffer("csd-0", buffer);
3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return -EINVAL;
3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer = new ABuffer(size);
3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        memcpy(buffer->data(), data, size);
3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt32("csd", true);
3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffer->meta()->setInt64("timeUs", 0);
3492d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        msg->setBuffer("csd-1", buffer);
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *format = msg;
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::selectTrack(size_t index) {
358dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
359dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mImpl == NULL) {
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mImpl->countTracks()) {
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mTrackIndex == index) {
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            // This track has already been selected.
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaSource> source = mImpl->getTrack(index);
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ((status_t)OK, source->start());
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mSelectedTracks.push();
3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1);
3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSource = source;
3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mTrackIndex = index;
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mFinalResult = OK;
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSample = NULL;
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSampleTimeUs = -1ll;
389ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    info->mTrackFlags = 0;
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const char *mime;
3925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime));
3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
395ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        info->mTrackFlags |= kIsVorbis;
3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4019d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::unselectTrack(size_t index) {
4029d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    Mutex::Autolock autoLock(mLock);
4039d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4049d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (mImpl == NULL) {
4059d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        return -EINVAL;
4069d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
4079d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4089d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (index >= mImpl->countTracks()) {
4099d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        return -ERANGE;
4109d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
4119d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4129d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    size_t i;
4139d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    for (i = 0; i < mSelectedTracks.size(); ++i) {
4149d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
4159d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4169d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        if (info->mTrackIndex == index) {
4179d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber            break;
4189d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        }
4199d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
4209d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4219d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (i == mSelectedTracks.size()) {
4229d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        // Not selected.
4239d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        return OK;
4249d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
4259d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4269d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(i);
4279d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4289d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (info->mSample != NULL) {
4299d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        info->mSample->release();
4309d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        info->mSample = NULL;
4319d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4329d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        info->mSampleTimeUs = -1ll;
4339d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
4349d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4359d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    CHECK_EQ((status_t)OK, info->mSource->stop());
4369d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4379d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    mSelectedTracks.removeAt(i);
4389d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4399d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    return OK;
4409d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber}
4419d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
4425778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuMediaExtractor::releaseTrackSamples() {
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mSample != NULL) {
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSample->release();
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSample = NULL;
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSampleTimeUs = -1ll;
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4559d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberssize_t NuMediaExtractor::fetchTrackSamples(
4569d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        int64_t seekTimeUs, MediaSource::ReadOptions::SeekMode mode) {
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *minInfo = NULL;
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = -1;
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (seekTimeUs >= 0ll) {
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mFinalResult = OK;
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (info->mSample != NULL) {
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSample->release();
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSample = NULL;
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSampleTimeUs = -1ll;
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (info->mFinalResult != OK) {
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            continue;
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mSample == NULL) {
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            MediaSource::ReadOptions options;
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (seekTimeUs >= 0ll) {
4789d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber                options.setSeekTo(seekTimeUs, mode);
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = info->mSource->read(&info->mSample, &options);
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (err != OK) {
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample == NULL);
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mFinalResult = err;
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSampleTimeUs = -1ll;
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                continue;
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample != NULL);
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample->meta_data()->findInt64(
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            kKeyTime, &info->mSampleTimeUs));
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (minInfo == NULL  || info->mSampleTimeUs < minInfo->mSampleTimeUs) {
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            minInfo = info;
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            minIndex = i;
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return minIndex;
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5049d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::seekTo(
5059d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        int64_t timeUs, MediaSource::ReadOptions::SeekMode mode) {
506dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
507dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
5089d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    ssize_t minIndex = fetchTrackSamples(timeUs, mode);
5094835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber
5104835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber    if (minIndex < 0) {
5114835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber        return ERROR_END_OF_STREAM;
5124835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber    }
5134835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber
5144835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber    return OK;
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5175778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::advance() {
518dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
519dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSample->release();
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSample = NULL;
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSampleTimeUs = -1ll;
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
536dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
537dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t sampleSize = info->mSample->range_length();
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
548ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (info->mTrackFlags & kIsVorbis) {
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // Each sample's data is suffixed by the number of page samples
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // or -1 if not available.
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sampleSize += sizeof(int32_t);
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer->capacity() < sampleSize) {
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ENOMEM;
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const uint8_t *src =
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        (const uint8_t *)info->mSample->data()
5605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            + info->mSample->range_offset();
5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    memcpy((uint8_t *)buffer->data(), src, info->mSample->range_length());
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
564ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (info->mTrackFlags & kIsVorbis) {
5655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t numPageSamples;
5665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!info->mSample->meta_data()->findInt32(
5675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    kKeyValidSamples, &numPageSamples)) {
5685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numPageSamples = -1;
5695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        memcpy((uint8_t *)buffer->data() + info->mSample->range_length(),
5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber               &numPageSamples,
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber               sizeof(numPageSamples));
5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    buffer->setRange(0, sampleSize);
5775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTrackIndex(size_t *trackIndex) {
582dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
583dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *trackIndex = info->mTrackIndex;
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTime(int64_t *sampleTimeUs) {
597dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
598dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
5995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
6035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
6065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *sampleTimeUs = info->mSampleTimeUs;
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
6095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
611f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huberstatus_t NuMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) {
612dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
613dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
614f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber    *sampleMeta = NULL;
615f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber
616ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    ssize_t minIndex = fetchTrackSamples();
617ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
618ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (minIndex < 0) {
619ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return ERROR_END_OF_STREAM;
620ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
621ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
622ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
623f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber    *sampleMeta = info->mSample->meta_data();
624ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
625ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    return OK;
626ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
627ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
628a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getTotalBitrate(int64_t *bitrate) const {
629a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    if (mTotalBitrate >= 0) {
630a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *bitrate = mTotalBitrate;
631a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
632a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
633a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
634a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    off64_t size;
635a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    if (mDurationUs >= 0 && mDataSource->getSize(&size) == OK) {
636a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
637a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
638a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
639a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
640a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    return false;
641a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber}
642a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
643a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber// Returns true iff cached duration is available/applicable.
644a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getCachedDuration(
645a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        int64_t *durationUs, bool *eos) const {
646dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
647dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
648a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    int64_t bitrate;
649a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    if (mIsWidevineExtractor) {
650a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        sp<WVMExtractor> wvmExtractor =
651a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            static_cast<WVMExtractor *>(mImpl.get());
652a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
653a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        status_t finalStatus;
654a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *durationUs = wvmExtractor->getCachedDurationUs(&finalStatus);
655a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *eos = (finalStatus != OK);
656a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
657a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    } else if ((mDataSource->flags() & DataSource::kIsCachingDataSource)
658a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            && getTotalBitrate(&bitrate)) {
659a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        sp<NuCachedSource2> cachedSource =
660a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            static_cast<NuCachedSource2 *>(mDataSource.get());
661a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
662a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        status_t finalStatus;
663a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        size_t cachedDataRemaining =
664a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            cachedSource->approxDataRemaining(&finalStatus);
665a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
666a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
667a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *eos = (finalStatus != OK);
668a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
669a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
670a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
671a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    return false;
672a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber}
673a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
6745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
675