Commit 881f9380 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

strmbase: Split RenderEvent into separate events for advising and flushing.

While it's certainly possible to use one event for both purposes, it's a little less clear, and it makes it a little more difficult to do other waits that need to be interrupted by flushing. For example, the video renderer should block in Receive() after rendering the sample until the filter is run. Signed-off-by: 's avatarZebediah Figura <z.figura12@gmail.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent f834e4a4
...@@ -736,7 +736,7 @@ static HRESULT WINAPI DSoundRender_Pause(IBaseFilter * iface) ...@@ -736,7 +736,7 @@ static HRESULT WINAPI DSoundRender_Pause(IBaseFilter * iface)
This->renderer.filter.state = State_Paused; This->renderer.filter.state = State_Paused;
ResetEvent(This->blocked); ResetEvent(This->blocked);
ResetEvent(This->renderer.RenderEvent); ResetEvent(This->renderer.flush_event);
} }
LeaveCriticalSection(&This->renderer.csRenderLock); LeaveCriticalSection(&This->renderer.csRenderLock);
......
...@@ -679,7 +679,7 @@ static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface) ...@@ -679,7 +679,7 @@ static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface)
VideoRenderer_AutoShowWindow(This); VideoRenderer_AutoShowWindow(This);
} }
ResetEvent(This->renderer.RenderEvent); ResetEvent(This->renderer.flush_event);
This->renderer.filter.state = State_Paused; This->renderer.filter.state = State_Paused;
} }
LeaveCriticalSection(&This->renderer.csRenderLock); LeaveCriticalSection(&This->renderer.csRenderLock);
......
...@@ -267,7 +267,8 @@ HRESULT WINAPI strmbase_renderer_init(BaseRenderer *filter, const IBaseFilterVtb ...@@ -267,7 +267,8 @@ HRESULT WINAPI strmbase_renderer_init(BaseRenderer *filter, const IBaseFilterVtb
InitializeCriticalSection(&filter->csRenderLock); InitializeCriticalSection(&filter->csRenderLock);
filter->csRenderLock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": BaseRenderer.csRenderLock"); filter->csRenderLock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": BaseRenderer.csRenderLock");
filter->state_event = CreateEventW(NULL, TRUE, TRUE, NULL); filter->state_event = CreateEventW(NULL, TRUE, TRUE, NULL);
filter->RenderEvent = CreateEventW(NULL, FALSE, FALSE, NULL); filter->advise_event = CreateEventW(NULL, FALSE, FALSE, NULL);
filter->flush_event = CreateEventW(NULL, TRUE, TRUE, NULL);
filter->pMediaSample = NULL; filter->pMediaSample = NULL;
QualityControlImpl_Create(&filter->sink.pin.IPin_iface, &filter->filter.IBaseFilter_iface, &filter->qcimpl); QualityControlImpl_Create(&filter->sink.pin.IPin_iface, &filter->filter.IBaseFilter_iface, &filter->qcimpl);
...@@ -291,7 +292,8 @@ void strmbase_renderer_cleanup(BaseRenderer *filter) ...@@ -291,7 +292,8 @@ void strmbase_renderer_cleanup(BaseRenderer *filter)
BaseRendererImpl_ClearPendingSample(filter); BaseRendererImpl_ClearPendingSample(filter);
CloseHandle(filter->state_event); CloseHandle(filter->state_event);
CloseHandle(filter->RenderEvent); CloseHandle(filter->advise_event);
CloseHandle(filter->flush_event);
QualityControlImpl_Destroy(filter->qcimpl); QualityControlImpl_Destroy(filter->qcimpl);
strmbase_filter_cleanup(&filter->filter); strmbase_filter_cleanup(&filter->filter);
} }
...@@ -366,12 +368,14 @@ HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSamp ...@@ -366,12 +368,14 @@ HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSamp
if (now - This->filter.rtStreamStart - start <= -10000) if (now - This->filter.rtStreamStart - start <= -10000)
{ {
HANDLE handles[2] = {This->advise_event, This->flush_event};
IReferenceClock_AdviseTime(This->filter.pClock, This->filter.rtStreamStart, IReferenceClock_AdviseTime(This->filter.pClock, This->filter.rtStreamStart,
start, (HEVENT)This->RenderEvent, &cookie); start, (HEVENT)This->advise_event, &cookie);
LeaveCriticalSection(&This->csRenderLock); LeaveCriticalSection(&This->csRenderLock);
WaitForSingleObject(This->RenderEvent, INFINITE); WaitForMultipleObjects(2, handles, FALSE, INFINITE);
IReferenceClock_Unadvise(This->filter.pClock, cookie); IReferenceClock_Unadvise(This->filter.pClock, cookie);
EnterCriticalSection(&This->csRenderLock); EnterCriticalSection(&This->csRenderLock);
...@@ -418,7 +422,7 @@ HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface) ...@@ -418,7 +422,7 @@ HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface)
This->pFuncsTable->pfnOnStopStreaming(This); This->pFuncsTable->pfnOnStopStreaming(This);
This->filter.state = State_Stopped; This->filter.state = State_Stopped;
SetEvent(This->state_event); SetEvent(This->state_event);
SetEvent(This->RenderEvent); SetEvent(This->flush_event);
} }
LeaveCriticalSection(&This->csRenderLock); LeaveCriticalSection(&This->csRenderLock);
...@@ -489,7 +493,7 @@ HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface) ...@@ -489,7 +493,7 @@ HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface)
if (This->filter.state == State_Stopped) if (This->filter.state == State_Stopped)
BaseRendererImpl_ClearPendingSample(This); BaseRendererImpl_ClearPendingSample(This);
ResetEvent(This->RenderEvent); ResetEvent(This->flush_event);
This->filter.state = State_Paused; This->filter.state = State_Paused;
} }
} }
...@@ -555,7 +559,7 @@ HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer* iface) ...@@ -555,7 +559,7 @@ HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer* iface)
{ {
TRACE("(%p)\n", iface); TRACE("(%p)\n", iface);
BaseRendererImpl_ClearPendingSample(iface); BaseRendererImpl_ClearPendingSample(iface);
SetEvent(iface->RenderEvent); SetEvent(iface->flush_event);
return S_OK; return S_OK;
} }
...@@ -564,7 +568,7 @@ HRESULT WINAPI BaseRendererImpl_EndFlush(BaseRenderer* iface) ...@@ -564,7 +568,7 @@ HRESULT WINAPI BaseRendererImpl_EndFlush(BaseRenderer* iface)
TRACE("(%p)\n", iface); TRACE("(%p)\n", iface);
QualityControlRender_Start(iface->qcimpl, iface->filter.rtStreamStart); QualityControlRender_Start(iface->qcimpl, iface->filter.rtStreamStart);
RendererPosPassThru_ResetMediaTime(iface->pPosition); RendererPosPassThru_ResetMediaTime(iface->pPosition);
ResetEvent(iface->RenderEvent); ResetEvent(iface->flush_event);
return S_OK; return S_OK;
} }
......
...@@ -535,21 +535,26 @@ HRESULT WINAPI BaseControlVideo_Destroy(BaseControlVideo *pControlVideo); ...@@ -535,21 +535,26 @@ HRESULT WINAPI BaseControlVideo_Destroy(BaseControlVideo *pControlVideo);
/* BaseRenderer Filter */ /* BaseRenderer Filter */
typedef struct BaseRendererTag typedef struct BaseRendererTag
{ {
BaseFilter filter; BaseFilter filter;
BaseInputPin sink; BaseInputPin sink;
IUnknown *pPosition; IUnknown *pPosition;
CRITICAL_SECTION csRenderLock; CRITICAL_SECTION csRenderLock;
/* Signaled when the filter has completed a state change. The filter waits /* Signaled when the filter has completed a state change. The filter waits
* for this event in IBaseFilter::GetState(). */ * for this event in IBaseFilter::GetState(). */
HANDLE state_event; HANDLE state_event;
HANDLE RenderEvent; /* Signaled when the sample presentation time occurs. The streaming thread
IMediaSample *pMediaSample; * waits for this event in Receive() if applicable. */
HANDLE advise_event;
IQualityControl *pQSink; /* Signaled when a flush or state change occurs, i.e. anything that needs
struct QualityControlImpl *qcimpl; * to immediately unblock the streaming thread. */
HANDLE flush_event;
IMediaSample *pMediaSample;
IQualityControl *pQSink;
struct QualityControlImpl *qcimpl;
const struct BaseRendererFuncTable * pFuncsTable; const struct BaseRendererFuncTable *pFuncsTable;
} BaseRenderer; } BaseRenderer;
typedef HRESULT (WINAPI *BaseRenderer_CheckMediaType)(BaseRenderer *This, const AM_MEDIA_TYPE *pmt); typedef HRESULT (WINAPI *BaseRenderer_CheckMediaType)(BaseRenderer *This, const AM_MEDIA_TYPE *pmt);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment