Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23950920 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Retry datasource fetches a few times before giving up (NuCachedSource2)."

parents da857bd9 178e8eb5
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include <sys/types.h>

#include <media/stagefright/MediaErrors.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
@@ -61,6 +62,10 @@ public:
        return 0;
    }

    virtual status_t reconnectAtOffset(off64_t offset) {
        return ERROR_UNSUPPORTED;
    }

    ////////////////////////////////////////////////////////////////////////////

    bool sniff(String8 *mimeType, float *confidence, sp<AMessage> *meta);
+54 −7
Original line number Diff line number Diff line
@@ -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;
+31 −3
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ struct ChromiumHTTPDataSource : public HTTPBase {

    virtual String8 getMIMEType() const;

    virtual status_t reconnectAtOffset(off64_t offset);

protected:
    virtual ~ChromiumHTTPDataSource();

+6 −0
Original line number Diff line number Diff line
@@ -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);