diff options
author | Andreas Huber <andih@google.com> | 2011-10-07 13:40:45 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2011-10-10 12:41:21 -0700 |
commit | 49c59815369616b0fd5451ccabd377e8fe1dc3fa (patch) | |
tree | 90e8850990af78df26d7c0a1b7097747aa57fda2 | |
parent | e87a2f05f39203dff8914b7612b1b2a709aeb75f (diff) | |
download | frameworks_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.cpp | 10 | ||||
-rw-r--r-- | media/libstagefright/NuCachedSource2.cpp | 58 | ||||
-rw-r--r-- | media/libstagefright/include/NuCachedSource2.h | 12 |
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); |