Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Commit

Permalink
EVR-CP/Sync renderers: The wrong frame was displayed when paused.
Browse files Browse the repository at this point in the history
34f0b26 was not enough to ensure the currently displayed sample was not reused.
  • Loading branch information
Underground78 committed Jun 11, 2015
1 parent dfaf50b commit 140aab9
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 24 deletions.
46 changes: 30 additions & 16 deletions src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.cpp
Expand Up @@ -314,6 +314,22 @@ STDMETHODIMP_(bool) CEVRAllocatorPresenter::Paint(bool bAll)
return __super::Paint(bAll);
}

STDMETHODIMP_(bool) CEVRAllocatorPresenter::Paint(IMFSample* pMFSample)
{
CAutoLock lock(&m_RenderLock);

m_pCurrentlyDisplayedSample = pMFSample;
pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32*)&m_nCurSurface);

auto sampleHasCurrentGroupId = [this](IMFSample* pSample) {
UINT32 nGroupId;
return (SUCCEEDED(pSample->GetUINT32(GUID_GROUP_ID, &nGroupId)) && nGroupId == m_nCurrentGroupId);
};
ASSERT(sampleHasCurrentGroupId(pMFSample));

return Paint(true);
}

STDMETHODIMP CEVRAllocatorPresenter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
HRESULT hr;
Expand Down Expand Up @@ -1173,6 +1189,7 @@ STDMETHODIMP CEVRAllocatorPresenter::ReleaseServicePointers()
{
TRACE_EVR("EVR: CEVRAllocatorPresenter::ReleaseServicePointers\n");
StopWorkerThreads();
m_pCurrentlyDisplayedSample = nullptr;
m_pMixer = nullptr;
m_pSink = nullptr;
m_pClock = nullptr;
Expand Down Expand Up @@ -1801,7 +1818,9 @@ LONGLONG CEVRAllocatorPresenter::GetClockTime(LONGLONG PerformanceCounter)

void CEVRAllocatorPresenter::OnVBlankFinished(bool bAll, LONGLONG PerformanceCounter)
{
if (!m_pCurrentDisplaydSample || !m_OrderedPaint || !bAll) {
// This function is meant to be called only from the rendering function
// so with the ownership on m_RenderLock.
if (!m_pCurrentlyDisplayedSample || !m_OrderedPaint || !bAll) {
return;
}

Expand All @@ -1820,14 +1839,14 @@ void CEVRAllocatorPresenter::OnVBlankFinished(bool bAll, LONGLONG PerformanceCou
llClockTime = m_StarvationClock;
}

if (SUCCEEDED(m_pCurrentDisplaydSample->GetSampleDuration(&SampleDuration))) {
if (SUCCEEDED(m_pCurrentlyDisplayedSample->GetSampleDuration(&SampleDuration))) {
// Some filters return invalid values, ignore them
if (SampleDuration > MIN_FRAME_TIME) {
TimePerFrame = SampleDuration;
}
}

if (FAILED(m_pCurrentDisplaydSample->GetSampleTime(&nsSampleTime))) {
if (FAILED(m_pCurrentlyDisplayedSample->GetSampleTime(&nsSampleTime))) {
nsSampleTime = llClockTime;
}

Expand Down Expand Up @@ -1859,7 +1878,6 @@ void CEVRAllocatorPresenter::OnVBlankFinished(bool bAll, LONGLONG PerformanceCou
m_fSyncOffsetAvr = MeanOffset;
m_bSyncStatsAvailable = true;
m_fSyncOffsetStdDev = StdDev;

}
}

Expand Down Expand Up @@ -2012,8 +2030,8 @@ void CEVRAllocatorPresenter::RenderThread()
UNREFERENCED_PARAMETER(llPerf);
int nSamplesLeft = 0;
if (SUCCEEDED(GetScheduledSample(&pMFSample, nSamplesLeft))) {
//pMFSample->GetUINT32 (GUID_SURFACE_INDEX, (UINT32*)&m_nCurSurface);
m_pCurrentDisplaydSample = pMFSample;
//UINT32 nSurface;
//pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32*)&nSurface);

bool bValidSampleTime = true;
HRESULT hrGetSampleTime = pMFSample->GetSampleTime(&nsSampleTime);
Expand All @@ -2029,7 +2047,7 @@ void CEVRAllocatorPresenter::RenderThread()
bValidSampleDuration = false;
}

//TRACE_EVR ("EVR: RenderThread ==>> Presenting surface %d (%I64d)\n", m_nCurSurface, nsSampleTime);
//TRACE_EVR("EVR: RenderThread ==>> Presenting surface %d (%I64d)\n", nSurface, nsSampleTime);

bool bStepForward = false;

Expand All @@ -2041,14 +2059,13 @@ void CEVRAllocatorPresenter::RenderThread()
m_nStepCount = 0;
/*
} else if (m_nStepCount > 0) {
pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32 *)&m_nCurSurface);
++m_OrderedPaint;
if (!g_bExternalSubtitleTime) {
__super::SetTime (g_tSegmentStart + nsSampleTime);
}
Paint(true);
Paint(pMFSample);
m_nDroppedUpdate = 0;
CompleteFrameStep (false);
CompleteFrameStep(false);
bStepForward = true;
*/
} else if (m_nRenderState == Started) {
Expand All @@ -2064,12 +2081,11 @@ void CEVRAllocatorPresenter::RenderThread()
if (!bValidSampleTime) {
// Just play as fast as possible
bStepForward = true;
pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32*)&m_nCurSurface);
++m_OrderedPaint;
if (!g_bExternalSubtitleTime) {
__super::SetTime(g_tSegmentStart + nsSampleTime);
}
Paint(true);
Paint(pMFSample);
} else {
LONGLONG TimePerFrame = (LONGLONG)(GetFrameTime() * 10000000.0);
LONGLONG DrawTime = m_PaintTime * 9 / 10 - 20000; // 2 ms offset (= m_PaintTime * 0.9 - 20000)
Expand Down Expand Up @@ -2183,7 +2199,6 @@ void CEVRAllocatorPresenter::RenderThread()
TRACE_EVR("EVR: Normalframe\n");
m_nDroppedUpdate = 0;
bStepForward = true;
pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32*)&m_nCurSurface);
m_LastFrameDuration = nsSampleTime - m_LastSampleTime;
m_LastSampleTime = nsSampleTime;
m_LastPredictedSync = VSyncOffset0;
Expand All @@ -2197,7 +2212,7 @@ void CEVRAllocatorPresenter::RenderThread()
if (!g_bExternalSubtitleTime) {
__super::SetTime(g_tSegmentStart + nsSampleTime);
}
Paint(true);
Paint(pMFSample);

NextSleepTime = 0;
m_pcFramesDrawn++;
Expand Down Expand Up @@ -2264,12 +2279,11 @@ void CEVRAllocatorPresenter::RenderThread()
if (!g_bExternalSubtitleTime) {
__super::SetTime(g_tSegmentStart + nsSampleTime);
}
Paint(false);
Paint(pMFSample);
}
NextSleepTime = int(SampleDuration / 10000 - 2);
}

m_pCurrentDisplaydSample = nullptr;
if (bStepForward) {
m_MaxSampleDuration = std::max(SampleDuration, m_MaxSampleDuration);
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/filters/renderer/VideoRenderers/EVRAllocatorPresenter.h
Expand Up @@ -145,6 +145,7 @@ namespace DSObjects
STDMETHODIMP GetVideoService(HANDLE hDevice, REFIID riid, void** ppService);

protected:
STDMETHODIMP_(bool) Paint(IMFSample* pMFSample);
void OnResetDevice();
virtual void OnVBlankFinished(bool bAll, LONGLONG PerformanceCounter);

Expand Down Expand Up @@ -197,7 +198,7 @@ namespace DSObjects
UINT32 m_nCurrentGroupId;
CInterfaceList<IMFSample> m_FreeSamples;
CInterfaceList<IMFSample> m_ScheduledSamples;
CComPtr<IMFSample> m_pCurrentDisplaydSample;
CComPtr<IMFSample> m_pCurrentlyDisplayedSample;
bool m_bWaitingSample;
bool m_bLastSampleOffsetValid;
LONGLONG m_LastScheduledSampleTime;
Expand Down
24 changes: 17 additions & 7 deletions src/filters/renderer/VideoRenderers/SyncRenderer.cpp
Expand Up @@ -2613,6 +2613,20 @@ STDMETHODIMP_(bool) CSyncAP::Paint(bool bAll)
return __super::Paint(bAll);
}

STDMETHODIMP_(bool) CSyncAP::Paint(IMFSample* pMFSample)
{
m_pCurrentlyDisplayedSample = pMFSample;
pMFSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32*)&m_nCurSurface);

auto sampleHasCurrentGroupId = [this](IMFSample* pSample) {
UINT32 nGroupId;
return (SUCCEEDED(pSample->GetUINT32(GUID_GROUP_ID, &nGroupId)) && nGroupId == m_nCurrentGroupId);
};
ASSERT(sampleHasCurrentGroupId(pMFSample));

return Paint(true);
}

STDMETHODIMP CSyncAP::NonDelegatingQueryInterface(REFIID riid, void** ppv)
{
HRESULT hr;
Expand Down Expand Up @@ -3252,6 +3266,7 @@ STDMETHODIMP CSyncAP::InitServicePointers(__in IMFTopologyServiceLookup* pLookup
STDMETHODIMP CSyncAP::ReleaseServicePointers()
{
StopWorkerThreads();
m_pCurrentlyDisplayedSample = nullptr;
m_pMixer = nullptr;
m_pSink = nullptr;
m_pClock = nullptr;
Expand Down Expand Up @@ -3787,20 +3802,15 @@ void CSyncAP::RenderThread()
m_pcFramesDropped++;
stepForward = true;
} else if (pNewSample && (m_nStepCount > 0)) {
pNewSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32*)&m_nCurSurface);
if (!g_bExternalSubtitleTime) {
__super::SetTime(g_tSegmentStart + m_llSampleTime);
}
Paint(true);
Paint(pNewSample);
CompleteFrameStep(false);
m_pcFramesDrawn++;
stepForward = true;
} else if (pNewSample && !m_bStepping) { // When a stepped frame is shown, a new one is fetched that we don't want to show here while stepping
pNewSample->GetUINT32(GUID_SURFACE_INDEX, (UINT32*)&m_nCurSurface);
if (!g_bExternalSubtitleTime) {
__super::SetTime(g_tSegmentStart + m_llSampleTime);
}
Paint(true);
Paint(pNewSample);
m_pcFramesDrawn++;
stepForward = true;
}
Expand Down
2 changes: 2 additions & 0 deletions src/filters/renderer/VideoRenderers/SyncRenderer.h
Expand Up @@ -449,6 +449,7 @@ namespace GothSync
STDMETHODIMP GetD3DFullscreen(bool* pfEnabled);

protected:
STDMETHODIMP_(bool) Paint(IMFSample* pMFSample);
void OnResetDevice();
MFCLOCK_STATE m_LastClockState;

Expand Down Expand Up @@ -493,6 +494,7 @@ namespace GothSync
UINT32 m_nCurrentGroupId;
CInterfaceList<IMFSample> m_FreeSamples;
CInterfaceList<IMFSample> m_ScheduledSamples;
CComPtr<IMFSample> m_pCurrentlyDisplayedSample;
UINT m_nResetToken;
int m_nStepCount;

Expand Down

0 comments on commit 140aab9

Please sign in to comment.