NuMediaExtractor.cpp revision b2487f03f12dcafdb801fc0007c8df8412397f44
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( 611b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const sp<IMediaHTTPService> &httpService, 621b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const char *path, 631b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const KeyedVector<String8, String8> *headers) { 64dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 65dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 66918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber if (mImpl != NULL) { 67918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber return -EINVAL; 68918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber } 69918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 701608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber sp<DataSource> dataSource = 711b86fe063badb5f28c467ade39be0f4008688947Andreas Huber DataSource::CreateFromURI(httpService, path, headers); 725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 735778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (dataSource == NULL) { 745778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ENOENT; 755778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 77a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mIsWidevineExtractor = false; 781608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber if (!strncasecmp("widevine://", path, 11)) { 791608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber String8 mimeType; 801608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber float confidence; 811608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber sp<AMessage> dummy; 821608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber bool success = SniffWVM(dataSource, &mimeType, &confidence, &dummy); 831608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber 841608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber if (!success 851608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber || strcasecmp( 861608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) { 871608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber return ERROR_UNSUPPORTED; 881608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber } 891608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber 901608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber sp<WVMExtractor> extractor = new WVMExtractor(dataSource); 911608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber extractor->setAdaptiveStreamingMode(true); 921608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber 931608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber mImpl = extractor; 94a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mIsWidevineExtractor = true; 951608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber } else { 961608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber mImpl = MediaExtractor::Create(dataSource); 971608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber } 985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 995778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mImpl == NULL) { 1005778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_UNSUPPORTED; 1015778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10394c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber sp<MetaData> fileMeta = mImpl->getMetaData(); 10494c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber const char *containerMime; 10594c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber if (fileMeta != NULL 10694c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber && fileMeta->findCString(kKeyMIMEType, &containerMime) 10794c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber && !strcasecmp(containerMime, "video/wvm")) { 10894c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber // We always want to use "cryptoPluginMode" when using the wvm 10994c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber // extractor. We can tell that it is this extractor by looking 11094c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber // at the container mime type. 11194c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber // The cryptoPluginMode ensures that the extractor will actually 11294c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber // give us data in a call to MediaSource::read(), unlike its 11394c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber // default mode that we use from AwesomePlayer. 11494c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber static_cast<WVMExtractor *>(mImpl.get())->setCryptoPluginMode(true); 1153499e2d178960ca3392855716c963eec7403a089James Dong } else if (mImpl->getDrmFlag()) { 1163499e2d178960ca3392855716c963eec7403a089James Dong // For all other drm content, we don't want to expose decrypted 1173499e2d178960ca3392855716c963eec7403a089James Dong // content to Java application. 1183499e2d178960ca3392855716c963eec7403a089James Dong mImpl.clear(); 1193499e2d178960ca3392855716c963eec7403a089James Dong mImpl = NULL; 1203499e2d178960ca3392855716c963eec7403a089James Dong return ERROR_UNSUPPORTED; 12194c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber } 12294c1c8c99b70f2fdab87e131812eb253271e5500Andreas Huber 123a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mDataSource = dataSource; 124a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 125a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber updateDurationAndBitrate(); 126a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 1275778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 1285778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 1295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 130918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huberstatus_t NuMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) { 131fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen 13283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen ALOGV("setDataSource fd=%d (%s), offset=%lld, length=%lld", 13383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen fd, nameForFd(fd).c_str(), (long long) offset, (long long) size); 13483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen 135dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 136dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 137918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber if (mImpl != NULL) { 138918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber return -EINVAL; 139918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber } 140918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 141918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber sp<FileSource> fileSource = new FileSource(dup(fd), offset, size); 142918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 143fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen status_t err = fileSource->initCheck(); 144fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen if (err != OK) { 145fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen return err; 146fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen } 147fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen 148fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen mImpl = MediaExtractor::Create(fileSource); 149fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen 150fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen if (mImpl == NULL) { 151fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen return ERROR_UNSUPPORTED; 152fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen } 153fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen 154fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen mDataSource = fileSource; 155fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen 156fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen updateDurationAndBitrate(); 157fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen 158fd7ec80f3d0e30c8df61b86951d926ab9c8c6d25Marco Nelissen return OK; 159dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen} 160dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen 161dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissenstatus_t NuMediaExtractor::setDataSource(const sp<DataSource> &source) { 162dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen Mutex::Autolock autoLock(mLock); 163dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen 164dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen if (mImpl != NULL) { 165dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen return -EINVAL; 166dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen } 167dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen 168dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen status_t err = source->initCheck(); 169918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber if (err != OK) { 170918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber return err; 171918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber } 172918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 173dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen mImpl = MediaExtractor::Create(source); 174918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 175918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber if (mImpl == NULL) { 176918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber return ERROR_UNSUPPORTED; 177918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber } 178918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 179dbcb4c17f16230dfc6af908f176681c49f61b13eMarco Nelissen mDataSource = source; 180a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 181a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber updateDurationAndBitrate(); 182a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 183918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber return OK; 184918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber} 185918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 186a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Hubervoid NuMediaExtractor::updateDurationAndBitrate() { 187a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mTotalBitrate = 0ll; 188a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mDurationUs = -1ll; 189a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 190a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber for (size_t i = 0; i < mImpl->countTracks(); ++i) { 191a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber sp<MetaData> meta = mImpl->getTrackMetaData(i); 19259e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen if (meta == NULL) { 19359e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen ALOGW("no metadata for track %zu", i); 19459e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen continue; 19559e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen } 196a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 197a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber int32_t bitrate; 198a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (!meta->findInt32(kKeyBitRate, &bitrate)) { 199a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber const char *mime; 200a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 201a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber ALOGV("track of type '%s' does not publish bitrate", mime); 202a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 203a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mTotalBitrate = -1ll; 204a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } else if (mTotalBitrate >= 0ll) { 205a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mTotalBitrate += bitrate; 206a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 207a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 208a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber int64_t durationUs; 209a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (meta->findInt64(kKeyDuration, &durationUs) 210a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber && durationUs > mDurationUs) { 211a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mDurationUs = durationUs; 212a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 213a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 214a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber} 215a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 2165778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t NuMediaExtractor::countTracks() const { 217dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 218dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 2195778822d86b0337407514b9372562b86edfa91cdAndreas Huber return mImpl == NULL ? 0 : mImpl->countTracks(); 2205778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 2215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2225778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getTrackFormat( 2235778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index, sp<AMessage> *format) const { 224dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 225dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 2265778822d86b0337407514b9372562b86edfa91cdAndreas Huber *format = NULL; 2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2285778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mImpl == NULL) { 2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mImpl->countTracks()) { 2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MetaData> meta = mImpl->getTrackMetaData(index); 2379806555d3930be43e11106281dee354820ac1c88Andreas Huber return convertMetaDataToMessage(meta, format); 2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 240ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissenstatus_t NuMediaExtractor::getFileFormat(sp<AMessage> *format) const { 241ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen Mutex::Autolock autoLock(mLock); 242ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 243ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *format = NULL; 244ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 245ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (mImpl == NULL) { 246ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return -EINVAL; 247ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 248ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 249ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen sp<MetaData> meta = mImpl->getMetaData(); 250ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 251ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen const char *mime; 252ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen CHECK(meta->findCString(kKeyMIMEType, &mime)); 253ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen *format = new AMessage(); 254ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen (*format)->setString("mime", mime); 255ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 256ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen uint32_t type; 257ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen const void *pssh; 258ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen size_t psshsize; 259ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen if (meta->findData(kKeyPssh, &type, &pssh, &psshsize)) { 260ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen sp<ABuffer> buf = new ABuffer(psshsize); 261ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen memcpy(buf->data(), pssh, psshsize); 262ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen (*format)->setBuffer("pssh", buf); 263ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen } 264ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 265ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen return OK; 266ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen} 267ec77122351b4e78c1fe5b60a208f76baf8c67591Marco Nelissen 2685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::selectTrack(size_t index) { 269dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 270dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mImpl == NULL) { 2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 2735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2755778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mImpl->countTracks()) { 2765778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 2775778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2795778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < mSelectedTracks.size(); ++i) { 2805778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2825778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mTrackIndex == index) { 2835778822d86b0337407514b9372562b86edfa91cdAndreas Huber // This track has already been selected. 2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 288b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen sp<IMediaSource> source = mImpl->getTrack(index); 2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ((status_t)OK, source->start()); 2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSelectedTracks.push(); 2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1); 2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSource = source; 2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mTrackIndex = index; 2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mFinalResult = OK; 2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 300ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info->mTrackFlags = 0; 3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber const char *mime; 3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime)); 3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) { 306ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info->mTrackFlags |= kIsVorbis; 3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3129d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::unselectTrack(size_t index) { 3139d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber Mutex::Autolock autoLock(mLock); 3149d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3159d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (mImpl == NULL) { 3169d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return -EINVAL; 3179d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3189d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3199d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (index >= mImpl->countTracks()) { 3209d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return -ERANGE; 3219d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3229d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3239d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber size_t i; 3249d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber for (i = 0; i < mSelectedTracks.size(); ++i) { 3259d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 3269d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3279d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (info->mTrackIndex == index) { 3289d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber break; 3299d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3309d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3319d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3329d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (i == mSelectedTracks.size()) { 3339d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber // Not selected. 3349d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return OK; 3359d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3369d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3379d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 3389d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3399d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (info->mSample != NULL) { 3409d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber info->mSample->release(); 3419d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber info->mSample = NULL; 3429d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3439d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber info->mSampleTimeUs = -1ll; 3449d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3459d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3469d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber CHECK_EQ((status_t)OK, info->mSource->stop()); 3479d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3489d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber mSelectedTracks.removeAt(i); 3499d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3509d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return OK; 3519d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber} 3529d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3535778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuMediaExtractor::releaseTrackSamples() { 3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < mSelectedTracks.size(); ++i) { 3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mSample != NULL) { 3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample->release(); 3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3669d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberssize_t NuMediaExtractor::fetchTrackSamples( 3679d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber int64_t seekTimeUs, MediaSource::ReadOptions::SeekMode mode) { 3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *minInfo = NULL; 3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = -1; 3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < mSelectedTracks.size(); ++i) { 3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (seekTimeUs >= 0ll) { 3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mFinalResult = OK; 3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mSample != NULL) { 3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample->release(); 3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (info->mFinalResult != OK) { 3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber continue; 3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mSample == NULL) { 3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber MediaSource::ReadOptions options; 3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (seekTimeUs >= 0ll) { 3899d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber options.setSeekTo(seekTimeUs, mode); 3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = info->mSource->read(&info->mSample, &options); 3925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mSample == NULL); 3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mFinalResult = err; 397bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber 398bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber if (info->mFinalResult != ERROR_END_OF_STREAM) { 399a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGW("read on track %zu failed with error %d", 400bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber info->mTrackIndex, err); 401bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } 402bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber 4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber continue; 4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mSample != NULL); 4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mSample->meta_data()->findInt64( 4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber kKeyTime, &info->mSampleTimeUs)); 4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minInfo == NULL || info->mSampleTimeUs < minInfo->mSampleTimeUs) { 4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber minInfo = info; 4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber minIndex = i; 4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber return minIndex; 4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4219d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::seekTo( 4229d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber int64_t timeUs, MediaSource::ReadOptions::SeekMode mode) { 423dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 424dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 4259d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber ssize_t minIndex = fetchTrackSamples(timeUs, mode); 4264835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber 4274835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber if (minIndex < 0) { 4284835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber return ERROR_END_OF_STREAM; 4294835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber } 4304835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber 4314835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber return OK; 4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4345778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::advance() { 435dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 436dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = fetchTrackSamples(); 4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minIndex < 0) { 4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_END_OF_STREAM; 4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample->release(); 4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) { 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 size_t sampleSize = info->mSample->range_length(); 4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 465ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (info->mTrackFlags & kIsVorbis) { 4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Each sample's data is suffixed by the number of page samples 4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber // or -1 if not available. 4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber sampleSize += sizeof(int32_t); 4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (buffer->capacity() < sampleSize) { 4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ENOMEM; 4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber const uint8_t *src = 4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber (const uint8_t *)info->mSample->data() 4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber + info->mSample->range_offset(); 4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy((uint8_t *)buffer->data(), src, info->mSample->range_length()); 4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 481ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (info->mTrackFlags & kIsVorbis) { 4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t numPageSamples; 4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!info->mSample->meta_data()->findInt32( 4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber kKeyValidSamples, &numPageSamples)) { 4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber numPageSamples = -1; 4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy((uint8_t *)buffer->data() + info->mSample->range_length(), 4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber &numPageSamples, 4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber sizeof(numPageSamples)); 4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->setRange(0, sampleSize); 4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4985778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTrackIndex(size_t *trackIndex) { 499dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 500dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = fetchTrackSamples(); 5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minIndex < 0) { 5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_END_OF_STREAM; 5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5075778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 5085778822d86b0337407514b9372562b86edfa91cdAndreas Huber *trackIndex = info->mTrackIndex; 5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTime(int64_t *sampleTimeUs) { 514dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 515dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = fetchTrackSamples(); 5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minIndex < 0) { 5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_END_OF_STREAM; 5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5225778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber *sampleTimeUs = info->mSampleTimeUs; 5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 528f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huberstatus_t NuMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) { 529dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 530dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 531f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber *sampleMeta = NULL; 532f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber 533ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ssize_t minIndex = fetchTrackSamples(); 534ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 535ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (minIndex < 0) { 536ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return ERROR_END_OF_STREAM; 537ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 538ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 539ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 540f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber *sampleMeta = info->mSample->meta_data(); 541ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 542ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 543ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 544ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 545a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getTotalBitrate(int64_t *bitrate) const { 546a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (mTotalBitrate >= 0) { 547a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *bitrate = mTotalBitrate; 548a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 549a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 550a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 551a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber off64_t size; 552a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (mDurationUs >= 0 && mDataSource->getSize(&size) == OK) { 553a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *bitrate = size * 8000000ll / mDurationUs; // in bits/sec 554a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 555a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 556a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 557a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return false; 558a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber} 559a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 560a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber// Returns true iff cached duration is available/applicable. 561a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getCachedDuration( 562a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber int64_t *durationUs, bool *eos) const { 563dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 564dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 565a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber int64_t bitrate; 566a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (mIsWidevineExtractor) { 567a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber sp<WVMExtractor> wvmExtractor = 568a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber static_cast<WVMExtractor *>(mImpl.get()); 569a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 570a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber status_t finalStatus; 571a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *durationUs = wvmExtractor->getCachedDurationUs(&finalStatus); 572a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *eos = (finalStatus != OK); 573a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 574a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } else if ((mDataSource->flags() & DataSource::kIsCachingDataSource) 575a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber && getTotalBitrate(&bitrate)) { 576a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber sp<NuCachedSource2> cachedSource = 577a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber static_cast<NuCachedSource2 *>(mDataSource.get()); 578a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 579a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber status_t finalStatus; 580a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber size_t cachedDataRemaining = 581a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber cachedSource->approxDataRemaining(&finalStatus); 582a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 583a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *durationUs = cachedDataRemaining * 8000000ll / bitrate; 584a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *eos = (finalStatus != OK); 585a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 586a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 587a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 588a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return false; 589a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber} 590a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber} // namespace android 592