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

Commit cfc30839 authored by Roger Jönsson's avatar Roger Jönsson Committed by Andreas Huber
Browse files

RTSP buffering improvements

Added buffering start and end notifications for RTSP.
MEDIA_INFO_BUFFERING_START is sent when buffering is started
and MEDIA_INFO_BUFFERING_END is sent when the buffer has
filled up.

This patch also adds RTSP end of stream handling.
EOS is signalled when BYE is received OR when
detecting end of stream even if no actual EOS is received.

Change-Id: I5cccb6845060ae6afd66d9f735b89da81476cd13
parent 0c3f0fa9
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1293,6 +1293,18 @@ void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
            break;
        }

        case Source::kWhatBufferingStart:
        {
            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
            break;
        }

        case Source::kWhatBufferingEnd:
        {
            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
            break;
        }

        default:
            TRESPASS();
    }
+6 −0
Original line number Diff line number Diff line
@@ -512,9 +512,15 @@ void NuPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) {
    entry.mFinalResult = finalResult;

    if (audio) {
        if (mAudioQueue.empty() && mSyncQueues) {
            syncQueuesDone();
        }
        mAudioQueue.push_back(entry);
        postDrainAudioQueue();
    } else {
        if (mVideoQueue.empty() && mSyncQueues) {
            syncQueuesDone();
        }
        mVideoQueue.push_back(entry);
        postDrainVideoQueue();
    }
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ struct NuPlayer::Source : public AHandler {
        kWhatPrepared,
        kWhatFlagsChanged,
        kWhatVideoSizeChanged,
        kWhatBufferingStart,
        kWhatBufferingEnd,
    };

    // The provides message is used to notify the player about various
+74 −6
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@

namespace android {

const int64_t kNearEOSTimeoutUs = 2000000ll; // 2 secs

NuPlayer::RTSPSource::RTSPSource(
        const sp<AMessage> &notify,
        const char *url,
@@ -45,8 +47,10 @@ NuPlayer::RTSPSource::RTSPSource(
      mState(DISCONNECTED),
      mFinalResult(OK),
      mDisconnectReplyID(0),
      mStartingUp(true),
      mSeekGeneration(0) {
      mBuffering(true),
      mSeekGeneration(0),
      mEOSTimeoutAudio(0),
      mEOSTimeoutVideo(0) {
    if (headers) {
        mExtraHeaders = *headers;

@@ -96,6 +100,10 @@ void NuPlayer::RTSPSource::prepareAsync() {

        mHandler->connect();
    }

    sp<AMessage> notifyStart = dupNotify();
    notifyStart->setInt32("what", kWhatBufferingStart);
    notifyStart->post();
}

void NuPlayer::RTSPSource::start() {
@@ -131,6 +139,13 @@ bool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() {

    static const int64_t kMinDurationUs = 2000000ll;

    int64_t mediaDurationUs = 0;
    getDuration(&mediaDurationUs);
    if ((mAudioTrack != NULL && mAudioTrack->isFinished(mediaDurationUs))
            || (mVideoTrack != NULL && mVideoTrack->isFinished(mediaDurationUs))) {
        return true;
    }

    status_t err;
    int64_t durationUs;
    if (mAudioTrack != NULL
@@ -156,12 +171,16 @@ bool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() {

status_t NuPlayer::RTSPSource::dequeueAccessUnit(
        bool audio, sp<ABuffer> *accessUnit) {
    if (mStartingUp) {
    if (mBuffering) {
        if (!haveSufficientDataOnAllTracks()) {
            return -EWOULDBLOCK;
        }

        mStartingUp = false;
        mBuffering = false;

        sp<AMessage> notify = dupNotify();
        notify->setInt32("what", kWhatBufferingEnd);
        notify->post();
    }

    sp<AnotherPacketSource> source = getSource(audio);
@@ -172,9 +191,51 @@ status_t NuPlayer::RTSPSource::dequeueAccessUnit(

    status_t finalResult;
    if (!source->hasBufferAvailable(&finalResult)) {
        return finalResult == OK ? -EWOULDBLOCK : finalResult;
        if (finalResult == OK) {
            int64_t mediaDurationUs = 0;
            getDuration(&mediaDurationUs);
            sp<AnotherPacketSource> otherSource = getSource(!audio);
            status_t otherFinalResult;

            // If other source already signaled EOS, this source should also signal EOS
            if (otherSource != NULL &&
                    !otherSource->hasBufferAvailable(&otherFinalResult) &&
                    otherFinalResult == ERROR_END_OF_STREAM) {
                source->signalEOS(ERROR_END_OF_STREAM);
                return ERROR_END_OF_STREAM;
            }

            // If this source has detected near end, give it some time to retrieve more
            // data before signaling EOS
            if (source->isFinished(mediaDurationUs)) {
                int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo;
                if (eosTimeout == 0) {
                    setEOSTimeout(audio, ALooper::GetNowUs());
                } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) {
                    setEOSTimeout(audio, 0);
                    source->signalEOS(ERROR_END_OF_STREAM);
                    return ERROR_END_OF_STREAM;
                }
                return -EWOULDBLOCK;
            }

            if (!(otherSource != NULL && otherSource->isFinished(mediaDurationUs))) {
                // We should not enter buffering mode
                // if any of the sources already have detected EOS.
                mBuffering = true;

                sp<AMessage> notify = dupNotify();
                notify->setInt32("what", kWhatBufferingStart);
                notify->post();
            }

            return -EWOULDBLOCK;
        }
        return finalResult;
    }

    setEOSTimeout(audio, 0);

    return source->dequeueAccessUnit(accessUnit);
}

@@ -189,6 +250,14 @@ sp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
    return audio ? mAudioTrack : mVideoTrack;
}

void NuPlayer::RTSPSource::setEOSTimeout(bool audio, int64_t timeout) {
    if (audio) {
        mEOSTimeoutAudio = timeout;
    } else {
        mEOSTimeoutVideo = timeout;
    }
}

status_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
    *durationUs = 0ll;

@@ -289,7 +358,6 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
        case MyHandler::kWhatSeekDone:
        {
            mState = CONNECTED;
            mStartingUp = true;
            break;
        }

+6 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ private:
    State mState;
    status_t mFinalResult;
    uint32_t mDisconnectReplyID;
    bool mStartingUp;
    bool mBuffering;

    sp<ALooper> mLooper;
    sp<AHandlerReflector<RTSPSource> > mReflector;
@@ -110,6 +110,9 @@ private:

    int32_t mSeekGeneration;

    int64_t mEOSTimeoutAudio;
    int64_t mEOSTimeoutVideo;

    sp<AnotherPacketSource> getSource(bool audio);

    void onConnected();
@@ -121,6 +124,8 @@ private:

    bool haveSufficientDataOnAllTracks();

    void setEOSTimeout(bool audio, int64_t timeout);

    DISALLOW_EVIL_CONSTRUCTORS(RTSPSource);
};

Loading