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

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

Merge "Properly buffer a certain amount of data on streaming sources before...

Merge "Properly buffer a certain amount of data on streaming sources before finishing prepare()." into gingerbread
parents e25b4bc7 87ab9cdd
Loading
Loading
Loading
Loading
+116 −88
Original line number Diff line number Diff line
@@ -50,6 +50,9 @@

namespace android {

static int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
static int64_t kHighWaterMarkUs = 10000000ll;  // 10secs

struct AwesomeEvent : public TimedEventQueue::Event {
    AwesomeEvent(
            AwesomePlayer *player,
@@ -450,50 +453,36 @@ void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
    }
}

void AwesomePlayer::onBufferingUpdate() {
    Mutex::Autolock autoLock(mLock);
    if (!mBufferingEventPending) {
        return;
    }
    mBufferingEventPending = false;

    int kLowWaterMarkSecs = 2;
    int kHighWaterMarkSecs = 10;
// Returns true iff cached duration is available/applicable.
bool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
    off_t totalSize;

    if (mRTSPController != NULL) {
        bool eos;
        int64_t queueDurationUs = mRTSPController->getQueueDurationUs(&eos);

        LOGV("queueDurationUs = %.2f secs", queueDurationUs / 1E6);
        *durationUs = mRTSPController->getQueueDurationUs(eos);
        return true;
    } else if (mCachedSource != NULL && mDurationUs >= 0
            && mCachedSource->getSize(&totalSize) == OK) {
        int64_t bitrate = totalSize * 8000000ll / mDurationUs;  // in bits/sec

        if ((mFlags & PLAYING) && !eos
                && (queueDurationUs < kLowWaterMarkSecs * 1000000ll)) {
            LOGI("rtsp cache is running low, pausing.");
            mFlags |= CACHE_UNDERRUN;
            pause_l();
            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
        } else if ((mFlags & CACHE_UNDERRUN)
                && (eos || queueDurationUs > kHighWaterMarkSecs * 1000000ll)) {
            LOGI("rtsp cache has filled up, resuming.");
            mFlags &= ~CACHE_UNDERRUN;
            play_l();
            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(eos);
        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
        return true;
    }

        postBufferingEvent_l();
        return;
    return false;
}

    if (mCachedSource == NULL) {
void AwesomePlayer::onBufferingUpdate() {
    Mutex::Autolock autoLock(mLock);
    if (!mBufferingEventPending) {
        return;
    }
    mBufferingEventPending = false;

    if (mCachedSource != NULL) {
        bool eos;
        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&eos);

    size_t lowWatermark = 400000;
    size_t highWatermark = 1000000;

        if (eos) {
            notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
        } else {
@@ -510,23 +499,60 @@ void AwesomePlayer::onBufferingUpdate() {
                }

                notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
            } else {
                // We don't know the bitrate of the stream, use absolute size
                // limits to maintain the cache.

                const size_t kLowWaterMarkBytes = 400000;
                const size_t kHighWaterMarkBytes = 1000000;

            lowWatermark = kLowWaterMarkSecs * bitrate / 8;
            highWatermark = kHighWaterMarkSecs * bitrate / 8;
                if ((mFlags & PLAYING) && !eos
                        && (cachedDataRemaining < kLowWaterMarkBytes)) {
                    LOGI("cache is running low (< %d) , pausing.",
                         kLowWaterMarkBytes);
                    mFlags |= CACHE_UNDERRUN;
                    pause_l();
                    notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
                } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
                    if (mFlags & CACHE_UNDERRUN) {
                        LOGI("cache has filled up (> %d), resuming.",
                             kHighWaterMarkBytes);
                        mFlags &= ~CACHE_UNDERRUN;
                        play_l();
                        notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
                    } else if (mFlags & PREPARING) {
                        LOGV("cache has filled up (> %d), prepare is done",
                             kHighWaterMarkBytes);
                        finishAsyncPrepare_l();
                    }
                }
            }
        }
    }

    if ((mFlags & PLAYING) && !eos && (cachedDataRemaining < lowWatermark)) {
        LOGI("cache is running low (< %d) , pausing.", lowWatermark);
    int64_t cachedDurationUs;
    bool eos;
    if (getCachedDuration_l(&cachedDurationUs, &eos)) {
        if ((mFlags & PLAYING) && !eos
                && (cachedDurationUs < kLowWaterMarkUs)) {
            LOGI("cache is running low (%.2f secs) , pausing.",
                 cachedDurationUs / 1E6);
            mFlags |= CACHE_UNDERRUN;
            pause_l();
            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
    } else if ((mFlags & CACHE_UNDERRUN)
            && (eos || cachedDataRemaining > highWatermark)) {
        LOGI("cache has filled up (> %d), resuming.", highWatermark);
        } else if (eos || cachedDurationUs > kHighWaterMarkUs) {
            if (mFlags & CACHE_UNDERRUN) {
                LOGI("cache has filled up (%.2f secs), resuming.",
                     cachedDurationUs / 1E6);
                mFlags &= ~CACHE_UNDERRUN;
                play_l();
                notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
            } else if (mFlags & PREPARING) {
                LOGV("cache has filled up (%.2f secs), prepare is done",
                     cachedDurationUs / 1E6);
                finishAsyncPrepare_l();
            }
        }
    }

    postBufferingEvent_l();
@@ -1437,7 +1463,6 @@ bool AwesomePlayer::ContinuePreparation(void *cookie) {
}

void AwesomePlayer::onPrepareAsyncEvent() {
    {
    Mutex::Autolock autoLock(mLock);

    if (mFlags & PREPARE_CANCELLED) {
@@ -1472,10 +1497,15 @@ void AwesomePlayer::onPrepareAsyncEvent() {
            return;
        }
    }
    }

    Mutex::Autolock autoLock(mLock);
    if (mCachedSource != NULL || mRTSPController != NULL) {
        postBufferingEvent_l();
    } else {
        finishAsyncPrepare_l();
    }
}

void AwesomePlayer::finishAsyncPrepare_l() {
    if (mIsAsyncPrepare) {
        if (mVideoWidth < 0 || mVideoHeight < 0) {
            notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
@@ -1491,8 +1521,6 @@ void AwesomePlayer::onPrepareAsyncEvent() {
    mFlags |= PREPARED;
    mAsyncPrepareEvent = NULL;
    mPreparedCondition.broadcast();

    postBufferingEvent_l();
}

status_t AwesomePlayer::suspend() {
+3 −0
Original line number Diff line number Diff line
@@ -238,6 +238,9 @@ private:
    void onCheckAudioStatus();
    void onPrepareAsyncEvent();
    void abortPrepare(status_t err);
    void finishAsyncPrepare_l();

    bool getCachedDuration_l(int64_t *durationUs, bool *eos);

    status_t finishSetDataSource_l();