summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorChong Zhang <chz@google.com>2014-08-22 21:01:40 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-08-22 21:01:41 +0000
commitb534f461f6056c84c3ae87e27430f4b934fd3eb1 (patch)
treed0fc2ce834f6c5aec73dff2569844b75f7b2e47a /media
parent89c4ab2f4e4fbccf5c67e2671cf252053dbe5d38 (diff)
parentd354d8d1b09503c0166c1f3e626cda72a3eeb83c (diff)
downloadframeworks_av-b534f461f6056c84c3ae87e27430f4b934fd3eb1.zip
frameworks_av-b534f461f6056c84c3ae87e27430f4b934fd3eb1.tar.gz
frameworks_av-b534f461f6056c84c3ae87e27430f4b934fd3eb1.tar.bz2
Merge "move cache prefill to GenericSource's message handler" into lmp-dev
Diffstat (limited to 'media')
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.cpp147
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.h16
-rw-r--r--media/libstagefright/DataSource.cpp77
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> &notify, 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.