//************************************************************************************************************** /// This method is running in its own thread /// Every second it will check the stream or local file and determine the total duration of the file/stream /// The duration can/will grow if we are playing a timeshifting buffer/stream // If the duration has changed it will update m_duration and send a EC_LENGTH_CHANGED event // to the graph void CTsReaderFilter::ThreadProc() { LogDebug("CTsReaderFilter::ThreadProc start()"); int durationUpdateLoop = 1; long Old_rtspDuration = -1 ; long PauseDuration =0; ::SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_BELOW_NORMAL); do { //if demuxer reached the end of the file, we can stop the thread //since we're no longer playing if (m_demultiplexer.EndOfFile()) break; //are we playing an RTSP stream? if (m_fileDuration!=NULL) { //no, then get the duration from the local file CTsDuration duration; duration.SetFileReader(m_fileDuration); duration.SetVideoPid(m_duration.GetPid()); duration.UpdateDuration(); //did we find a duration? if (duration.Duration().Millisecs()>0) { //yes, is it different then the one we determined last time? if (duration.StartPcr().PcrReferenceBase!=m_duration.StartPcr().PcrReferenceBase || duration.EndPcr().PcrReferenceBase!=m_duration.EndPcr().PcrReferenceBase) { //yes, then update it m_duration.Set(duration.StartPcr(), duration.EndPcr(), duration.MaxPcr()); // Local file // Is graph running? if (m_State == State_Running||m_State==State_Paused) { //yes, then send a EC_LENGTH_CHANGED event to the graph NotifyEvent(EC_LENGTH_CHANGED, NULL, NULL); SetDuration(); } } } if (m_bLiveTv && (m_State == State_Paused)) { // After 10 secs Pause, for sure, liveTv is cancelled. PauseDuration++ ; if (PauseDuration > 10) { m_bLiveTv=false; LogDebug("CTsReaderFilter, Live Tv is paused for more than 10 secs => m_bLiveTv=false."); } } else PauseDuration=0 ; } else { // we are not playing a local file // we are playing a (RTSP) stream? if(m_bTimeShifting || m_bRecording) { if(durationUpdateLoop == 0) { Old_rtspDuration = m_rtspClient.Duration(); m_rtspClient.UpdateDuration(); } CPcr pcrStart, pcrEnd, pcrMax ; double duration = m_rtspClient.Duration() / 1000.0f ; double start = m_duration.StartPcr().ToClock() ; double end = m_duration.EndPcr().ToClock() ; if (m_bTimeShifting) { // EndPcr is continuously increasing ( until ~26 hours for rollover that will fail ! ) // So, we refer duration to End, and just update start. end = (double)(GetTickCount()-m_tickCount)/1000.0 ; if(durationUpdateLoop == 0) { start = end - duration; if (start<0) start=0 ; } } else { end = start + duration ; if (Old_rtspDuration!=m_rtspClient.Duration()) // recording alive, continue to increase every second. { end += (double)(durationUpdateLoop % 5) ; } else { m_bRecording = false; } } //set the duration pcrStart.FromClock(start) ; pcrEnd.FromClock(end); m_duration.Set( pcrStart, pcrEnd, pcrMax); // Continuous update // LogDebug("Start : %f, End : %f",(float)m_duration.StartPcr().ToClock(),(float)m_duration.EndPcr().ToClock()) ; durationUpdateLoop = (durationUpdateLoop + 1) % 5; // Is graph running? if (m_State == State_Running) { //yes, then send a EC_LENGTH_CHANGED event to the graph NotifyEvent(EC_LENGTH_CHANGED, NULL, NULL); SetDuration(); } } } } while (!ThreadIsStopping(1000)) ; LogDebug("CTsReaderFilter::ThreadProc stopped()"); }