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

Commit af7a7c34 authored by Andreas Huber's avatar Andreas Huber Committed by Android Git Automerger
Browse files

am cc4a38c6: Merge "Properly buffer a certain amount of data on streaming...

am cc4a38c6: Merge "Properly buffer a certain amount of data on streaming sources before finishing prepare()." into gingerbread

Merge commit 'cc4a38c6' into gingerbread-plus-aosp

* commit 'cc4a38c6':
  Properly buffer a certain amount of data on streaming sources before finishing prepare().
parents 3d7d3690 cc4a38c6
Loading
Loading
Loading
Loading
+116 −88
Original line number Original line Diff line number Diff line
@@ -50,6 +50,9 @@


namespace android {
namespace android {


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

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


void AwesomePlayer::onBufferingUpdate() {
// Returns true iff cached duration is available/applicable.
    Mutex::Autolock autoLock(mLock);
bool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
    if (!mBufferingEventPending) {
    off_t totalSize;
        return;
    }
    mBufferingEventPending = false;

    int kLowWaterMarkSecs = 2;
    int kHighWaterMarkSecs = 10;


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

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


        if ((mFlags & PLAYING) && !eos
        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(eos);
                && (queueDurationUs < kLowWaterMarkSecs * 1000000ll)) {
        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
            LOGI("rtsp cache is running low, pausing.");
        return true;
            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);
    }
    }


        postBufferingEvent_l();
    return false;
        return;
}
}


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


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


    size_t lowWatermark = 400000;
    size_t highWatermark = 1000000;

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


                notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
                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;
                if ((mFlags & PLAYING) && !eos
            highWatermark = kHighWaterMarkSecs * bitrate / 8;
                        && (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)) {
    int64_t cachedDurationUs;
        LOGI("cache is running low (< %d) , pausing.", lowWatermark);
    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;
            mFlags |= CACHE_UNDERRUN;
            pause_l();
            pause_l();
            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
    } else if ((mFlags & CACHE_UNDERRUN)
        } else if (eos || cachedDurationUs > kHighWaterMarkUs) {
            && (eos || cachedDataRemaining > highWatermark)) {
            if (mFlags & CACHE_UNDERRUN) {
        LOGI("cache has filled up (> %d), resuming.", highWatermark);
                LOGI("cache has filled up (%.2f secs), resuming.",
                     cachedDurationUs / 1E6);
                mFlags &= ~CACHE_UNDERRUN;
                mFlags &= ~CACHE_UNDERRUN;
                play_l();
                play_l();
                notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
                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();
    postBufferingEvent_l();
@@ -1437,7 +1463,6 @@ bool AwesomePlayer::ContinuePreparation(void *cookie) {
}
}


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


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


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


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

    postBufferingEvent_l();
}
}


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

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


    status_t finishSetDataSource_l();
    status_t finishSetDataSource_l();