Index: AudioPin.cpp =================================================================== --- AudioPin.cpp (revision 27941) +++ AudioPin.cpp (working copy) @@ -181,7 +181,6 @@ return CSourceStream::BreakConnect(); } -extern int ShowBuffer; HRESULT CAudioPin::FillBuffer(IMediaSample *pSample) { @@ -200,7 +199,7 @@ //we dont try to read any packets, but simply return... if (m_pTsReaderFilter->IsSeeking() || m_pTsReaderFilter->IsStopping())// /*|| m_bSeeking*/ || m_pTsReaderFilter->IsSeekingToEof()) { - //if (ShowBuffer) LogDebug("aud:isseeking"); + //if (m_pTsReaderFilter->m_ShowBufferAudio) LogDebug("aud:isseeking"); Sleep(20); pSample->SetTime(NULL,NULL); pSample->SetActualDataLength(0); @@ -391,11 +390,11 @@ float clock = (double)(RefClock-m_rtStart.m_time)/10000000.0 ; float fTime=(float)cRefTime.Millisecs()/1000.0f - clock ; - if (ShowBuffer || fTime < 0.030) + if (m_pTsReaderFilter->m_ShowBufferAudio || fTime < 0.030) { LogDebug("Aud/Ref : %03.3f, Late Compensated = %03.3f ( %0.3f A/V buffers=%02d/%02d), Clk : %f, State %d", (float)RefTime.Millisecs()/1000.0f, (float)cRefTime.Millisecs()/1000.0f, fTime,cntA,cntV, clock, m_pTsReaderFilter->State()); } - if (ShowBuffer) ShowBuffer--; + if (m_pTsReaderFilter->m_ShowBufferAudio) m_pTsReaderFilter->m_ShowBufferAudio--; } } else Index: DeMultiplexer.cpp =================================================================== --- DeMultiplexer.cpp (revision 27941) +++ DeMultiplexer.cpp (working copy) @@ -1640,6 +1640,10 @@ } } } + else + { + m_bSetVideoDiscontinuity = true; + } m_VideoValidPES=true ; // We've just completed a frame, set flag until problem clears it m_pl.RemoveAll() ; } Index: TsReader.cpp =================================================================== --- TsReader.cpp (revision 27941) +++ TsReader.cpp (working copy) @@ -170,8 +170,8 @@ TCHAR filename[1024]; GetLogFile(filename); ::DeleteFile(filename); - LogDebug("--------- Fast forward debug ---------"); - LogDebug("-------------- v0.4.7 ----------------"); + LogDebug("------ FFDShow A/V sync fix ----------"); + LogDebug("---------- v0.4.8 --------------------"); m_fileReader=NULL; m_fileDuration=NULL; @@ -223,6 +223,11 @@ m_bForceSeekOnStop=false ; m_bForceSeekAfterRateChange=false ; m_bSeekAfterRcDone=false ; + m_videoDecoderCLSID=GUID_NULL; + m_bFastSyncAtStart=false; + m_ShowBufferAudio = INIT_SHOWBUFFERAUDIO; + m_ShowBufferVideo = INIT_SHOWBUFFERVIDEO; + m_MPmainThreadID = GetCurrentThreadId() ; } @@ -356,7 +361,7 @@ return S_OK; } -extern int ShowBuffer; + STDMETHODIMP CTsReaderFilter::SetRelaxedMode(BOOL relaxedReading) { LogDebug("SetRelaxedMode"); @@ -415,7 +420,8 @@ LogDebug("Elapsed time from pause to Audio/Video ( total zapping time ) : %d mS",GetTickCount()-m_lastPause); } - ShowBuffer=40; + m_ShowBufferVideo = INIT_SHOWBUFFERVIDEO; + m_ShowBufferAudio = INIT_SHOWBUFFERAUDIO; CAutoLock cObjectLock(m_pLock); @@ -502,10 +508,13 @@ { return m_bTimeShifting; } -extern int ShowBuffer; + + STDMETHODIMP CTsReaderFilter::Pause() { - ShowBuffer=100 ; + //m_ShowBufferVideo = INIT_SHOWBUFFERVIDEO; + //m_ShowBufferAudio = INIT_SHOWBUFFERAUDIO; + LogDebug("CTsReaderFilter::Pause() - IsTimeShifting = %d - state = %d", IsTimeShifting(), m_State); CAutoLock cObjectLock(m_pLock); @@ -1550,6 +1559,29 @@ *pMediaPos = (m_MediaPos + m_LastTime - m_BaseTime) ; return ; } + +//---------------------------------------------------- +// Derived from FFDShow code +CLSID CTsReaderFilter::GetCLSIDFromPin(IPin* pPin) +{ + if (!pPin) + { + return GUID_NULL; + } + CLSID clsid=GUID_NULL; + PIN_INFO pi; + if (SUCCEEDED(pPin->QueryPinInfo(&pi))) + { + if (pi.pFilter) // IBaseFilter pointer + { + pi.pFilter->GetClassID(&clsid); + pi.pFilter->Release(); + } + } + return clsid; +} + + //////////////////////////////////////////////////////////////////////// // // Exported entry points for registration and unregistration Index: TsReader.h =================================================================== --- TsReader.h (revision 27941) +++ TsReader.h (working copy) @@ -32,6 +32,10 @@ #include "IAudioStream.h" #include "ITeletextSource.h" #include + +#define INIT_SHOWBUFFERVIDEO 20 +#define INIT_SHOWBUFFERAUDIO 5 + using namespace std; class CSubtitlePin; @@ -44,6 +48,15 @@ DEFINE_GUID(IID_ITSReader, 0xb9559486, 0xe1bb, 0x45d3, 0xa2, 0xa2, 0x9a, 0x7a, 0xfe, 0x49, 0xb2, 0x4f); //DEFINE_GUID(IID_ITSReaderAudioChange, 0xb9559486, 0xe1bb, 0x45d3, 0xa2, 0xa2, 0x9a, 0x7a, 0xfe, 0x49, 0xb2, 0x5f); +// CLSIDs used to identify connected filters +// {04FE9017-F873-410e-871E-AB91661A4EF7} +DEFINE_GUID(CLSID_FFDSHOWVIDEO, 0x04fe9017, 0xf873, 0x410e, 0x87, 0x1e, 0xab, 0x91, 0x66, 0x1a, 0x4e, 0xf7); +// {0B390488-D80F-4a68-8408-48DC199F0E97} +DEFINE_GUID(CLSID_FFDSHOWDXVA, 0xb0eff97, 0xc750, 0x462c, 0x94, 0x88, 0xb1, 0xe, 0x7d, 0x87, 0xf1, 0xa6); +// {DBF9000E-F08C-4858-B769-C914A0FBB1D7} +DEFINE_GUID(CLSID_FFDSHOWSUBTITLES, 0xdbf9000e, 0xf08c, 0x4858, 0xb7, 0x69, 0xc9, 0x14, 0xa0, 0xfb, 0xb1, 0xd7); + + DECLARE_INTERFACE_(ITSReaderCallback, IUnknown) { STDMETHOD(OnMediaTypeChanged) (int mediaTypes)PURE; @@ -186,6 +199,14 @@ bool m_bForceSeekAfterRateChange; bool m_bSeekAfterRcDone; + int m_ShowBufferAudio; + int m_ShowBufferVideo; + + CLSID m_videoDecoderCLSID; + bool m_bFastSyncAtStart; + + CLSID GetCLSIDFromPin(IPin* pPin); + protected: void ThreadProc(); Index: VideoPin.cpp =================================================================== --- VideoPin.cpp (revision 27941) +++ VideoPin.cpp (working copy) @@ -125,14 +125,32 @@ //LogDebug("vid:CheckConnect()"); return CBaseOutputPin::CheckConnect(pReceivePin); } + + HRESULT CVideoPin::CompleteConnect(IPin *pReceivePin) { - //LogDebug("vid:CompleteConnect()"); HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin); if (SUCCEEDED(hr)) { + CLSID &ref=m_pTsReaderFilter->GetCLSIDFromPin(pReceivePin); + m_pTsReaderFilter->m_videoDecoderCLSID = ref; + if (m_pTsReaderFilter->m_videoDecoderCLSID == CLSID_FFDSHOWVIDEO) + { + m_pTsReaderFilter->m_bFastSyncAtStart=true; + LogDebug("vid:CompleteConnect() FFDShow Video Decoder connected, fast sync enabled"); + } + else if (m_pTsReaderFilter->m_videoDecoderCLSID == CLSID_FFDSHOWDXVA) + { + m_pTsReaderFilter->m_bFastSyncAtStart=true; + LogDebug("vid:CompleteConnect() FFDShow DXVA Video Decoder connected, fast sync enabled"); + } + else + { + m_pTsReaderFilter->m_bFastSyncAtStart=false; + } + + m_bConnected=true; LogDebug("vid:CompleteConnect() done"); - m_bConnected=true; } else { @@ -245,7 +263,6 @@ return S_FALSE; } -int ShowBuffer=100; HRESULT CVideoPin::FillBuffer(IMediaSample *pSample) { @@ -264,7 +281,7 @@ //we dont try to read any packets, but simply return... if (m_pTsReaderFilter->IsSeeking() || m_pTsReaderFilter->IsStopping()) //|| m_bSeeking*/ || m_pTsReaderFilter->IsSeekingToEof()) { - //if (ShowBuffer) LogDebug("vid:isseeking:%d %d",m_pTsReaderFilter->IsSeeking() ,m_bSeeking); + //if (m_pTsReaderFilter->m_ShowBufferVideo) LogDebug("vid:isseeking:%d %d",m_pTsReaderFilter->IsSeeking() ,m_bSeeking); Sleep(5); pSample->SetActualDataLength(0); return NOERROR; @@ -304,30 +321,29 @@ cRefTime -= m_rtStart; //adjust the timestamp with the compensation cRefTime -= m_pTsReaderFilter->Compensation; - cRefTime -= AddOffset; - cRefTime -= m_pTsReaderFilter->m_ClockOnStart.m_time; - CRefTime Dur; - Dur = (m_pTsReaderFilter->AddVideoComp.m_time * DRIFT_RATE); + //CRefTime Dur; + //Dur = (m_pTsReaderFilter->AddVideoComp.m_time * DRIFT_RATE); - if (cRefTime.m_time < (m_pTsReaderFilter->AddVideoComp.m_time * DRIFT_RATE)) + if (!m_pTsReaderFilter->m_bFastSyncAtStart && (cRefTime.m_time < (m_pTsReaderFilter->AddVideoComp.m_time * DRIFT_RATE)) ) { // Ambass : try to stretch video after zapping + cRefTime -= AddOffset; + cRefTime -= m_pTsReaderFilter->m_ClockOnStart.m_time; AddOffset = cRefTime.m_time / DRIFT_RATE; // LogDebug("%03.3f, %03.3f, %03.3f", (float)AddOffset.Millisecs()/1000.0f,(float)cRefTime.Millisecs()/1000.0f, (float)m_pTsReaderFilter->AddVideoComp.Millisecs()/1000.0f); // m_pTsReaderFilter->AddVideoComp.m_time =0; + cRefTime += AddOffset; + cRefTime += m_pTsReaderFilter->m_ClockOnStart.m_time; } - - cRefTime += AddOffset; - cRefTime += m_pTsReaderFilter->m_ClockOnStart.m_time; if (cRefTime.m_time >= 0) + { Sleep(1); // Ambass : avoid blocking audio FillBuffer method ( on audio/video starting ) by excessive video Fill buffer preemption + } + m_bPresentSample = true; - //else - // Sample is too late. - //m_ShowSample = false ; - } + } if (m_bPresentSample) { @@ -356,7 +372,7 @@ float clock = (double)(RefClock-m_rtStart.m_time)/10000000.0 ; float fTime=(float)cRefTime.Millisecs()/1000.0f - clock ; - if (ShowBuffer || fTime < 0.030) + if (m_pTsReaderFilter->m_ShowBufferVideo || fTime < 0.030) { int cntA, cntV; CRefTime firstAudio, lastAudio; @@ -365,8 +381,14 @@ cntV = demux.GetVideoBufferPts(firstVideo, lastVideo) + 1; LogDebug("Vid/Ref : %03.3f, Late %c-frame(%02d), Compensated = %03.3f ( %0.3f A/V buffers=%02d/%02d), Clk : %f, State %d", (float)RefTime.Millisecs()/1000.0f,buffer->GetFrameType(),buffer->GetFrameCount(), (float)cRefTime.Millisecs()/1000.0f, fTime, cntA,cntV,clock, m_pTsReaderFilter->State()); - } - if (ShowBuffer) ShowBuffer--; + } + + if (m_pTsReaderFilter->m_bFastSyncAtStart && m_pTsReaderFilter->m_ShowBufferVideo == INIT_SHOWBUFFERVIDEO) + { + pSample->SetDiscontinuity(TRUE); + LogDebug("vid: ShowBuffer = %d, force discontinuity", m_pTsReaderFilter->m_ShowBufferVideo); + } + if (m_pTsReaderFilter->m_ShowBufferVideo) m_pTsReaderFilter->m_ShowBufferVideo--; } } else @@ -437,6 +459,12 @@ m_dRateSeeking = 1.0; // Reset to a reasonable value. return E_FAIL; } + if( m_dRateSeeking > 2.0 && m_pTsReaderFilter->m_videoDecoderCLSID == CLSID_FFDSHOWVIDEO) + { + //FFDShow video decoder doesn't handle rate > 2.0 properly + m_dRateSeeking = 1.0; // Reset to a reasonable value. + return E_FAIL; + } LogDebug("vid: ChangeRate, m_dRateSeeking %f, Force seek done %d",(float)m_dRateSeeking, m_pTsReaderFilter->m_bSeekAfterRcDone); if (!m_pTsReaderFilter->m_bSeekAfterRcDone) //Don't force seek if another pin has already triggered it { Index: VideoPin.h =================================================================== --- VideoPin.h (revision 27941) +++ VideoPin.h (working copy) @@ -23,6 +23,7 @@ #define __VideoPin_H #include "tsreader.h" + class CVideoPin : public CSourceStream, public CSourceSeeking { public: @@ -39,6 +40,7 @@ HRESULT FillBuffer(IMediaSample *pSample); HRESULT BreakConnect(); + HRESULT DoBufferProcessingLoop(void); // CSourceSeeking