@@ -911,10 +911,8 @@ bool SESSION::CSession::GetNextSample(ISampleReader*& sampleReader)
911911 return false ;
912912}
913913
914- bool SESSION::CSession::SeekTime (double seekTime, bool preceeding)
914+ bool SESSION::CSession::SeekTime (double seekTime, bool & isError, bool preceeding)
915915{
916- bool ret{false };
917-
918916 if (m_streams.empty ())
919917 return false ;
920918
@@ -949,26 +947,14 @@ bool SESSION::CSession::SeekTime(double seekTime, bool preceeding)
949947
950948 seekTime -= chapterTime;
951949
952- // don't try to seek past the end of the stream, leave a sensible amount so we can buffer properly
953950 if (m_adaptiveTree->IsLive ())
954951 {
955- double maxSeek{0 };
956- uint64_t curTime;
957- uint64_t maxTime{0 };
958- for (auto & stream : m_streams)
959- {
960- if (stream->IsEnabled () && (curTime = stream->m_adStream .getMaxTimeMs ()) && curTime > maxTime)
961- {
962- maxTime = curTime;
963- }
964- }
952+ double delayPtsSecs =
953+ (static_cast <double >(GetMediaDurationMs ()) / 1000 ) - m_adaptiveTree->m_liveDelay ;
965954
966- maxSeek = (static_cast <double >(maxTime) / 1000 ) - m_adaptiveTree->m_liveDelay ;
967- if (maxSeek < 0 )
968- maxSeek = 0 ;
969-
970- if (seekTime > maxSeek)
971- seekTime = maxSeek;
955+ // Check to avoid seek into live delay duration portion, to allow an appropriate live buffering
956+ if (seekTime > delayPtsSecs)
957+ seekTime = delayPtsSecs;
972958 }
973959
974960 // Helper lambda to check if reader is started,
@@ -993,7 +979,7 @@ bool SESSION::CSession::SeekTime(double seekTime, bool preceeding)
993979 {
994980 if (!stream.m_adStream .seek_time (seekSecs))
995981 {
996- stream.GetReader ()->Reset (true );
982+ stream.GetReader ()->Reset (false );
997983 return false ;
998984 }
999985 if (!preceeding)
@@ -1057,17 +1043,22 @@ bool SESSION::CSession::SeekTime(double seekTime, bool preceeding)
10571043 const double seekSecs{static_cast <double >(seekTimeCorrected - ptsDiff) / STREAM_TIME_BASE};
10581044
10591045 if (!SeekAdStream (*stream, seekSecs, preceeding))
1060- continue ;
1046+ return false ;
10611047 }
10621048
10631049 if (!CheckReaderRunning (*stream))
1064- continue ;
1050+ return false ;
10651051
10661052 streamReader->SetPTSDiff (ptsDiff);
10671053
10681054 if (!streamReader->TimeSeek (seekTimeCorrected, preceeding))
10691055 {
1056+ // ! @todo: check whether we can better manage EOS on stream readers
1057+ // ! if it fails for other reasons, we could avoid setting isError
1058+ // ! to allow an attempt to restore playback to previous state (see PosTime method)
10701059 streamReader->Reset (true );
1060+ isError = true ;
1061+ return false ;
10711062 }
10721063 else
10731064 {
@@ -1085,11 +1076,9 @@ bool SESSION::CSession::SeekTime(double seekTime, bool preceeding)
10851076 seekTimeCorrected = streamReader->PTS ();
10861077 preceeding = false ;
10871078 }
1088- ret = true ;
10891079 }
10901080 }
1091-
1092- return ret;
1081+ return true ;
10931082}
10941083
10951084void SESSION::CSession::OnDemuxRead ()
@@ -1100,7 +1089,10 @@ void SESSION::CSession::OnDemuxRead()
11001089
11011090 if (GetChapterSeekTime () > 0 )
11021091 {
1103- SeekTime (GetChapterSeekTime ());
1092+ bool isError{false };
1093+ if (!SeekTime (GetChapterSeekTime (), isError))
1094+ DeleteStreams ();
1095+
11041096 ResetChapterSeekTime ();
11051097 }
11061098 }
@@ -1344,3 +1336,11 @@ PLAYLIST::CAdaptationSet* SESSION::CSession::DetermineDefaultAdpSet(PLAYLIST::CP
13441336
13451337 return defaultAdp;
13461338}
1339+
1340+ uint64_t SESSION::CSession::GetMediaDurationMs ()
1341+ {
1342+ if (!m_timingStream || !m_timingStream->IsEnabled ())
1343+ return 0 ;
1344+
1345+ return m_timingStream->m_adStream .getMaxTimeMs ();
1346+ }
0 commit comments