diff options
author | Chong Zhang <chz@google.com> | 2014-08-22 21:18:41 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-08-22 21:18:41 +0000 |
commit | e61989593b2afec539f7d699e5b4c0bfdbca27d8 (patch) | |
tree | 4cd005e4b404641f5f8e933a9389ba9b71bf9fde /media | |
parent | 687ee2d4e0fcddc4af0b6ad1096ea330c23a85c4 (diff) | |
parent | b534f461f6056c84c3ae87e27430f4b934fd3eb1 (diff) | |
download | frameworks_av-e61989593b2afec539f7d699e5b4c0bfdbca27d8.zip frameworks_av-e61989593b2afec539f7d699e5b4c0bfdbca27d8.tar.gz frameworks_av-e61989593b2afec539f7d699e5b4c0bfdbca27d8.tar.bz2 |
am b534f461: Merge "move cache prefill to GenericSource\'s message handler" into lmp-dev
* commit 'b534f461f6056c84c3ae87e27430f4b934fd3eb1':
move cache prefill to GenericSource's message handler
Diffstat (limited to 'media')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.cpp | 147 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.h | 16 | ||||
-rw-r--r-- | media/libstagefright/DataSource.cpp | 77 |
3 files changed, 142 insertions, 98 deletions
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 76e1d54..3706117 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -32,6 +32,7 @@ #include <media/stagefright/MediaExtractor.h> #include <media/stagefright/MediaSource.h> #include <media/stagefright/MetaData.h> +#include "../../libstagefright/include/NuCachedSource2.h" #include "../../libstagefright/include/WVMExtractor.h" namespace android { @@ -47,7 +48,8 @@ NuPlayer::GenericSource::GenericSource( mAudioIsVorbis(false), mIsWidevine(false), mUIDValid(uidValid), - mUID(uid) { + mUID(uid), + mMetaDataSize(-1ll) { resetDataSource(); DataSource::RegisterDefaultSniffers(); } @@ -92,18 +94,18 @@ status_t NuPlayer::GenericSource::setDataSource( return OK; } -status_t NuPlayer::GenericSource::initFromDataSource( - const sp<DataSource> &dataSource, - const char* mime) { +status_t NuPlayer::GenericSource::initFromDataSource() { sp<MediaExtractor> extractor; + CHECK(mDataSource != NULL); + if (mIsWidevine) { String8 mimeType; float confidence; sp<AMessage> dummy; bool success; - success = SniffWVM(dataSource, &mimeType, &confidence, &dummy); + success = SniffWVM(mDataSource, &mimeType, &confidence, &dummy); if (!success || strcasecmp( mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) { @@ -111,14 +113,15 @@ status_t NuPlayer::GenericSource::initFromDataSource( return UNKNOWN_ERROR; } - sp<WVMExtractor> wvmExtractor = new WVMExtractor(dataSource); + sp<WVMExtractor> wvmExtractor = new WVMExtractor(mDataSource); wvmExtractor->setAdaptiveStreamingMode(true); if (mUIDValid) { wvmExtractor->setUID(mUID); } extractor = wvmExtractor; } else { - extractor = MediaExtractor::Create(dataSource, mime); + extractor = MediaExtractor::Create(mDataSource, + mSniffedMIME.empty() ? NULL: mSniffedMIME.c_str()); } if (extractor == NULL) { @@ -213,34 +216,49 @@ void NuPlayer::GenericSource::prepareAsync() { void NuPlayer::GenericSource::onPrepareAsync() { // delayed data source creation - AString sniffedMIME; - sp<DataSource> dataSource; + if (mDataSource == NULL) { + if (!mUri.empty()) { + mIsWidevine = !strncasecmp(mUri.c_str(), "widevine://", 11); - if (!mUri.empty()) { - mIsWidevine = !strncasecmp(mUri.c_str(), "widevine://", 11); + mDataSource = DataSource::CreateFromURI( + mHTTPService, mUri.c_str(), &mUriHeaders, &mContentType); + } else { + // set to false first, if the extractor + // comes back as secure, set it to true then. + mIsWidevine = false; - 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; + mDataSource = new FileSource(mFd, mOffset, mLength); + } + + if (mDataSource == NULL) { + ALOGE("Failed to create data source!"); + notifyPreparedAndCleanup(UNKNOWN_ERROR); + return; + } - dataSource = new FileSource(mFd, mOffset, mLength); + if (mDataSource->flags() & DataSource::kIsCachingDataSource) { + mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get()); + } } - if (dataSource == NULL) { - ALOGE("Failed to create data source!"); - notifyPrepared(UNKNOWN_ERROR); + // check initial caching status + status_t err = prefillCacheIfNecessary(); + if (err != OK) { + if (err == -EAGAIN) { + (new AMessage(kWhatPrepareAsync, id()))->post(200000); + } else { + ALOGE("Failed to prefill data cache!"); + notifyPreparedAndCleanup(UNKNOWN_ERROR); + } return; } - status_t err = initFromDataSource( - dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str()); + // init extrator from data source + err = initFromDataSource(); if (err != OK) { ALOGE("Failed to init from data source!"); - notifyPrepared(err); + notifyPreparedAndCleanup(err); return; } @@ -258,6 +276,87 @@ void NuPlayer::GenericSource::onPrepareAsync() { notifyPrepared(); } +void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) { + if (err != OK) { + mMetaDataSize = -1ll; + mContentType = ""; + mSniffedMIME = ""; + mDataSource.clear(); + mCachedSource.clear(); + } + notifyPrepared(err); +} + +status_t NuPlayer::GenericSource::prefillCacheIfNecessary() { + CHECK(mDataSource != NULL); + + if (mCachedSource == NULL) { + // no prefill if the data source is not cached + return OK; + } + + // We're not doing this for streams that appear to be audio-only + // streams to ensure that even low bandwidth streams start + // playing back fairly instantly. + if (!strncasecmp(mContentType.string(), "audio/", 6)) { + return OK; + } + + // We're going to prefill the cache before trying to instantiate + // the extractor below, as the latter is an operation that otherwise + // could block on the datasource for a significant amount of time. + // During that time we'd be unable to abort the preparation phase + // without this prefill. + + // Initially make sure we have at least 192 KB for the sniff + // to complete without blocking. + static const size_t kMinBytesForSniffing = 192 * 1024; + static const size_t kDefaultMetaSize = 200000; + + status_t finalStatus; + + size_t cachedDataRemaining = + mCachedSource->approxDataRemaining(&finalStatus); + + if (finalStatus != OK || (mMetaDataSize >= 0 + && (off64_t)cachedDataRemaining >= mMetaDataSize)) { + ALOGV("stop caching, status %d, " + "metaDataSize %lld, cachedDataRemaining %zu", + finalStatus, mMetaDataSize, cachedDataRemaining); + return OK; + } + + ALOGV("now cached %zu bytes of data", cachedDataRemaining); + + if (mMetaDataSize < 0 + && cachedDataRemaining >= kMinBytesForSniffing) { + String8 tmp; + float confidence; + sp<AMessage> meta; + if (!mCachedSource->sniff(&tmp, &confidence, &meta)) { + return UNKNOWN_ERROR; + } + + // We successfully identified the file's extractor to + // be, remember this mime type so we don't have to + // sniff it again when we call MediaExtractor::Create() + mSniffedMIME = tmp.string(); + + if (meta == NULL + || !meta->findInt64("meta-data-size", + reinterpret_cast<int64_t*>(&mMetaDataSize))) { + mMetaDataSize = kDefaultMetaSize; + } + + if (mMetaDataSize < 0ll) { + ALOGE("invalid metaDataSize = %lld bytes", mMetaDataSize); + return UNKNOWN_ERROR; + } + } + + return -EAGAIN; +} + void NuPlayer::GenericSource::start() { ALOGI("start"); diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index d3081de..946307c 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -33,6 +33,7 @@ struct DataSource; struct IMediaHTTPService; struct MediaSource; class MediaBuffer; +struct NuCachedSource2; struct NuPlayer::GenericSource : public NuPlayer::Source { GenericSource(const sp<AMessage> ¬ify, bool uidValid, uid_t uid); @@ -105,14 +106,21 @@ private: int64_t mOffset; int64_t mLength; - sp<ALooper> mLooper; + sp<DataSource> mDataSource; + sp<NuCachedSource2> mCachedSource; + String8 mContentType; + AString mSniffedMIME; + off64_t mMetaDataSize; + sp<ALooper> mLooper; void resetDataSource(); - status_t initFromDataSource( - const sp<DataSource> &dataSource, - const char *mime); + status_t initFromDataSource(); + + status_t prefillCacheIfNecessary(); + + void notifyPreparedAndCleanup(status_t err); void onPrepareAsync(); diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index 008da5a..9d6fd78 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -186,9 +186,9 @@ sp<DataSource> DataSource::CreateFromURI( const sp<IMediaHTTPService> &httpService, const char *uri, const KeyedVector<String8, String8> *headers, - AString *sniffedMIME) { - if (sniffedMIME != NULL) { - *sniffedMIME = ""; + String8 *contentType) { + if (contentType != NULL) { + *contentType = ""; } bool isWidevine = !strncasecmp("widevine://", uri, 11); @@ -226,77 +226,14 @@ sp<DataSource> DataSource::CreateFromURI( } if (!isWidevine) { - String8 contentType = httpSource->getMIMEType(); + if (contentType != NULL) { + *contentType = httpSource->getMIMEType(); + } - sp<NuCachedSource2> cachedSource = new NuCachedSource2( + source = new NuCachedSource2( httpSource, cacheConfig.isEmpty() ? NULL : cacheConfig.string(), disconnectAtHighwatermark); - - if (strncasecmp(contentType.string(), "audio/", 6)) { - // We're not doing this for streams that appear to be audio-only - // streams to ensure that even low bandwidth streams start - // playing back fairly instantly. - - // We're going to prefill the cache before trying to instantiate - // the extractor below, as the latter is an operation that otherwise - // could block on the datasource for a significant amount of time. - // During that time we'd be unable to abort the preparation phase - // without this prefill. - - // Initially make sure we have at least 192 KB for the sniff - // to complete without blocking. - static const size_t kMinBytesForSniffing = 192 * 1024; - - off64_t metaDataSize = -1ll; - for (;;) { - status_t finalStatus; - size_t cachedDataRemaining = - cachedSource->approxDataRemaining(&finalStatus); - - if (finalStatus != OK || (metaDataSize >= 0 - && (off64_t)cachedDataRemaining >= metaDataSize)) { - ALOGV("stop caching, status %d, " - "metaDataSize %lld, cachedDataRemaining %zu", - finalStatus, metaDataSize, cachedDataRemaining); - break; - } - - ALOGV("now cached %zu bytes of data", cachedDataRemaining); - - if (metaDataSize < 0 - && cachedDataRemaining >= kMinBytesForSniffing) { - String8 tmp; - float confidence; - sp<AMessage> meta; - if (!cachedSource->sniff(&tmp, &confidence, &meta)) { - return NULL; - } - - // We successfully identified the file's extractor to - // be, remember this mime type so we don't have to - // sniff it again when we call MediaExtractor::Create() - if (sniffedMIME != NULL) { - *sniffedMIME = tmp.string(); - } - - if (meta == NULL - || !meta->findInt64("meta-data-size", - reinterpret_cast<int64_t*>(&metaDataSize))) { - metaDataSize = kDefaultMetaSize; - } - - if (metaDataSize < 0ll) { - ALOGE("invalid metaDataSize = %lld bytes", metaDataSize); - return NULL; - } - } - - usleep(200000); - } - } - - source = cachedSource; } else { // We do not want that prefetching, caching, datasource wrapper // in the widevine:// case. |