Loading media/libmediaplayerservice/nuplayer/RTSPSource.cpp +78 −24 Original line number Diff line number Diff line Loading @@ -32,6 +32,12 @@ namespace android { const int64_t kNearEOSTimeoutUs = 2000000ll; // 2 secs // Buffer Underflow/Prepare/StartServer/Overflow Marks const int64_t NuPlayer::RTSPSource::kUnderflowMarkUs = 1000000ll; const int64_t NuPlayer::RTSPSource::kPrepareMarkUs = 3000000ll; const int64_t NuPlayer::RTSPSource::kStartServerMarkUs = 5000000ll; const int64_t NuPlayer::RTSPSource::kOverflowMarkUs = 10000000ll; NuPlayer::RTSPSource::RTSPSource( const sp<AMessage> ¬ify, const sp<IMediaHTTPService> &httpService, Loading @@ -51,6 +57,7 @@ NuPlayer::RTSPSource::RTSPSource( mFinalResult(OK), mDisconnectReplyID(0), mBuffering(false), mInPreparationPhase(true), mSeekGeneration(0), mEOSTimeoutAudio(0), mEOSTimeoutVideo(0) { Loading Loading @@ -127,29 +134,6 @@ void NuPlayer::RTSPSource::stop() { msg->postAndAwaitResponse(&dummy); } void NuPlayer::RTSPSource::pause() { int64_t mediaDurationUs = 0; getDuration(&mediaDurationUs); for (size_t index = 0; index < mTracks.size(); index++) { TrackInfo *info = &mTracks.editItemAt(index); sp<AnotherPacketSource> source = info->mSource; // Check if EOS or ERROR is received if (source != NULL && source->isFinished(mediaDurationUs)) { return; } } if (mHandler != NULL) { mHandler->pause(); } } void NuPlayer::RTSPSource::resume() { if (mHandler != NULL) { mHandler->resume(); } } status_t NuPlayer::RTSPSource::feedMoreTSData() { Mutex::Autolock _l(mBufferingLock); return mFinalResult; Loading Loading @@ -324,6 +308,73 @@ void NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) { mHandler->seek(seekTimeUs); } void NuPlayer::RTSPSource::schedulePollBuffering() { sp<AMessage> msg = new AMessage(kWhatPollBuffering, this); msg->post(1000000ll); // 1 second intervals } void NuPlayer::RTSPSource::checkBuffering( bool *prepared, bool *underflow, bool *overflow, bool *startServer) { size_t numTracks = mTracks.size(); size_t preparedCount, underflowCount, overflowCount, startCount; preparedCount = underflowCount = overflowCount = startCount = 0; for (size_t i = 0; i < numTracks; ++i) { status_t finalResult; TrackInfo *info = &mTracks.editItemAt(i); sp<AnotherPacketSource> src = info->mSource; int64_t bufferedDurationUs = src->getBufferedDurationUs(&finalResult); // isFinished when duration is 0 checks for EOS result only if (bufferedDurationUs > kPrepareMarkUs || src->isFinished(/* duration */ 0)) { ++preparedCount; } if (src->isFinished(/* duration */ 0)) { ++overflowCount; } else { if (bufferedDurationUs < kUnderflowMarkUs) { ++underflowCount; } if (bufferedDurationUs > kOverflowMarkUs) { ++overflowCount; } if (bufferedDurationUs < kStartServerMarkUs) { ++startCount; } } } *prepared = (preparedCount == numTracks); *underflow = (underflowCount > 0); *overflow = (overflowCount == numTracks); *startServer = (startCount > 0); } void NuPlayer::RTSPSource::onPollBuffering() { bool prepared, underflow, overflow, startServer; checkBuffering(&prepared, &underflow, &overflow, &startServer); if (prepared && mInPreparationPhase) { mInPreparationPhase = false; notifyPrepared(); } if (!mInPreparationPhase && underflow) { startBufferingIfNecessary(); } if (overflow && mHandler != NULL) { stopBufferingIfNecessary(); mHandler->pause(); } if (startServer && mHandler != NULL) { mHandler->resume(); } schedulePollBuffering(); } void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { if (msg->what() == kWhatDisconnect) { sp<AReplyToken> replyID; Loading @@ -348,6 +399,9 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { performSeek(seekTimeUs); return; } else if (msg->what() == kWhatPollBuffering) { onPollBuffering(); return; } CHECK_EQ(msg->what(), (int)kWhatNotify); Loading @@ -372,7 +426,7 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { } notifyFlagsChanged(flags); notifyPrepared(); schedulePollBuffering(); break; } Loading media/libmediaplayerservice/nuplayer/RTSPSource.h +11 −2 Original line number Diff line number Diff line Loading @@ -43,8 +43,6 @@ struct NuPlayer::RTSPSource : public NuPlayer::Source { virtual void prepareAsync(); virtual void start(); virtual void stop(); virtual void pause(); virtual void resume(); virtual status_t feedMoreTSData(); Loading @@ -65,6 +63,7 @@ private: kWhatNotify = 'noti', kWhatDisconnect = 'disc', kWhatPerformSeek = 'seek', kWhatPollBuffering = 'poll', }; enum State { Loading @@ -79,6 +78,12 @@ private: kFlagIncognito = 1, }; // Buffer Prepare/Underflow/Overflow/Resume Marks static const int64_t kPrepareMarkUs; static const int64_t kUnderflowMarkUs; static const int64_t kOverflowMarkUs; static const int64_t kStartServerMarkUs; struct TrackInfo { sp<AnotherPacketSource> mSource; Loading @@ -100,6 +105,7 @@ private: sp<AReplyToken> mDisconnectReplyID; Mutex mBufferingLock; bool mBuffering; bool mInPreparationPhase; sp<ALooper> mLooper; sp<MyHandler> mHandler; Loading @@ -126,6 +132,9 @@ private: void finishDisconnectIfPossible(); void performSeek(int64_t seekTimeUs); void schedulePollBuffering(); void checkBuffering(bool *prepared, bool *underflow, bool *overflow, bool *startServer); void onPollBuffering(); bool haveSufficientDataOnAllTracks(); Loading media/libstagefright/rtsp/MyHandler.h +12 −1 Original line number Diff line number Diff line Loading @@ -235,7 +235,7 @@ struct MyHandler : public AHandler { sp<AMessage> msg = new AMessage('paus', this); mPauseGeneration++; msg->setInt32("pausecheck", mPauseGeneration); msg->post(kPauseDelayUs); msg->post(); } void resume() { Loading Loading @@ -979,6 +979,11 @@ struct MyHandler : public AHandler { case 'accu': { if (mSeekPending) { ALOGV("Stale access unit."); break; } int32_t timeUpdate; if (msg->findInt32("time-update", &timeUpdate) && timeUpdate) { size_t trackIndex; Loading Loading @@ -1070,6 +1075,12 @@ struct MyHandler : public AHandler { ALOGW("This is a live stream, ignoring pause request."); break; } if (mPausing) { ALOGV("This stream is already paused."); break; } mCheckPending = true; ++mCheckGeneration; mPausing = true; Loading Loading
media/libmediaplayerservice/nuplayer/RTSPSource.cpp +78 −24 Original line number Diff line number Diff line Loading @@ -32,6 +32,12 @@ namespace android { const int64_t kNearEOSTimeoutUs = 2000000ll; // 2 secs // Buffer Underflow/Prepare/StartServer/Overflow Marks const int64_t NuPlayer::RTSPSource::kUnderflowMarkUs = 1000000ll; const int64_t NuPlayer::RTSPSource::kPrepareMarkUs = 3000000ll; const int64_t NuPlayer::RTSPSource::kStartServerMarkUs = 5000000ll; const int64_t NuPlayer::RTSPSource::kOverflowMarkUs = 10000000ll; NuPlayer::RTSPSource::RTSPSource( const sp<AMessage> ¬ify, const sp<IMediaHTTPService> &httpService, Loading @@ -51,6 +57,7 @@ NuPlayer::RTSPSource::RTSPSource( mFinalResult(OK), mDisconnectReplyID(0), mBuffering(false), mInPreparationPhase(true), mSeekGeneration(0), mEOSTimeoutAudio(0), mEOSTimeoutVideo(0) { Loading Loading @@ -127,29 +134,6 @@ void NuPlayer::RTSPSource::stop() { msg->postAndAwaitResponse(&dummy); } void NuPlayer::RTSPSource::pause() { int64_t mediaDurationUs = 0; getDuration(&mediaDurationUs); for (size_t index = 0; index < mTracks.size(); index++) { TrackInfo *info = &mTracks.editItemAt(index); sp<AnotherPacketSource> source = info->mSource; // Check if EOS or ERROR is received if (source != NULL && source->isFinished(mediaDurationUs)) { return; } } if (mHandler != NULL) { mHandler->pause(); } } void NuPlayer::RTSPSource::resume() { if (mHandler != NULL) { mHandler->resume(); } } status_t NuPlayer::RTSPSource::feedMoreTSData() { Mutex::Autolock _l(mBufferingLock); return mFinalResult; Loading Loading @@ -324,6 +308,73 @@ void NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) { mHandler->seek(seekTimeUs); } void NuPlayer::RTSPSource::schedulePollBuffering() { sp<AMessage> msg = new AMessage(kWhatPollBuffering, this); msg->post(1000000ll); // 1 second intervals } void NuPlayer::RTSPSource::checkBuffering( bool *prepared, bool *underflow, bool *overflow, bool *startServer) { size_t numTracks = mTracks.size(); size_t preparedCount, underflowCount, overflowCount, startCount; preparedCount = underflowCount = overflowCount = startCount = 0; for (size_t i = 0; i < numTracks; ++i) { status_t finalResult; TrackInfo *info = &mTracks.editItemAt(i); sp<AnotherPacketSource> src = info->mSource; int64_t bufferedDurationUs = src->getBufferedDurationUs(&finalResult); // isFinished when duration is 0 checks for EOS result only if (bufferedDurationUs > kPrepareMarkUs || src->isFinished(/* duration */ 0)) { ++preparedCount; } if (src->isFinished(/* duration */ 0)) { ++overflowCount; } else { if (bufferedDurationUs < kUnderflowMarkUs) { ++underflowCount; } if (bufferedDurationUs > kOverflowMarkUs) { ++overflowCount; } if (bufferedDurationUs < kStartServerMarkUs) { ++startCount; } } } *prepared = (preparedCount == numTracks); *underflow = (underflowCount > 0); *overflow = (overflowCount == numTracks); *startServer = (startCount > 0); } void NuPlayer::RTSPSource::onPollBuffering() { bool prepared, underflow, overflow, startServer; checkBuffering(&prepared, &underflow, &overflow, &startServer); if (prepared && mInPreparationPhase) { mInPreparationPhase = false; notifyPrepared(); } if (!mInPreparationPhase && underflow) { startBufferingIfNecessary(); } if (overflow && mHandler != NULL) { stopBufferingIfNecessary(); mHandler->pause(); } if (startServer && mHandler != NULL) { mHandler->resume(); } schedulePollBuffering(); } void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { if (msg->what() == kWhatDisconnect) { sp<AReplyToken> replyID; Loading @@ -348,6 +399,9 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { performSeek(seekTimeUs); return; } else if (msg->what() == kWhatPollBuffering) { onPollBuffering(); return; } CHECK_EQ(msg->what(), (int)kWhatNotify); Loading @@ -372,7 +426,7 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { } notifyFlagsChanged(flags); notifyPrepared(); schedulePollBuffering(); break; } Loading
media/libmediaplayerservice/nuplayer/RTSPSource.h +11 −2 Original line number Diff line number Diff line Loading @@ -43,8 +43,6 @@ struct NuPlayer::RTSPSource : public NuPlayer::Source { virtual void prepareAsync(); virtual void start(); virtual void stop(); virtual void pause(); virtual void resume(); virtual status_t feedMoreTSData(); Loading @@ -65,6 +63,7 @@ private: kWhatNotify = 'noti', kWhatDisconnect = 'disc', kWhatPerformSeek = 'seek', kWhatPollBuffering = 'poll', }; enum State { Loading @@ -79,6 +78,12 @@ private: kFlagIncognito = 1, }; // Buffer Prepare/Underflow/Overflow/Resume Marks static const int64_t kPrepareMarkUs; static const int64_t kUnderflowMarkUs; static const int64_t kOverflowMarkUs; static const int64_t kStartServerMarkUs; struct TrackInfo { sp<AnotherPacketSource> mSource; Loading @@ -100,6 +105,7 @@ private: sp<AReplyToken> mDisconnectReplyID; Mutex mBufferingLock; bool mBuffering; bool mInPreparationPhase; sp<ALooper> mLooper; sp<MyHandler> mHandler; Loading @@ -126,6 +132,9 @@ private: void finishDisconnectIfPossible(); void performSeek(int64_t seekTimeUs); void schedulePollBuffering(); void checkBuffering(bool *prepared, bool *underflow, bool *overflow, bool *startServer); void onPollBuffering(); bool haveSufficientDataOnAllTracks(); Loading
media/libstagefright/rtsp/MyHandler.h +12 −1 Original line number Diff line number Diff line Loading @@ -235,7 +235,7 @@ struct MyHandler : public AHandler { sp<AMessage> msg = new AMessage('paus', this); mPauseGeneration++; msg->setInt32("pausecheck", mPauseGeneration); msg->post(kPauseDelayUs); msg->post(); } void resume() { Loading Loading @@ -979,6 +979,11 @@ struct MyHandler : public AHandler { case 'accu': { if (mSeekPending) { ALOGV("Stale access unit."); break; } int32_t timeUpdate; if (msg->findInt32("time-update", &timeUpdate) && timeUpdate) { size_t trackIndex; Loading Loading @@ -1070,6 +1075,12 @@ struct MyHandler : public AHandler { ALOGW("This is a live stream, ignoring pause request."); break; } if (mPausing) { ALOGV("This stream is already paused."); break; } mCheckPending = true; ++mCheckGeneration; mPausing = true; Loading