summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-10-07 13:40:45 -0700
committerAndreas Huber <andih@google.com>2011-10-10 12:41:21 -0700
commit49c59815369616b0fd5451ccabd377e8fe1dc3fa (patch)
tree90e8850990af78df26d7c0a1b7097747aa57fda2
parente87a2f05f39203dff8914b7612b1b2a709aeb75f (diff)
downloadframeworks_av-49c59815369616b0fd5451ccabd377e8fe1dc3fa.zip
frameworks_av-49c59815369616b0fd5451ccabd377e8fe1dc3fa.tar.gz
frameworks_av-49c59815369616b0fd5451ccabd377e8fe1dc3fa.tar.bz2
YouTube can now request custom cache/prefetch parameters and disconnect-at-highwater
through the use of pseudo http headers specified in the setDataSource call. x-cache-config: -1/-1/0 x-disconnect-at-highwatermark: 1 turns off keep-alives and disconnects every time the cache is full (will attempt to reconnect once it run below lowwater mark) related-to-bug: 5433309 Change-Id: Id2f942fc956e0e156834cfcd6bb08dae6a29fae1
-rw-r--r--media/libstagefright/AwesomePlayer.cpp10
-rw-r--r--media/libstagefright/NuCachedSource2.cpp58
-rw-r--r--media/libstagefright/include/NuCachedSource2.h12
3 files changed, 76 insertions, 4 deletions
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index fa9417a..1165af5 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -2005,6 +2005,11 @@ status_t AwesomePlayer::finishSetDataSource_l() {
mConnectingDataSource->setUID(mUID);
}
+ String8 cacheConfig;
+ bool disconnectAtHighwatermark;
+ NuCachedSource2::RemoveCacheSpecificHeaders(
+ &mUriHeaders, &cacheConfig, &disconnectAtHighwatermark);
+
mLock.unlock();
status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
mLock.lock();
@@ -2024,7 +2029,10 @@ status_t AwesomePlayer::finishSetDataSource_l() {
new ThrottledSource(
mConnectingDataSource, 50 * 1024 /* bytes/sec */));
#else
- mCachedSource = new NuCachedSource2(mConnectingDataSource);
+ mCachedSource = new NuCachedSource2(
+ mConnectingDataSource,
+ cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
+ disconnectAtHighwatermark);
#endif
dataSource = mCachedSource;
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 9adb841..4f183f5 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -177,7 +177,10 @@ void PageCache::copy(size_t from, void *data, size_t size) {
////////////////////////////////////////////////////////////////////////////////
-NuCachedSource2::NuCachedSource2(const sp<DataSource> &source)
+NuCachedSource2::NuCachedSource2(
+ const sp<DataSource> &source,
+ const char *cacheConfig,
+ bool disconnectAtHighwatermark)
: mSource(source),
mReflector(new AHandlerReflector<NuCachedSource2>(this)),
mLooper(new ALooper),
@@ -190,9 +193,24 @@ NuCachedSource2::NuCachedSource2(const sp<DataSource> &source)
mNumRetriesLeft(kMaxNumRetries),
mHighwaterThresholdBytes(kDefaultHighWaterThreshold),
mLowwaterThresholdBytes(kDefaultLowWaterThreshold),
- mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs) {
+ mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs),
+ mDisconnectAtHighwatermark(disconnectAtHighwatermark) {
+ // We are NOT going to support disconnect-at-highwatermark indefinitely
+ // and we are not guaranteeing support for client-specified cache
+ // parameters. Both of these are temporary measures to solve a specific
+ // problem that will be solved in a better way going forward.
+
updateCacheParamsFromSystemProperty();
+ if (cacheConfig != NULL) {
+ updateCacheParamsFromString(cacheConfig);
+ }
+
+ if (mDisconnectAtHighwatermark) {
+ // Makes no sense to disconnect and do keep-alives...
+ mKeepAliveIntervalUs = 0;
+ }
+
mLooper->setName("NuCachedSource2");
mLooper->registerHandler(mReflector);
mLooper->start();
@@ -339,6 +357,12 @@ void NuCachedSource2::onFetch() {
if (mFetching && mCache->totalSize() >= mHighwaterThresholdBytes) {
LOGI("Cache full, done prefetching for now");
mFetching = false;
+
+ if (mDisconnectAtHighwatermark
+ && (mSource->flags() & DataSource::kIsHTTPBasedSource)) {
+ LOGV("Disconnecting at high watermark");
+ static_cast<HTTPBase *>(mSource.get())->disconnect();
+ }
}
} else {
Mutex::Autolock autoLock(mLock);
@@ -637,4 +661,34 @@ void NuCachedSource2::updateCacheParamsFromString(const char *s) {
mKeepAliveIntervalUs);
}
+// static
+void NuCachedSource2::RemoveCacheSpecificHeaders(
+ KeyedVector<String8, String8> *headers,
+ String8 *cacheConfig,
+ bool *disconnectAtHighwatermark) {
+ *cacheConfig = String8();
+ *disconnectAtHighwatermark = false;
+
+ if (headers == NULL) {
+ return;
+ }
+
+ ssize_t index;
+ if ((index = headers->indexOfKey(String8("x-cache-config"))) >= 0) {
+ *cacheConfig = headers->valueAt(index);
+
+ headers->removeItemsAt(index);
+
+ LOGV("Using special cache config '%s'", cacheConfig->string());
+ }
+
+ if ((index = headers->indexOfKey(
+ String8("x-disconnect-at-highwatermark"))) >= 0) {
+ *disconnectAtHighwatermark = true;
+ headers->removeItemsAt(index);
+
+ LOGV("Client requested disconnection at highwater mark");
+ }
+}
+
} // namespace android
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index f04c566..7a03e7e 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -28,7 +28,10 @@ struct ALooper;
struct PageCache;
struct NuCachedSource2 : public DataSource {
- NuCachedSource2(const sp<DataSource> &source);
+ NuCachedSource2(
+ const sp<DataSource> &source,
+ const char *cacheConfig = NULL,
+ bool disconnectAtHighwatermark = false);
virtual status_t initCheck() const;
@@ -56,6 +59,11 @@ struct NuCachedSource2 : public DataSource {
status_t getEstimatedBandwidthKbps(int32_t *kbps);
status_t setCacheStatCollectFreq(int32_t freqMs);
+ static void RemoveCacheSpecificHeaders(
+ KeyedVector<String8, String8> *headers,
+ String8 *cacheConfig,
+ bool *disconnectAtHighwatermark);
+
protected:
virtual ~NuCachedSource2();
@@ -105,6 +113,8 @@ private:
// If the keep-alive interval is 0, keep-alives are disabled.
int64_t mKeepAliveIntervalUs;
+ bool mDisconnectAtHighwatermark;
+
void onMessageReceived(const sp<AMessage> &msg);
void onFetch();
void onRead(const sp<AMessage> &msg);