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 308be03007574a1e303635b851613eda520c1475bb4Wei Jia if (source == nullptr) { 309be03007574a1e303635b851613eda520c1475bb4Wei Jia return ERROR_MALFORMED; 310be03007574a1e303635b851613eda520c1475bb4Wei Jia } 311be03007574a1e303635b851613eda520c1475bb4Wei Jia 3126db5763b0cc771278d3ee8ef1bcad945d6d2c430Marco Nelissen status_t ret = source->start(); 3136db5763b0cc771278d3ee8ef1bcad945d6d2c430Marco Nelissen if (ret != OK) { 3146db5763b0cc771278d3ee8ef1bcad945d6d2c430Marco Nelissen return ret; 3156db5763b0cc771278d3ee8ef1bcad945d6d2c430Marco Nelissen } 3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSelectedTracks.push(); 3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1); 3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSource = source; 3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mTrackIndex = index; 3225778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mFinalResult = OK; 3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 3245778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 325ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info->mTrackFlags = 0; 3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber const char *mime; 3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime)); 3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) { 331ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info->mTrackFlags |= kIsVorbis; 3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3379d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::unselectTrack(size_t index) { 3389d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber Mutex::Autolock autoLock(mLock); 3399d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3409d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (mImpl == NULL) { 3419d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return -EINVAL; 3429d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3439d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3449d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (index >= mImpl->countTracks()) { 3459d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return -ERANGE; 3469d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3479d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3489d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber size_t i; 3499d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber for (i = 0; i < mSelectedTracks.size(); ++i) { 3509d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 3519d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3529d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (info->mTrackIndex == index) { 3539d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber break; 3549d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3559d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3569d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3579d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (i == mSelectedTracks.size()) { 3589d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber // Not selected. 3599d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return OK; 3609d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3619d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3629d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 3639d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3649d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (info->mSample != NULL) { 3659d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber info->mSample->release(); 3669d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber info->mSample = NULL; 3679d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3689d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber info->mSampleTimeUs = -1ll; 3699d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3709d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3719d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber CHECK_EQ((status_t)OK, info->mSource->stop()); 3729d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3739d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber mSelectedTracks.removeAt(i); 3749d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3759d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return OK; 3769d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber} 3779d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3785778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuMediaExtractor::releaseTrackSamples() { 3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < mSelectedTracks.size(); ++i) { 3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mSample != NULL) { 3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample->release(); 3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3919d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberssize_t NuMediaExtractor::fetchTrackSamples( 3929d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber int64_t seekTimeUs, MediaSource::ReadOptions::SeekMode mode) { 3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *minInfo = NULL; 3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = -1; 3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < mSelectedTracks.size(); ++i) { 3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 3985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (seekTimeUs >= 0ll) { 4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mFinalResult = OK; 4015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4025778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mSample != NULL) { 4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample->release(); 4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (info->mFinalResult != OK) { 4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber continue; 4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mSample == NULL) { 4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber MediaSource::ReadOptions options; 4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (seekTimeUs >= 0ll) { 4149d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber options.setSeekTo(seekTimeUs, mode); 4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = info->mSource->read(&info->mSample, &options); 4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mSample == NULL); 4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mFinalResult = err; 422bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber 423bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber if (info->mFinalResult != ERROR_END_OF_STREAM) { 424a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGW("read on track %zu failed with error %d", 425bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber info->mTrackIndex, err); 426bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber } 427bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber 4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber continue; 4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mSample != NULL); 4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mSample->meta_data()->findInt64( 4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber kKeyTime, &info->mSampleTimeUs)); 4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minInfo == NULL || info->mSampleTimeUs < minInfo->mSampleTimeUs) { 4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber minInfo = info; 4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber minIndex = i; 4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber return minIndex; 4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4469d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::seekTo( 4479d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber int64_t timeUs, MediaSource::ReadOptions::SeekMode mode) { 448dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 449dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 4509d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber ssize_t minIndex = fetchTrackSamples(timeUs, mode); 4514835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber 4524835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber if (minIndex < 0) { 4534835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber return ERROR_END_OF_STREAM; 4544835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber } 4554835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber 4564835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber return OK; 4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::advance() { 460dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 461dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = fetchTrackSamples(); 4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minIndex < 0) { 4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_END_OF_STREAM; 4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample->release(); 4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 477793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shihstatus_t NuMediaExtractor::appendVorbisNumPageSamples(TrackInfo *info, const sp<ABuffer> &buffer) { 478793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih int32_t numPageSamples; 479793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih if (!info->mSample->meta_data()->findInt32( 480793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih kKeyValidSamples, &numPageSamples)) { 481793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih numPageSamples = -1; 482793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 483793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 484793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih memcpy((uint8_t *)buffer->data() + info->mSample->range_length(), 485793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih &numPageSamples, 486793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih sizeof(numPageSamples)); 487793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 488793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih uint32_t type; 489793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih const void *data; 490793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih size_t size, size2; 491793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih if (info->mSample->meta_data()->findData(kKeyEncryptedSizes, &type, &data, &size)) { 492793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih // Signal numPageSamples (a plain int32_t) is appended at the end, 493793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih // i.e. sizeof(numPageSamples) plain bytes + 0 encrypted bytes 494793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih if (SIZE_MAX - size < sizeof(int32_t)) { 495793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih return -ENOMEM; 496793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 497793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 498793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih size_t newSize = size + sizeof(int32_t); 499793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih sp<ABuffer> abuf = new ABuffer(newSize); 500793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih uint8_t *adata = static_cast<uint8_t *>(abuf->data()); 501793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih if (adata == NULL) { 502793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih return -ENOMEM; 503793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 504793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 505793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih // append 0 to encrypted sizes 506793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih int32_t zero = 0; 507793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih memcpy(adata, data, size); 508793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih memcpy(adata + size, &zero, sizeof(zero)); 509793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih info->mSample->meta_data()->setData(kKeyEncryptedSizes, type, adata, newSize); 510793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 511793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih if (info->mSample->meta_data()->findData(kKeyPlainSizes, &type, &data, &size2)) { 512793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih if (size2 != size) { 513793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih return ERROR_MALFORMED; 514793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 515793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih memcpy(adata, data, size); 516793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } else { 517793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih // if sample meta data does not include plain size array, assume filled with zeros, 518793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih // i.e. entire buffer is encrypted 519793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih memset(adata, 0, size); 520793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 521793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih // append sizeof(numPageSamples) to plain sizes. 522793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih int32_t int32Size = sizeof(numPageSamples); 523793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih memcpy(adata + size, &int32Size, sizeof(int32Size)); 524793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih info->mSample->meta_data()->setData(kKeyPlainSizes, type, adata, newSize); 525793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 526793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 527793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih return OK; 528793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih} 529793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 5305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) { 531dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 532dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = fetchTrackSamples(); 5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minIndex < 0) { 5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_END_OF_STREAM; 5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t sampleSize = info->mSample->range_length(); 5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 543ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (info->mTrackFlags & kIsVorbis) { 5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Each sample's data is suffixed by the number of page samples 5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber // or -1 if not available. 5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber sampleSize += sizeof(int32_t); 5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (buffer->capacity() < sampleSize) { 5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ENOMEM; 5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber const uint8_t *src = 5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber (const uint8_t *)info->mSample->data() 5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber + info->mSample->range_offset(); 5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy((uint8_t *)buffer->data(), src, info->mSample->range_length()); 5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 559793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih status_t err = OK; 560ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (info->mTrackFlags & kIsVorbis) { 561793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih err = appendVorbisNumPageSamples(info, buffer); 5625778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 564793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih if (err == OK) { 565793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih buffer->setRange(0, sampleSize); 566793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 5675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 568793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih return err; 5695778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5715778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTrackIndex(size_t *trackIndex) { 572dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 573dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = fetchTrackSamples(); 5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5765778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minIndex < 0) { 5775778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_END_OF_STREAM; 5785778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5805778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber *trackIndex = info->mTrackIndex; 5825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5835778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTime(int64_t *sampleTimeUs) { 587dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 588dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = fetchTrackSamples(); 5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minIndex < 0) { 5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_END_OF_STREAM; 5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber *sampleTimeUs = info->mSampleTimeUs; 5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 5995778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 601f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huberstatus_t NuMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) { 602dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 603dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 604f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber *sampleMeta = NULL; 605f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber 606ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ssize_t minIndex = fetchTrackSamples(); 607ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 608ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (minIndex < 0) { 609ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return ERROR_END_OF_STREAM; 610ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 611ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 612ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 613f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber *sampleMeta = info->mSample->meta_data(); 614ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 615ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 616ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 617ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 618a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getTotalBitrate(int64_t *bitrate) const { 619a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (mTotalBitrate >= 0) { 620a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *bitrate = mTotalBitrate; 621a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 622a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 623a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 624a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber off64_t size; 62536b04932bb93cc3269279282686b439a17a89920Marco Nelissen if (mDurationUs > 0 && mDataSource->getSize(&size) == OK) { 626a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *bitrate = size * 8000000ll / mDurationUs; // in bits/sec 627a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 628a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 629a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 630a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return false; 631a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber} 632a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 633a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber// Returns true iff cached duration is available/applicable. 634a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getCachedDuration( 635a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber int64_t *durationUs, bool *eos) const { 636dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 637dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 638a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber int64_t bitrate; 639a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (mIsWidevineExtractor) { 640a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber sp<WVMExtractor> wvmExtractor = 641a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber static_cast<WVMExtractor *>(mImpl.get()); 642a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 643a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber status_t finalStatus; 644a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *durationUs = wvmExtractor->getCachedDurationUs(&finalStatus); 645a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *eos = (finalStatus != OK); 646a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 647a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } else if ((mDataSource->flags() & DataSource::kIsCachingDataSource) 648a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber && getTotalBitrate(&bitrate)) { 649a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber sp<NuCachedSource2> cachedSource = 650a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber static_cast<NuCachedSource2 *>(mDataSource.get()); 651a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 652a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber status_t finalStatus; 653a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber size_t cachedDataRemaining = 654a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber cachedSource->approxDataRemaining(&finalStatus); 655a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 656a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *durationUs = cachedDataRemaining * 8000000ll / bitrate; 657a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *eos = (finalStatus != OK); 658a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 659a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 660a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 661a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return false; 662a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber} 663a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 6645778822d86b0337407514b9372562b86edfa91cdAndreas Huber} // namespace android 665