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

Commit 4d8f66bc authored by Andreas Huber's avatar Andreas Huber
Browse files

Better support for buffered streaming of rtsp content, if buffer drops below a...

Better support for buffered streaming of rtsp content, if buffer drops below a certain threshold we will temporarily pause playback until we have sufficient data.

Change-Id: Ice8564e902e48c89c9c00f6651c5504b3c41fcad
related-to-bug: 2556656
parent 81f339bc
Loading
Loading
Loading
Loading
+29 −2
Original line number Diff line number Diff line
@@ -457,6 +457,33 @@ void AwesomePlayer::onBufferingUpdate() {
    }
    mBufferingEventPending = false;

    int kLowWaterMarkSecs = 2;
    int kHighWaterMarkSecs = 10;

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

        LOGV("queueDurationUs = %.2f secs", queueDurationUs / 1E6);

        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);
        }

        postBufferingEvent_l();
        return;
    }

    if (mCachedSource == NULL) {
        return;
    }
@@ -484,8 +511,8 @@ void AwesomePlayer::onBufferingUpdate() {

            notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);

            lowWatermark = 2 * bitrate / 8;  // 2 secs
            highWatermark = 10 * bitrate / 8;  // 10 secs
            lowWatermark = kLowWaterMarkSecs * bitrate / 8;
            highWatermark = kHighWaterMarkSecs * bitrate / 8;
        }
    }

+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ struct ARTSPController : public MediaExtractor {
            size_t index, uint32_t flags);

    int64_t getNormalPlayTimeUs();
    int64_t getQueueDurationUs(bool *eos);

    void onMessageReceived(const sp<AMessage> &msg);

+23 −0
Original line number Diff line number Diff line
@@ -746,4 +746,27 @@ void APacketSource::setNormalPlayTimeMapping(
    mNormalPlayTimeBaseUs = normalPlayTimeUs;
}

int64_t APacketSource::getQueueDurationUs(bool *eos) {
    Mutex::Autolock autoLock(mLock);

    *eos = (mEOSResult != OK);

    if (mBuffers.size() < 2) {
        return 0;
    }

    const sp<ABuffer> first = *mBuffers.begin();
    const sp<ABuffer> last = *--mBuffers.end();

    int64_t firstTimeUs;
    CHECK(first->meta()->findInt64("timeUs", &firstTimeUs));

    int64_t lastTimeUs;
    CHECK(last->meta()->findInt64("timeUs", &lastTimeUs));

    CHECK_GE(lastTimeUs, firstTimeUs);

    return lastTimeUs - firstTimeUs;
}

}  // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ struct APacketSource : public MediaSource {
    void setNormalPlayTimeMapping(
            uint32_t rtpTime, int64_t normalPlayTimeUs);

    int64_t getQueueDurationUs(bool *eos);

protected:
    virtual ~APacketSource();

+22 −0
Original line number Diff line number Diff line
@@ -143,4 +143,26 @@ int64_t ARTSPController::getNormalPlayTimeUs() {
    return mHandler->getNormalPlayTimeUs();
}

int64_t ARTSPController::getQueueDurationUs(bool *eos) {
    *eos = true;

    int64_t minQueuedDurationUs = 0;
    for (size_t i = 0; i < mHandler->countTracks(); ++i) {
        sp<APacketSource> source = mHandler->getPacketSource(i);

        bool newEOS;
        int64_t queuedDurationUs = source->getQueueDurationUs(&newEOS);

        if (!newEOS) {
            *eos = false;
        }

        if (i == 0 || queuedDurationUs < minQueuedDurationUs) {
            minQueuedDurationUs = queuedDurationUs;
        }
    }

    return minQueuedDurationUs;
}

}  // namespace android