From 8d237a5ce1e3c1dbc1d538f47e68cff2cc52d799 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Mon, 13 Jul 2015 17:59:36 -0700 Subject: RTSP: clear data/eos status before returning from seek The original RTSP seek implementation involves pausing and restarting a session. This change clears data/eos status after an rtsp session is paused for a seek, and delays the seek to return after data/eos status are cleared. Bug: 22207372 Change-Id: I1bdf65653f90436f7ee5d7fe85eeadc1598a0d56 --- .../libmediaplayerservice/nuplayer/RTSPSource.cpp | 54 ++++++++++++++++++++-- media/libmediaplayerservice/nuplayer/RTSPSource.h | 3 ++ 2 files changed, 54 insertions(+), 3 deletions(-) (limited to 'media/libmediaplayerservice') diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp index 5210fc8..58ff113 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp @@ -138,7 +138,9 @@ void NuPlayer::RTSPSource::pause() { } void NuPlayer::RTSPSource::resume() { - mHandler->resume(); + if (mHandler != NULL) { + mHandler->resume(); + } } status_t NuPlayer::RTSPSource::feedMoreTSData() { @@ -295,13 +297,19 @@ status_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) { sp msg = new AMessage(kWhatPerformSeek, this); msg->setInt32("generation", ++mSeekGeneration); msg->setInt64("timeUs", seekTimeUs); - msg->post(200000ll); - return OK; + sp response; + status_t err = msg->postAndAwaitResponse(&response); + if (err == OK && response != NULL) { + CHECK(response->findInt32("err", &err)); + } + + return err; } void NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) { if (mState != CONNECTED) { + finishSeek(INVALID_OPERATION); return; } @@ -320,9 +328,11 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp &msg) { } else if (msg->what() == kWhatPerformSeek) { int32_t generation; CHECK(msg->findInt32("generation", &generation)); + CHECK(msg->senderAwaitsResponse(&mSeekReplyID)); if (generation != mSeekGeneration) { // obsolete. + finishSeek(OK); return; } @@ -368,6 +378,37 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp &msg) { case MyHandler::kWhatSeekDone: { mState = CONNECTED; + if (mSeekReplyID != NULL) { + // Unblock seekTo here in case we attempted to seek in a live stream + finishSeek(OK); + } + break; + } + + case MyHandler::kWhatSeekPaused: + { + sp source = getSource(true /* audio */); + if (source != NULL) { + source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE, + /* extra */ NULL, + /* discard */ true); + } + source = getSource(false /* video */); + if (source != NULL) { + source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE, + /* extra */ NULL, + /* discard */ true); + }; + + status_t err = OK; + msg->findInt32("err", &err); + finishSeek(err); + + if (err == OK) { + int64_t timeUs; + CHECK(msg->findInt64("time", &timeUs)); + mHandler->continueSeekAfterPause(timeUs); + } break; } @@ -700,5 +741,12 @@ bool NuPlayer::RTSPSource::stopBufferingIfNecessary() { return true; } +void NuPlayer::RTSPSource::finishSeek(status_t err) { + CHECK(mSeekReplyID != NULL); + sp seekReply = new AMessage; + seekReply->setInt32("err", err); + seekReply->postReply(mSeekReplyID); + mSeekReplyID = NULL; +} } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h index 5f2cf33..6438a1e 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.h +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h @@ -116,6 +116,8 @@ private: int64_t mEOSTimeoutAudio; int64_t mEOSTimeoutVideo; + sp mSeekReplyID; + sp getSource(bool audio); void onConnected(); @@ -131,6 +133,7 @@ private: void setError(status_t err); void startBufferingIfNecessary(); bool stopBufferingIfNecessary(); + void finishSeek(status_t err); DISALLOW_EVIL_CONSTRUCTORS(RTSPSource); }; -- cgit v1.1