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();
584a631e84df76e97fa3424970a1a625dc9f1f5b9dRobert Shih    if (mDataSource != NULL) {
594a631e84df76e97fa3424970a1a625dc9f1f5b9dRobert Shih        mDataSource->close();
604a631e84df76e97fa3424970a1a625dc9f1f5b9dRobert Shih    }
615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
63918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huberstatus_t NuMediaExtractor::setDataSource(
641b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const sp<IMediaHTTPService> &httpService,
651b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const char *path,
661b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const KeyedVector<String8, String8> *headers) {
67dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
68dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
69918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (mImpl != NULL) {
70918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        return -EINVAL;
71918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
72918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
731608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    sp<DataSource> dataSource =
741b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        DataSource::CreateFromURI(httpService, path, headers);
755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (dataSource == NULL) {
775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ENOENT;
785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
80a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mIsWidevineExtractor = false;
811608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    if (!strncasecmp("widevine://", path, 11)) {
821608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        String8 mimeType;
831608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        float confidence;
841608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        sp<AMessage> dummy;
851608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        bool success = SniffWVM(dataSource, &mimeType, &confidence, &dummy);
861608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
871608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        if (!success
881608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber                || strcasecmp(
891608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
901608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber            return ERROR_UNSUPPORTED;
911608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        }
921608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
931608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        sp<WVMExtractor> extractor = new WVMExtractor(dataSource);
941608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        extractor->setAdaptiveStreamingMode(true);
951608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber
961608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        mImpl = extractor;
97a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        mIsWidevineExtractor = true;
981608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    } else {
991608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber        mImpl = MediaExtractor::Create(dataSource);
1001608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber    }
1015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mImpl == NULL) {
1035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10694c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    sp<MetaData> fileMeta = mImpl->getMetaData();
10794c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    const char *containerMime;
10894c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    if (fileMeta != NULL
10994c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber            && fileMeta->findCString(kKeyMIMEType, &containerMime)
11094c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber            && !strcasecmp(containerMime, "video/wvm")) {
11194c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        // We always want to use "cryptoPluginMode" when using the wvm
11294c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        // extractor. We can tell that it is this extractor by looking
11394c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        // at the container mime type.
11494c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        // The cryptoPluginMode ensures that the extractor will actually
11594c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        // give us data in a call to MediaSource::read(), unlike its
116e4d40ad91f3516bde106658673b2cb076b5dfcb7Lajos Molnar        // default mode that we used in AwesomePlayer.
117e4d40ad91f3516bde106658673b2cb076b5dfcb7Lajos Molnar        // TODO: change default mode
11894c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber        static_cast<WVMExtractor *>(mImpl.get())->setCryptoPluginMode(true);
1193499e2d178960ca3392855716c963eec7403a089James Dong    } else if (mImpl->getDrmFlag()) {
1203499e2d178960ca3392855716c963eec7403a089James Dong        // For all other drm content, we don't want to expose decrypted
1213499e2d178960ca3392855716c963eec7403a089James Dong        // content to Java application.
1223499e2d178960ca3392855716c963eec7403a089James Dong        mImpl.clear();
1233499e2d178960ca3392855716c963eec7403a089James Dong        mImpl = NULL;
1243499e2d178960ca3392855716c963eec7403a089James Dong        return ERROR_UNSUPPORTED;
12594c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber    }
12694c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber
127faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    status_t err = updateDurationAndBitrate();
128faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    if (err == OK) {
129faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar        mDataSource = dataSource;
130faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    }
131a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
1325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
135918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huberstatus_t NuMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) {
136fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen
13783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    ALOGV("setDataSource fd=%d (%s), offset=%lld, length=%lld",
13883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            fd, nameForFd(fd).c_str(), (long long) offset, (long long) size);
13983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen
140dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
141dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
142918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (mImpl != NULL) {
143918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        return -EINVAL;
144918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
145918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
146918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    sp<FileSource> fileSource = new FileSource(dup(fd), offset, size);
147918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
148fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    status_t err = fileSource->initCheck();
149fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    if (err != OK) {
150fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen        return err;
151fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    }
152fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen
153fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    mImpl = MediaExtractor::Create(fileSource);
154fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen
155fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    if (mImpl == NULL) {
156fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen        return ERROR_UNSUPPORTED;
157fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    }
158fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen
159faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    err = updateDurationAndBitrate();
160faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    if (err == OK) {
161faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar        mDataSource = fileSource;
162faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    }
163fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen
164fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen    return OK;
165dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen}
166dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen
167dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissenstatus_t NuMediaExtractor::setDataSource(const sp<DataSource> &source) {
168dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen    Mutex::Autolock autoLock(mLock);
169dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen
170dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen    if (mImpl != NULL) {
171dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen        return -EINVAL;
172dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen    }
173dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen
174dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen    status_t err = source->initCheck();
175918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (err != OK) {
176918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        return err;
177918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
178918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
179dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen    mImpl = MediaExtractor::Create(source);
180918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
181918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    if (mImpl == NULL) {
182918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber        return ERROR_UNSUPPORTED;
183918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber    }
184918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
185faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    err = updateDurationAndBitrate();
186faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    if (err == OK) {
187faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar        mDataSource = source;
188faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    }
189a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
190faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    return err;
191918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber}
192918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber
193faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnarstatus_t NuMediaExtractor::updateDurationAndBitrate() {
194faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    if (mImpl->countTracks() > kMaxTrackCount) {
195faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar        return ERROR_UNSUPPORTED;
196faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    }
197faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar
198a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mTotalBitrate = 0ll;
199a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    mDurationUs = -1ll;
200a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
201a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    for (size_t i = 0; i < mImpl->countTracks(); ++i) {
202a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        sp<MetaData> meta = mImpl->getTrackMetaData(i);
20359e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen        if (meta == NULL) {
20459e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen            ALOGW("no metadata for track %zu", i);
20559e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen            continue;
20659e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen        }
207a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
208a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        int32_t bitrate;
209a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        if (!meta->findInt32(kKeyBitRate, &bitrate)) {
210a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            const char *mime;
211a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            CHECK(meta->findCString(kKeyMIMEType, &mime));
212a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            ALOGV("track of type '%s' does not publish bitrate", mime);
213a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
214a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            mTotalBitrate = -1ll;
215a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        } else if (mTotalBitrate >= 0ll) {
216a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            mTotalBitrate += bitrate;
217a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        }
218a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
219a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        int64_t durationUs;
220a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        if (meta->findInt64(kKeyDuration, &durationUs)
221a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber                && durationUs > mDurationUs) {
222a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            mDurationUs = durationUs;
223a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        }
224a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
225faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    return OK;
226a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber}
227a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
2285778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t NuMediaExtractor::countTracks() const {
229dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
230dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mImpl == NULL ? 0 : mImpl->countTracks();
2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2345778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getTrackFormat(
235768a2537a86ac2f3513e42aafb5f3b8ee967ef6cLajos Molnar        size_t index, sp<AMessage> *format, uint32_t flags) const {
236dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
237dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *format = NULL;
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mImpl == NULL) {
2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mImpl->countTracks()) {
2455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
2465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
248768a2537a86ac2f3513e42aafb5f3b8ee967ef6cLajos Molnar    sp<MetaData> meta = mImpl->getTrackMetaData(index, flags);
249faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    // Extractors either support trackID-s or not, so either all tracks have trackIDs or none.
250faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    // Generate trackID if missing.
251faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    int32_t trackID;
252faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    if (meta != NULL && !meta->findInt32(kKeyTrackID, &trackID)) {
253faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar        meta->setInt32(kKeyTrackID, (int32_t)index + 1);
254faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    }
2559806555d3930be43e11106281dee354820ac1c88Andreas Huber    return convertMetaDataToMessage(meta, format);
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
258ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissenstatus_t NuMediaExtractor::getFileFormat(sp<AMessage> *format) const {
259ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    Mutex::Autolock autoLock(mLock);
260ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
261ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    *format = NULL;
262ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
263ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (mImpl == NULL) {
264ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        return -EINVAL;
265ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
266ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
267ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    sp<MetaData> meta = mImpl->getMetaData();
268ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
269ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    const char *mime;
270ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    CHECK(meta->findCString(kKeyMIMEType, &mime));
271ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    *format = new AMessage();
272ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    (*format)->setString("mime", mime);
273ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
274ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    uint32_t type;
275ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    const void *pssh;
276ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    size_t psshsize;
277ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    if (meta->findData(kKeyPssh, &type, &pssh, &psshsize)) {
278ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        sp<ABuffer> buf = new ABuffer(psshsize);
279ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        memcpy(buf->data(), pssh, psshsize);
280ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen        (*format)->setBuffer("pssh", buf);
281ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    }
282ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
283ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen    return OK;
284ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen}
285ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen
2865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::selectTrack(size_t index) {
287dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
288dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mImpl == NULL) {
2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mImpl->countTracks()) {
2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mTrackIndex == index) {
3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            // This track has already been selected.
3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
306b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    sp<IMediaSource> source = mImpl->getTrack(index);
3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ((status_t)OK, source->start());
3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mSelectedTracks.push();
3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1);
3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSource = source;
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mTrackIndex = index;
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mFinalResult = OK;
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSample = NULL;
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSampleTimeUs = -1ll;
318ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    info->mTrackFlags = 0;
3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const char *mime;
3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime));
3225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
324ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        info->mTrackFlags |= kIsVorbis;
3255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3309d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::unselectTrack(size_t index) {
3319d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    Mutex::Autolock autoLock(mLock);
3329d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3339d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (mImpl == NULL) {
3349d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        return -EINVAL;
3359d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
3369d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3379d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (index >= mImpl->countTracks()) {
3389d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        return -ERANGE;
3399d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
3409d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3419d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    size_t i;
3429d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    for (i = 0; i < mSelectedTracks.size(); ++i) {
3439d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
3449d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3459d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        if (info->mTrackIndex == index) {
3469d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber            break;
3479d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        }
3489d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
3499d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3509d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (i == mSelectedTracks.size()) {
3519d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        // Not selected.
3529d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        return OK;
3539d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
3549d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3559d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(i);
3569d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3579d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    if (info->mSample != NULL) {
3589d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        info->mSample->release();
3599d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        info->mSample = NULL;
3609d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3619d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        info->mSampleTimeUs = -1ll;
3629d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    }
3639d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3649d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    CHECK_EQ((status_t)OK, info->mSource->stop());
3659d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3669d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    mSelectedTracks.removeAt(i);
3679d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3689d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    return OK;
3699d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber}
3709d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber
3715778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuMediaExtractor::releaseTrackSamples() {
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mSample != NULL) {
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSample->release();
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSample = NULL;
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mSampleTimeUs = -1ll;
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3849d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberssize_t NuMediaExtractor::fetchTrackSamples(
3859d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        int64_t seekTimeUs, MediaSource::ReadOptions::SeekMode mode) {
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *minInfo = NULL;
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = -1;
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        TrackInfo *info = &mSelectedTracks.editItemAt(i);
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (seekTimeUs >= 0ll) {
3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mFinalResult = OK;
3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (info->mSample != NULL) {
3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSample->release();
3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSample = NULL;
3985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSampleTimeUs = -1ll;
3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (info->mFinalResult != OK) {
4015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            continue;
4025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mSample == NULL) {
4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            MediaSource::ReadOptions options;
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (seekTimeUs >= 0ll) {
4079d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber                options.setSeekTo(seekTimeUs, mode);
4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = info->mSource->read(&info->mSample, &options);
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (err != OK) {
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample == NULL);
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mFinalResult = err;
415bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
416bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                if (info->mFinalResult != ERROR_END_OF_STREAM) {
417a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                    ALOGW("read on track %zu failed with error %d",
418bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                          info->mTrackIndex, err);
419bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                }
420bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mSampleTimeUs = -1ll;
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                continue;
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample != NULL);
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(info->mSample->meta_data()->findInt64(
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            kKeyTime, &info->mSampleTimeUs));
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (minInfo == NULL  || info->mSampleTimeUs < minInfo->mSampleTimeUs) {
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            minInfo = info;
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            minIndex = i;
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return minIndex;
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4399d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::seekTo(
4409d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber        int64_t timeUs, MediaSource::ReadOptions::SeekMode mode) {
441dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
442dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
4439d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber    ssize_t minIndex = fetchTrackSamples(timeUs, mode);
4444835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber
4454835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber    if (minIndex < 0) {
4464835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber        return ERROR_END_OF_STREAM;
4474835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber    }
4484835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber
4494835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber    return OK;
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::advance() {
453dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
454dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSample->release();
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSample = NULL;
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mSampleTimeUs = -1ll;
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
470793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shihstatus_t NuMediaExtractor::appendVorbisNumPageSamples(TrackInfo *info, const sp<ABuffer> &buffer) {
471793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    int32_t numPageSamples;
472793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (!info->mSample->meta_data()->findInt32(
473793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih            kKeyValidSamples, &numPageSamples)) {
474793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        numPageSamples = -1;
475793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    }
476793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
477793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    memcpy((uint8_t *)buffer->data() + info->mSample->range_length(),
478793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih           &numPageSamples,
479793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih           sizeof(numPageSamples));
480793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
481793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    uint32_t type;
482793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    const void *data;
483793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    size_t size, size2;
484793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (info->mSample->meta_data()->findData(kKeyEncryptedSizes, &type, &data, &size)) {
485793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        // Signal numPageSamples (a plain int32_t) is appended at the end,
486793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        // i.e. sizeof(numPageSamples) plain bytes + 0 encrypted bytes
487793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        if (SIZE_MAX - size < sizeof(int32_t)) {
488793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih            return -ENOMEM;
489793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        }
490793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
491793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        size_t newSize = size + sizeof(int32_t);
492793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        sp<ABuffer> abuf = new ABuffer(newSize);
493793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        uint8_t *adata = static_cast<uint8_t *>(abuf->data());
494793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        if (adata == NULL) {
495793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih            return -ENOMEM;
496793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        }
497793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
498793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        // append 0 to encrypted sizes
499793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        int32_t zero = 0;
500793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        memcpy(adata, data, size);
501793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        memcpy(adata + size, &zero, sizeof(zero));
502793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        info->mSample->meta_data()->setData(kKeyEncryptedSizes, type, adata, newSize);
503793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
504793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        if (info->mSample->meta_data()->findData(kKeyPlainSizes, &type, &data, &size2)) {
505793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih            if (size2 != size) {
506793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih                return ERROR_MALFORMED;
507793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih            }
508793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih            memcpy(adata, data, size);
509793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        } else {
510793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih            // if sample meta data does not include plain size array, assume filled with zeros,
511793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih            // i.e. entire buffer is encrypted
512793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih            memset(adata, 0, size);
513793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        }
514793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        // append sizeof(numPageSamples) to plain sizes.
515793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        int32_t int32Size = sizeof(numPageSamples);
516793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        memcpy(adata + size, &int32Size, sizeof(int32Size));
517793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        info->mSample->meta_data()->setData(kKeyPlainSizes, type, adata, newSize);
518793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    }
519793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
520793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    return OK;
521793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih}
522793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
524dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
525dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t sampleSize = info->mSample->range_length();
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
536ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (info->mTrackFlags & kIsVorbis) {
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // Each sample's data is suffixed by the number of page samples
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // or -1 if not available.
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sampleSize += sizeof(int32_t);
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer->capacity() < sampleSize) {
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ENOMEM;
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const uint8_t *src =
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        (const uint8_t *)info->mSample->data()
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            + info->mSample->range_offset();
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    memcpy((uint8_t *)buffer->data(), src, info->mSample->range_length());
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
552793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    status_t err = OK;
553ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (info->mTrackFlags & kIsVorbis) {
554793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        err = appendVorbisNumPageSamples(info, buffer);
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
557793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (err == OK) {
558793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        buffer->setRange(0, sampleSize);
559793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    }
5605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
561793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    return err;
5625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTrackIndex(size_t *trackIndex) {
565dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
566dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
5675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
5685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
5715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *trackIndex = info->mTrackIndex;
5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
5775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTime(int64_t *sampleTimeUs) {
580dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
581dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
5825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t minIndex = fetchTrackSamples();
5835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minIndex < 0) {
5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_END_OF_STREAM;
5865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *sampleTimeUs = info->mSampleTimeUs;
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
594f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huberstatus_t NuMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) {
595dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
596dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
597f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber    *sampleMeta = NULL;
598f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber
599ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    ssize_t minIndex = fetchTrackSamples();
600ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
601ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (minIndex < 0) {
602ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return ERROR_END_OF_STREAM;
603ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
604ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
605ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
606f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber    *sampleMeta = info->mSample->meta_data();
607ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
608ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    return OK;
609ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
610ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
611a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getTotalBitrate(int64_t *bitrate) const {
612a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    if (mTotalBitrate >= 0) {
613a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *bitrate = mTotalBitrate;
614a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
615a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
616a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
617a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    off64_t size;
618a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    if (mDurationUs >= 0 && mDataSource->getSize(&size) == OK) {
619a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
620a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
621a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
622a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
623a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    return false;
624a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber}
625a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
626a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber// Returns true iff cached duration is available/applicable.
627a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getCachedDuration(
628a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        int64_t *durationUs, bool *eos) const {
629dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber    Mutex::Autolock autoLock(mLock);
630dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber
631a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    int64_t bitrate;
632a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    if (mIsWidevineExtractor) {
633a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        sp<WVMExtractor> wvmExtractor =
634a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            static_cast<WVMExtractor *>(mImpl.get());
635a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
636a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        status_t finalStatus;
637a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *durationUs = wvmExtractor->getCachedDurationUs(&finalStatus);
638a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *eos = (finalStatus != OK);
639a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
640a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    } else if ((mDataSource->flags() & DataSource::kIsCachingDataSource)
641a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            && getTotalBitrate(&bitrate)) {
642a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        sp<NuCachedSource2> cachedSource =
643a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            static_cast<NuCachedSource2 *>(mDataSource.get());
644a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
645a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        status_t finalStatus;
646a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        size_t cachedDataRemaining =
647a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber            cachedSource->approxDataRemaining(&finalStatus);
648a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
649a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
650a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        *eos = (finalStatus != OK);
651a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber        return true;
652a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    }
653a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
654a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber    return false;
655a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber}
656a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber
6575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
658