From bf9b95d712a24b654761cb9fea0d94d383cfc661 Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Thu, 7 Aug 2014 15:35:07 -0700 Subject: delay data source creation for GenericSource prepare time Bug: 16708180 Change-Id: I9d578ef5e2edaed50279d28d3831c68556468f39 --- .../nuplayer/GenericSource.cpp | 80 ++++++++++++++++++---- .../libmediaplayerservice/nuplayer/GenericSource.h | 13 +++- media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 8 +-- 3 files changed, 80 insertions(+), 21 deletions(-) (limited to 'media') diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index a18407f..a39b546 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -21,6 +21,7 @@ #include "AnotherPacketSource.h" +#include #include #include #include @@ -47,33 +48,48 @@ NuPlayer::GenericSource::GenericSource( mIsWidevine(false), mUIDValid(uidValid), mUID(uid) { + resetDataSource(); DataSource::RegisterDefaultSniffers(); } -status_t NuPlayer::GenericSource::init( +void NuPlayer::GenericSource::resetDataSource() { + mHTTPService.clear(); + mUri.clear(); + mUriHeaders.clear(); + mFd = -1; + mOffset = 0; + mLength = 0; +} + +status_t NuPlayer::GenericSource::setDataSource( const sp &httpService, const char *url, const KeyedVector *headers) { - mIsWidevine = !strncasecmp(url, "widevine://", 11); - - AString sniffedMIME; + resetDataSource(); - sp dataSource = - DataSource::CreateFromURI(httpService, url, headers, &sniffedMIME); + mHTTPService = httpService; + mUri = url; - if (dataSource == NULL) { - return UNKNOWN_ERROR; + if (headers) { + mUriHeaders = *headers; } - return initFromDataSource( - dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str()); + // delay data source creation to prepareAsync() to avoid blocking + // the calling thread in setDataSource for any significant time. + return OK; } -status_t NuPlayer::GenericSource::init( +status_t NuPlayer::GenericSource::setDataSource( int fd, int64_t offset, int64_t length) { - sp dataSource = new FileSource(dup(fd), offset, length); + resetDataSource(); + + mFd = dup(fd); + mOffset = offset; + mLength = length; - return initFromDataSource(dataSource, NULL); + // delay data source creation to prepareAsync() to avoid blocking + // the calling thread in setDataSource for any significant time. + return OK; } status_t NuPlayer::GenericSource::initFromDataSource( @@ -143,7 +159,8 @@ status_t NuPlayer::GenericSource::initFromDataSource( // check if the source requires secure buffers int32_t secure; - if (meta->findInt32(kKeyRequiresSecureBuffers, &secure) && secure) { + if (meta->findInt32(kKeyRequiresSecureBuffers, &secure) + && secure) { mIsWidevine = true; if (mUIDValid) { extractor->setUID(mUID); @@ -166,7 +183,8 @@ status_t NuPlayer::GenericSource::initFromDataSource( return OK; } -status_t NuPlayer::GenericSource::setBuffers(bool audio, Vector &buffers) { +status_t NuPlayer::GenericSource::setBuffers( + bool audio, Vector &buffers) { if (mIsWidevine && !audio) { return mVideoTrack.mSource->setBuffers(buffers); } @@ -177,6 +195,38 @@ NuPlayer::GenericSource::~GenericSource() { } void NuPlayer::GenericSource::prepareAsync() { + // delayed data source creation + AString sniffedMIME; + sp dataSource; + + if (!mUri.empty()) { + mIsWidevine = !strncasecmp(mUri.c_str(), "widevine://", 11); + + dataSource = DataSource::CreateFromURI( + mHTTPService, mUri.c_str(), &mUriHeaders, &sniffedMIME); + } else { + // set to false first, if the extractor + // comes back as secure, set it to true then. + mIsWidevine = false; + + dataSource = new FileSource(mFd, mOffset, mLength); + } + + if (dataSource == NULL) { + ALOGE("Failed to create data source!"); + notifyPrepared(UNKNOWN_ERROR); + return; + } + + status_t err = initFromDataSource( + dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str()); + + if (err != OK) { + ALOGE("Failed to init from data source!"); + notifyPrepared(err); + return; + } + if (mVideoTrack.mSource != NULL) { sp meta = mVideoTrack.mSource->getFormat(); diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index 76e628b..44d690e 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -30,18 +30,19 @@ namespace android { struct AnotherPacketSource; struct ARTSPController; struct DataSource; +struct IMediaHTTPService; struct MediaSource; class MediaBuffer; struct NuPlayer::GenericSource : public NuPlayer::Source { GenericSource(const sp ¬ify, bool uidValid, uid_t uid); - status_t init( + status_t setDataSource( const sp &httpService, const char *url, const KeyedVector *headers); - status_t init(int fd, int64_t offset, int64_t length); + status_t setDataSource(int fd, int64_t offset, int64_t length); virtual void prepareAsync(); @@ -96,6 +97,14 @@ private: bool mIsWidevine; bool mUIDValid; uid_t mUID; + sp mHTTPService; + AString mUri; + KeyedVector mUriHeaders; + int mFd; + int64_t mOffset; + int64_t mLength; + + void resetDataSource(); status_t initFromDataSource( const sp &dataSource, diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index d56b1f0..0668600 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -232,12 +232,12 @@ void NuPlayer::setDataSourceAsync( // The correct flags will be updated in Source::kWhatFlagsChanged // handler when GenericSource is prepared. - status_t err = genericSource->init(httpService, url, headers); + status_t err = genericSource->setDataSource(httpService, url, headers); if (err == OK) { source = genericSource; } else { - ALOGE("Failed to initialize generic source!"); + ALOGE("Failed to set data source!"); } } msg->setObject("source", source); @@ -252,10 +252,10 @@ void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) { sp source = new GenericSource(notify, mUIDValid, mUID); - status_t err = source->init(fd, offset, length); + status_t err = source->setDataSource(fd, offset, length); if (err != OK) { - ALOGE("Failed to initialize generic source!"); + ALOGE("Failed to set data source!"); source = NULL; } -- cgit v1.1