summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-07-18 13:47:55 -0700
committerAndreas Huber <andih@google.com>2011-07-22 08:17:41 -0700
commit0683eba6b35c396c21f10e926709f2f8fc05f090 (patch)
tree2cb1f37218e73941c6f7bb575bb972696e362ef4 /media
parent59d49c0b3b56b24c5b6d98cdfdcd75c537322f2e (diff)
downloadframeworks_av-0683eba6b35c396c21f10e926709f2f8fc05f090.zip
frameworks_av-0683eba6b35c396c21f10e926709f2f8fc05f090.tar.gz
frameworks_av-0683eba6b35c396c21f10e926709f2f8fc05f090.tar.bz2
Retry datasource fetches a few times before giving up (NuCachedSource2).
Change-Id: I147fc18ef55bc89d2e2fee69b7869c45abbfdd6b related-to-bug: 3405354
Diffstat (limited to 'media')
-rw-r--r--media/libstagefright/NuCachedSource2.cpp61
-rw-r--r--media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp34
-rw-r--r--media/libstagefright/include/ChromiumHTTPDataSource.h2
-rw-r--r--media/libstagefright/include/NuCachedSource2.h6
4 files changed, 93 insertions, 10 deletions
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 77a6602..4edb613 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -185,7 +185,8 @@ NuCachedSource2::NuCachedSource2(const sp<DataSource> &source)
mFinalStatus(OK),
mLastAccessPos(0),
mFetching(true),
- mLastFetchTimeUs(-1) {
+ mLastFetchTimeUs(-1),
+ mNumRetriesLeft(kMaxNumRetries) {
mLooper->setName("NuCachedSource2");
mLooper->registerHandler(mReflector);
mLooper->start();
@@ -254,7 +255,27 @@ void NuCachedSource2::onMessageReceived(const sp<AMessage> &msg) {
void NuCachedSource2::fetchInternal() {
LOGV("fetchInternal");
- CHECK_EQ(mFinalStatus, (status_t)OK);
+ {
+ Mutex::Autolock autoLock(mLock);
+ CHECK(mFinalStatus == OK || mNumRetriesLeft > 0);
+
+ if (mFinalStatus != OK) {
+ --mNumRetriesLeft;
+
+ status_t err =
+ mSource->reconnectAtOffset(mCacheOffset + mCache->totalSize());
+
+ if (err == ERROR_UNSUPPORTED) {
+ mNumRetriesLeft = 0;
+ return;
+ } else if (err != OK) {
+ LOGI("The attempt to reconnect failed, %d retries remaining",
+ mNumRetriesLeft);
+
+ return;
+ }
+ }
+ }
PageCache::Page *page = mCache->acquirePage();
@@ -264,14 +285,23 @@ void NuCachedSource2::fetchInternal() {
Mutex::Autolock autoLock(mLock);
if (n < 0) {
- LOGE("source returned error %ld", n);
+ LOGE("source returned error %ld, %d retries left", n, mNumRetriesLeft);
mFinalStatus = n;
mCache->releasePage(page);
} else if (n == 0) {
LOGI("ERROR_END_OF_STREAM");
+
+ mNumRetriesLeft = 0;
mFinalStatus = ERROR_END_OF_STREAM;
+
mCache->releasePage(page);
} else {
+ if (mFinalStatus != OK) {
+ LOGI("retrying a previously failed read succeeded.");
+ }
+ mNumRetriesLeft = kMaxNumRetries;
+ mFinalStatus = OK;
+
page->mSize = n;
mCache->appendPage(page);
}
@@ -280,7 +310,7 @@ void NuCachedSource2::fetchInternal() {
void NuCachedSource2::onFetch() {
LOGV("onFetch");
- if (mFinalStatus != OK) {
+ if (mFinalStatus != OK && mNumRetriesLeft == 0) {
LOGV("EOS reached, done prefetching for now");
mFetching = false;
}
@@ -308,8 +338,19 @@ void NuCachedSource2::onFetch() {
restartPrefetcherIfNecessary_l();
}
- (new AMessage(kWhatFetchMore, mReflector->id()))->post(
- mFetching ? 0 : 100000ll);
+ int64_t delayUs;
+ if (mFetching) {
+ if (mFinalStatus != OK && mNumRetriesLeft > 0) {
+ // We failed this time and will try again in 3 seconds.
+ delayUs = 3000000ll;
+ } else {
+ delayUs = 0;
+ }
+ } else {
+ delayUs = 100000ll;
+ }
+
+ (new AMessage(kWhatFetchMore, mReflector->id()))->post(delayUs);
}
void NuCachedSource2::onRead(const sp<AMessage> &msg) {
@@ -345,7 +386,7 @@ void NuCachedSource2::restartPrefetcherIfNecessary_l(
bool ignoreLowWaterThreshold, bool force) {
static const size_t kGrayArea = 1024 * 1024;
- if (mFetching || mFinalStatus != OK) {
+ if (mFetching || (mFinalStatus != OK && mNumRetriesLeft == 0)) {
return;
}
@@ -427,6 +468,12 @@ size_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) {
size_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) {
*finalStatus = mFinalStatus;
+
+ if (mFinalStatus != OK && mNumRetriesLeft > 0) {
+ // Pretend that everything is fine until we're out of retries.
+ *finalStatus = OK;
+ }
+
off64_t lastBytePosCached = mCacheOffset + mCache->totalSize();
if (mLastAccessPos < lastBytePosCached) {
return lastBytePosCached - mLastAccessPos;
diff --git a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
index 588a74d..07a9eb8 100644
--- a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
+++ b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
@@ -25,6 +25,8 @@
#include "support.h"
+#include <cutils/properties.h> // for property_get
+
namespace android {
ChromiumHTTPDataSource::ChromiumHTTPDataSource(uint32_t flags)
@@ -111,7 +113,7 @@ void ChromiumHTTPDataSource::onConnectionFailed(status_t err) {
mState = DISCONNECTED;
mCondition.broadcast();
- mURI.clear();
+ // mURI.clear();
mIOResult = err;
@@ -150,8 +152,18 @@ ssize_t ChromiumHTTPDataSource::readAt(off64_t offset, void *data, size_t size)
Mutex::Autolock autoLock(mLock);
if (mState != CONNECTED) {
- return ERROR_NOT_CONNECTED;
+ return INVALID_OPERATION;
+ }
+
+#if 0
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("media.stagefright.disable-net", value, 0)
+ && (!strcasecmp(value, "true") || !strcmp(value, "1"))) {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Simulating that the network is down.");
+ disconnect_l();
+ return ERROR_IO;
}
+#endif
if (offset != mCurrentOffset) {
AString tmp = mURI;
@@ -236,7 +248,7 @@ void ChromiumHTTPDataSource::onDisconnectComplete() {
CHECK_EQ((int)mState, (int)DISCONNECTING);
mState = DISCONNECTED;
- mURI.clear();
+ // mURI.clear();
mCondition.broadcast();
@@ -299,5 +311,21 @@ void ChromiumHTTPDataSource::clearDRMState_l() {
}
}
+status_t ChromiumHTTPDataSource::reconnectAtOffset(off64_t offset) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mURI.empty()) {
+ return INVALID_OPERATION;
+ }
+
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Reconnecting...");
+ status_t err = connect_l(mURI.c_str(), &mHeaders, offset);
+ if (err != OK) {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Reconnect failed w/ err 0x%08x", err);
+ }
+
+ return err;
+}
+
} // namespace android
diff --git a/media/libstagefright/include/ChromiumHTTPDataSource.h b/media/libstagefright/include/ChromiumHTTPDataSource.h
index d833e2e..18f8913 100644
--- a/media/libstagefright/include/ChromiumHTTPDataSource.h
+++ b/media/libstagefright/include/ChromiumHTTPDataSource.h
@@ -51,6 +51,8 @@ struct ChromiumHTTPDataSource : public HTTPBase {
virtual String8 getMIMEType() const;
+ virtual status_t reconnectAtOffset(off64_t offset);
+
protected:
virtual ~ChromiumHTTPDataSource();
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index 2d6cb84..22b2855 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -77,6 +77,10 @@ private:
kWhatRead = 'read',
};
+ enum {
+ kMaxNumRetries = 10,
+ };
+
sp<DataSource> mSource;
sp<AHandlerReflector<NuCachedSource2> > mReflector;
sp<ALooper> mLooper;
@@ -93,6 +97,8 @@ private:
bool mFetching;
int64_t mLastFetchTimeUs;
+ int32_t mNumRetriesLeft;
+
void onMessageReceived(const sp<AMessage> &msg);
void onFetch();
void onRead(const sp<AMessage> &msg);