NuMediaExtractor.cpp revision 9d07855aaff8a6b502a3ab058002cdd4a278b965
15778822d86b0337407514b9372562b86edfa91cdAndreas Huber/* 25778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Copyright 2012, The Android Open Source Project 35778822d86b0337407514b9372562b86edfa91cdAndreas Huber * 45778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 55778822d86b0337407514b9372562b86edfa91cdAndreas Huber * you may not use this file except in compliance with the License. 65778822d86b0337407514b9372562b86edfa91cdAndreas Huber * You may obtain a copy of the License at 75778822d86b0337407514b9372562b86edfa91cdAndreas Huber * 85778822d86b0337407514b9372562b86edfa91cdAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 95778822d86b0337407514b9372562b86edfa91cdAndreas Huber * 105778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Unless required by applicable law or agreed to in writing, software 115778822d86b0337407514b9372562b86edfa91cdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 125778822d86b0337407514b9372562b86edfa91cdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135778822d86b0337407514b9372562b86edfa91cdAndreas Huber * See the License for the specific language governing permissions and 145778822d86b0337407514b9372562b86edfa91cdAndreas Huber * limitations under the License. 155778822d86b0337407514b9372562b86edfa91cdAndreas Huber */ 165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 175778822d86b0337407514b9372562b86edfa91cdAndreas Huber//#define LOG_NDEBUG 0 185778822d86b0337407514b9372562b86edfa91cdAndreas Huber#define LOG_TAG "NuMediaExtractor" 195778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <utils/Log.h> 205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 215778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NuMediaExtractor.h> 225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 235778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "include/ESDS.h" 24a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber#include "include/NuCachedSource2.h" 251608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber#include "include/WVMExtractor.h" 265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 275778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 285778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h> 295778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h> 305778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/DataSource.h> 31918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber#include <media/stagefright/FileSource.h> 325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaBuffer.h> 335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaDefs.h> 345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h> 355778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaExtractor.h> 365778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaSource.h> 375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h> 385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/Utils.h> 395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 405778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android { 415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 42a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas HuberNuMediaExtractor::NuMediaExtractor() 43a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber : mIsWidevineExtractor(false), 44a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mTotalBitrate(-1ll), 45a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mDurationUs(-1ll) { 465778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 485778822d86b0337407514b9372562b86edfa91cdAndreas HuberNuMediaExtractor::~NuMediaExtractor() { 495778822d86b0337407514b9372562b86edfa91cdAndreas Huber releaseTrackSamples(); 505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 515778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < mSelectedTracks.size(); ++i) { 525778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 545778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ((status_t)OK, info->mSource->stop()); 555778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 575778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSelectedTracks.clear(); 585778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 60918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huberstatus_t NuMediaExtractor::setDataSource( 61918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber const char *path, const KeyedVector<String8, String8> *headers) { 62dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 63dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 64918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber if (mImpl != NULL) { 65918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber return -EINVAL; 66918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber } 67918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 681608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber sp<DataSource> dataSource = 691608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber DataSource::CreateFromURI(path, headers); 705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 715778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (dataSource == NULL) { 725778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ENOENT; 735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 75a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mIsWidevineExtractor = false; 761608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber if (!strncasecmp("widevine://", path, 11)) { 771608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber String8 mimeType; 781608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber float confidence; 791608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber sp<AMessage> dummy; 801608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber bool success = SniffWVM(dataSource, &mimeType, &confidence, &dummy); 811608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber 821608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber if (!success 831608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber || strcasecmp( 841608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) { 851608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber return ERROR_UNSUPPORTED; 861608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber } 871608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber 881608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber sp<WVMExtractor> extractor = new WVMExtractor(dataSource); 891608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber extractor->setAdaptiveStreamingMode(true); 901608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber 911608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber mImpl = extractor; 92a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mIsWidevineExtractor = true; 931608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber } else { 941608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber mImpl = MediaExtractor::Create(dataSource); 951608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber } 965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 975778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mImpl == NULL) { 985778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_UNSUPPORTED; 995778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 101a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mDataSource = dataSource; 102a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 103a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber updateDurationAndBitrate(); 104a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 1055778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 1065778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 1075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 108918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huberstatus_t NuMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) { 109dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 110dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 111918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber if (mImpl != NULL) { 112918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber return -EINVAL; 113918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber } 114918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 115918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber sp<FileSource> fileSource = new FileSource(dup(fd), offset, size); 116918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 117918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber status_t err = fileSource->initCheck(); 118918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber if (err != OK) { 119918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber return err; 120918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber } 121918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 122918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber mImpl = MediaExtractor::Create(fileSource); 123918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 124918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber if (mImpl == NULL) { 125918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber return ERROR_UNSUPPORTED; 126918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber } 127918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 128a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mDataSource = fileSource; 129a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 130a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber updateDurationAndBitrate(); 131a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 132918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber return OK; 133918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber} 134918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 135a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Hubervoid NuMediaExtractor::updateDurationAndBitrate() { 136a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mTotalBitrate = 0ll; 137a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mDurationUs = -1ll; 138a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 139a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber for (size_t i = 0; i < mImpl->countTracks(); ++i) { 140a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber sp<MetaData> meta = mImpl->getTrackMetaData(i); 141a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 142a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber int32_t bitrate; 143a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (!meta->findInt32(kKeyBitRate, &bitrate)) { 144a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber const char *mime; 145a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 146a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber ALOGV("track of type '%s' does not publish bitrate", mime); 147a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 148a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mTotalBitrate = -1ll; 149a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } else if (mTotalBitrate >= 0ll) { 150a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mTotalBitrate += bitrate; 151a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 152a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 153a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber int64_t durationUs; 154a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (meta->findInt64(kKeyDuration, &durationUs) 155a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber && durationUs > mDurationUs) { 156a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber mDurationUs = durationUs; 157a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 158a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 159a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber} 160a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 1615778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t NuMediaExtractor::countTracks() const { 162dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 163dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 1645778822d86b0337407514b9372562b86edfa91cdAndreas Huber return mImpl == NULL ? 0 : mImpl->countTracks(); 1655778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 1665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getTrackFormat( 1685778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index, sp<AMessage> *format) const { 169dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 170dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 1715778822d86b0337407514b9372562b86edfa91cdAndreas Huber *format = NULL; 1725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1735778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mImpl == NULL) { 1745778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 1755778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1775778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mImpl->countTracks()) { 1785778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 1795778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1815778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MetaData> meta = mImpl->getTrackMetaData(index); 1825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1835778822d86b0337407514b9372562b86edfa91cdAndreas Huber const char *mime; 1845778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 1855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1865778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> msg = new AMessage; 1875778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setString("mime", mime); 1885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 189918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber int64_t durationUs; 190918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber if (meta->findInt64(kKeyDuration, &durationUs)) { 191918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber msg->setInt64("durationUs", durationUs); 192918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber } 193918c7652b9a38c02e26c0c46541cea82070c0e43Andreas Huber 1945778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!strncasecmp("video/", mime, 6)) { 1955778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t width, height; 1965778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 1975778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 1985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1995778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("width", width); 2005778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("height", height); 201e370bb62b89d2f2980f519392010ea08a24c558eAndreas Huber } else if (!strncasecmp("audio/", mime, 6)) { 2025778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t numChannels, sampleRate; 2035778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 2045778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 2055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2065778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("channel-count", numChannels); 2075778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("sample-rate", sampleRate); 208ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 209ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber int32_t isADTS; 210ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (meta->findInt32(kKeyIsADTS, &isADTS)) { 211ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber msg->setInt32("is-adts", true); 212ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2135778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2155778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t maxInputSize; 2165778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 2175778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("max-input-size", maxInputSize); 2185778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2195778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2205778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t type; 2215778822d86b0337407514b9372562b86edfa91cdAndreas Huber const void *data; 2225778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size; 2235778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (meta->findData(kKeyAVCC, &type, &data, &size)) { 2245778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Parse the AVCDecoderConfigurationRecord 2255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2265778822d86b0337407514b9372562b86edfa91cdAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2285778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(size >= 7); 2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint8_t profile = ptr[1]; 2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint8_t level = ptr[3]; 2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber // There is decodable content out there that fails the following 2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber // assertion, let's be lenient for now... 2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber // CHECK((ptr[4] >> 2) == 0x3f); // reserved 2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t lengthSize = 1 + (ptr[4] & 3); 2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber // violates it... 2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber // CHECK((ptr[5] >> 5) == 7); // reserved 2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2435778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t numSeqParameterSets = ptr[5] & 31; 2445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2455778822d86b0337407514b9372562b86edfa91cdAndreas Huber ptr += 6; 2465778822d86b0337407514b9372562b86edfa91cdAndreas Huber size -= 6; 2475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2485778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<ABuffer> buffer = new ABuffer(1024); 2495778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->setRange(0, 0); 2505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2515778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 2525778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(size >= 2); 2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t length = U16_AT(ptr); 2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber ptr += 2; 2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber size -= 2; 2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2585778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(size >= length); 2595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2605778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 2615778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 2625778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->setRange(0, buffer->size() + 4 + length); 2635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2645778822d86b0337407514b9372562b86edfa91cdAndreas Huber ptr += length; 2655778822d86b0337407514b9372562b86edfa91cdAndreas Huber size -= length; 2665778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2685778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt32("csd", true); 2695778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt64("timeUs", 0); 2705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2712d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber msg->setBuffer("csd-0", buffer); 2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2735778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer = new ABuffer(1024); 2745778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->setRange(0, 0); 2755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2765778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(size >= 1); 2775778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t numPictureParameterSets = *ptr; 2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++ptr; 2795778822d86b0337407514b9372562b86edfa91cdAndreas Huber --size; 2805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < numPictureParameterSets; ++i) { 2825778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(size >= 2); 2835778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t length = U16_AT(ptr); 2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber ptr += 2; 2865778822d86b0337407514b9372562b86edfa91cdAndreas Huber size -= 2; 2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2885778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(size >= length); 2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->setRange(0, buffer->size() + 4 + length); 2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber ptr += length; 2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber size -= length; 2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt32("csd", true); 2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt64("timeUs", 0); 3002d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber msg->setBuffer("csd-1", buffer); 3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber ESDS esds((const char *)data, size); 3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(esds.InitCheck(), (status_t)OK); 3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber const void *codec_specific_data; 3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t codec_specific_data_size; 3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber esds.getCodecSpecificInfo( 3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber &codec_specific_data, &codec_specific_data_size); 3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy(buffer->data(), codec_specific_data, 3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber codec_specific_data_size); 3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt32("csd", true); 3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt64("timeUs", 0); 3172d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber msg->setBuffer("csd-0", buffer); 3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<ABuffer> buffer = new ABuffer(size); 3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy(buffer->data(), data, size); 3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3225778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt32("csd", true); 3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt64("timeUs", 0); 3242d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber msg->setBuffer("csd-0", buffer); 3255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) { 3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer = new ABuffer(size); 3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy(buffer->data(), data, size); 3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt32("csd", true); 3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt64("timeUs", 0); 3352d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber msg->setBuffer("csd-1", buffer); 3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber *format = msg; 3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3435778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::selectTrack(size_t index) { 344dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 345dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mImpl == NULL) { 3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mImpl->countTracks()) { 3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < mSelectedTracks.size(); ++i) { 3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mTrackIndex == index) { 3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber // This track has already been selected. 3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaSource> source = mImpl->getTrack(index); 3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ((status_t)OK, source->start()); 3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSelectedTracks.push(); 3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1); 3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSource = source; 3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mTrackIndex = index; 3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mFinalResult = OK; 3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 375ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info->mTrackFlags = 0; 3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber const char *mime; 3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime)); 3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) { 381ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info->mTrackFlags |= kIsVorbis; 3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3879d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::unselectTrack(size_t index) { 3889d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber Mutex::Autolock autoLock(mLock); 3899d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3909d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (mImpl == NULL) { 3919d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return -EINVAL; 3929d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3939d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3949d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (index >= mImpl->countTracks()) { 3959d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return -ERANGE; 3969d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 3979d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 3989d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber size_t i; 3999d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber for (i = 0; i < mSelectedTracks.size(); ++i) { 4009d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 4019d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 4029d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (info->mTrackIndex == index) { 4039d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber break; 4049d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 4059d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 4069d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 4079d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (i == mSelectedTracks.size()) { 4089d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber // Not selected. 4099d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return OK; 4109d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 4119d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 4129d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 4139d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 4149d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber if (info->mSample != NULL) { 4159d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber info->mSample->release(); 4169d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber info->mSample = NULL; 4179d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 4189d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber info->mSampleTimeUs = -1ll; 4199d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber } 4209d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 4219d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber CHECK_EQ((status_t)OK, info->mSource->stop()); 4229d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 4239d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber mSelectedTracks.removeAt(i); 4249d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 4259d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber return OK; 4269d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber} 4279d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber 4285778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuMediaExtractor::releaseTrackSamples() { 4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < mSelectedTracks.size(); ++i) { 4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mSample != NULL) { 4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample->release(); 4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4419d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberssize_t NuMediaExtractor::fetchTrackSamples( 4429d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber int64_t seekTimeUs, MediaSource::ReadOptions::SeekMode mode) { 4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *minInfo = NULL; 4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = -1; 4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < mSelectedTracks.size(); ++i) { 4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(i); 4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (seekTimeUs >= 0ll) { 4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mFinalResult = OK; 4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mSample != NULL) { 4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample->release(); 4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (info->mFinalResult != OK) { 4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber continue; 4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mSample == NULL) { 4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber MediaSource::ReadOptions options; 4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (seekTimeUs >= 0ll) { 4649d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber options.setSeekTo(seekTimeUs, mode); 4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = info->mSource->read(&info->mSample, &options); 4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mSample == NULL); 4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mFinalResult = err; 4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber continue; 4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mSample != NULL); 4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mSample->meta_data()->findInt64( 4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber kKeyTime, &info->mSampleTimeUs)); 4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minInfo == NULL || info->mSampleTimeUs < minInfo->mSampleTimeUs) { 4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber minInfo = info; 4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber minIndex = i; 4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber return minIndex; 4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4909d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huberstatus_t NuMediaExtractor::seekTo( 4919d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber int64_t timeUs, MediaSource::ReadOptions::SeekMode mode) { 492dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 493dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 4949d07855aaff8a6b502a3ab058002cdd4a278b965Andreas Huber ssize_t minIndex = fetchTrackSamples(timeUs, mode); 4954835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber 4964835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber if (minIndex < 0) { 4974835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber return ERROR_END_OF_STREAM; 4984835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber } 4994835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber 5004835705370584f6904c80afebcc6e8b9fdb110a5Andreas Huber return OK; 5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5035778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::advance() { 504dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 505dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = fetchTrackSamples(); 5075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5085778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minIndex < 0) { 5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_END_OF_STREAM; 5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5145778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample->release(); 5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSample = NULL; 5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mSampleTimeUs = -1ll; 5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) { 522dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 523dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = fetchTrackSamples(); 5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minIndex < 0) { 5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_END_OF_STREAM; 5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t sampleSize = info->mSample->range_length(); 5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 534ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (info->mTrackFlags & kIsVorbis) { 5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Each sample's data is suffixed by the number of page samples 5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber // or -1 if not available. 5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber sampleSize += sizeof(int32_t); 5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (buffer->capacity() < sampleSize) { 5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ENOMEM; 5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber const uint8_t *src = 5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber (const uint8_t *)info->mSample->data() 5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber + info->mSample->range_offset(); 5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy((uint8_t *)buffer->data(), src, info->mSample->range_length()); 5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 550ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (info->mTrackFlags & kIsVorbis) { 5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t numPageSamples; 5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!info->mSample->meta_data()->findInt32( 5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber kKeyValidSamples, &numPageSamples)) { 5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber numPageSamples = -1; 5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy((uint8_t *)buffer->data() + info->mSample->range_length(), 5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber &numPageSamples, 5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber sizeof(numPageSamples)); 5605778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5625778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->setRange(0, sampleSize); 5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 5655778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTrackIndex(size_t *trackIndex) { 568dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 569dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = fetchTrackSamples(); 5715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minIndex < 0) { 5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_END_OF_STREAM; 5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5765778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 5775778822d86b0337407514b9372562b86edfa91cdAndreas Huber *trackIndex = info->mTrackIndex; 5785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 5805778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5825778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t NuMediaExtractor::getSampleTime(int64_t *sampleTimeUs) { 583dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 584dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t minIndex = fetchTrackSamples(); 5865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (minIndex < 0) { 5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber return ERROR_END_OF_STREAM; 5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber *sampleTimeUs = info->mSampleTimeUs; 5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 597f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huberstatus_t NuMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) { 598dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 599dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 600f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber *sampleMeta = NULL; 601f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber 602ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ssize_t minIndex = fetchTrackSamples(); 603ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 604ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (minIndex < 0) { 605ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return ERROR_END_OF_STREAM; 606ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 607ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 608ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber TrackInfo *info = &mSelectedTracks.editItemAt(minIndex); 609f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber *sampleMeta = info->mSample->meta_data(); 610ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 611ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 612ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 613ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 614a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getTotalBitrate(int64_t *bitrate) const { 615a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (mTotalBitrate >= 0) { 616a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *bitrate = mTotalBitrate; 617a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 618a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 619a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 620a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber off64_t size; 621a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (mDurationUs >= 0 && mDataSource->getSize(&size) == OK) { 622a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *bitrate = size * 8000000ll / mDurationUs; // in bits/sec 623a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 624a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 625a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 626a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return false; 627a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber} 628a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 629a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber// Returns true iff cached duration is available/applicable. 630a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huberbool NuMediaExtractor::getCachedDuration( 631a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber int64_t *durationUs, bool *eos) const { 632dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber Mutex::Autolock autoLock(mLock); 633dc7431e70b4b030b5f42d0dfc3ef244d4f583dd2Andreas Huber 634a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber int64_t bitrate; 635a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber if (mIsWidevineExtractor) { 636a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber sp<WVMExtractor> wvmExtractor = 637a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber static_cast<WVMExtractor *>(mImpl.get()); 638a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 639a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber status_t finalStatus; 640a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *durationUs = wvmExtractor->getCachedDurationUs(&finalStatus); 641a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *eos = (finalStatus != OK); 642a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 643a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } else if ((mDataSource->flags() & DataSource::kIsCachingDataSource) 644a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber && getTotalBitrate(&bitrate)) { 645a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber sp<NuCachedSource2> cachedSource = 646a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber static_cast<NuCachedSource2 *>(mDataSource.get()); 647a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 648a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber status_t finalStatus; 649a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber size_t cachedDataRemaining = 650a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber cachedSource->approxDataRemaining(&finalStatus); 651a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 652a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *durationUs = cachedDataRemaining * 8000000ll / bitrate; 653a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber *eos = (finalStatus != OK); 654a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return true; 655a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber } 656a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 657a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber return false; 658a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber} 659a53d87c7b1428fe02f535c31dafd64cb1362fde9Andreas Huber 6605778822d86b0337407514b9372562b86edfa91cdAndreas Huber} // namespace android 661