IPin::EndOfStream() is called from a streaming thread. The streaming thread should never take the filter lock.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/dsoundrender.c | 2 -- dlls/strmbase/renderer.c | 2 -- 2 files changed, 4 deletions(-)
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c index fca1a710de..71851f6b4a 100644 --- a/dlls/quartz/dsoundrender.c +++ b/dlls/quartz/dsoundrender.c @@ -236,11 +236,9 @@ static HRESULT DSoundRender_HandleEndOfStream(DSoundRenderImpl *This) break;
This->in_loop = 1; - LeaveCriticalSection(&This->renderer.filter.csFilter); LeaveCriticalSection(&This->renderer.csRenderLock); WaitForSingleObject(This->renderer.flush_event, 10); EnterCriticalSection(&This->renderer.csRenderLock); - EnterCriticalSection(&This->renderer.filter.csFilter); This->in_loop = 0; }
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index dbb677e9ad..98d27cc83a 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -88,13 +88,11 @@ static HRESULT WINAPI BaseRenderer_InputPin_EndOfStream(IPin * iface) TRACE("iface %p.\n", iface);
EnterCriticalSection(&pFilter->csRenderLock); - EnterCriticalSection(&pFilter->filter.csFilter); pFilter->eos = TRUE; if (pFilter->pFuncsTable->pfnEndOfStream) hr = pFilter->pFuncsTable->pfnEndOfStream(pFilter); else hr = BaseRendererImpl_EndOfStream(pFilter); - LeaveCriticalSection(&pFilter->filter.csFilter); LeaveCriticalSection(&pFilter->csRenderLock); return hr; }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/renderer.c | 13 ++++--------- include/wine/strmbase.h | 1 - 2 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 98d27cc83a..2f09cadf13 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -108,7 +108,10 @@ static HRESULT WINAPI BaseRenderer_InputPin_BeginFlush(IPin * iface) EnterCriticalSection(&pFilter->filter.csFilter); hr = BaseInputPinImpl_BeginFlush(iface); if (SUCCEEDED(hr)) - hr = BaseRendererImpl_BeginFlush(pFilter); + { + BaseRendererImpl_ClearPendingSample(pFilter); + SetEvent(pFilter->flush_event); + } LeaveCriticalSection(&pFilter->filter.csFilter); LeaveCriticalSection(&pFilter->csRenderLock); return hr; @@ -476,14 +479,6 @@ HRESULT WINAPI BaseRendererImpl_EndOfStream(struct strmbase_renderer *iface) return hr; }
-HRESULT WINAPI BaseRendererImpl_BeginFlush(struct strmbase_renderer *iface) -{ - TRACE("(%p)\n", iface); - BaseRendererImpl_ClearPendingSample(iface); - SetEvent(iface->flush_event); - return S_OK; -} - HRESULT WINAPI BaseRendererImpl_EndFlush(struct strmbase_renderer *iface) { TRACE("(%p)\n", iface); diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index d0a0da1b10..cf209ae892 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -567,7 +567,6 @@ struct strmbase_renderer_ops HRESULT (*renderer_pin_query_interface)(struct strmbase_renderer *iface, REFIID iid, void **out); };
-HRESULT WINAPI BaseRendererImpl_BeginFlush(struct strmbase_renderer *filter); HRESULT WINAPI BaseRendererImpl_ClearPendingSample(struct strmbase_renderer *filter); HRESULT WINAPI BaseRendererImpl_EndOfStream(struct strmbase_renderer *filter); HRESULT WINAPI BaseRendererImpl_EndFlush(struct strmbase_renderer *filter);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/dsoundrender.c | 4 ---- dlls/strmbase/renderer.c | 15 ++++----------- include/wine/strmbase.h | 1 - 3 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c index 71851f6b4a..3979853b8b 100644 --- a/dlls/quartz/dsoundrender.c +++ b/dlls/quartz/dsoundrender.c @@ -520,10 +520,6 @@ static HRESULT WINAPI DSoundRender_EndFlush(struct strmbase_renderer *iface) { DSoundRenderImpl *This = impl_from_strmbase_renderer(iface);
- TRACE("\n"); - - BaseRendererImpl_EndFlush(iface); - if (This->dsbuffer) { LPBYTE buffer; diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 2f09cadf13..5aee4380f2 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -130,10 +130,12 @@ static HRESULT WINAPI BaseRenderer_InputPin_EndFlush(IPin * iface) hr = BaseInputPinImpl_EndFlush(iface); if (SUCCEEDED(hr)) { + QualityControlRender_Start(pFilter->qcimpl, pFilter->stream_start); + RendererPosPassThru_ResetMediaTime(pFilter->pPosition); + ResetEvent(pFilter->flush_event); + if (pFilter->pFuncsTable->pfnEndFlush) hr = pFilter->pFuncsTable->pfnEndFlush(pFilter); - else - hr = BaseRendererImpl_EndFlush(pFilter); } LeaveCriticalSection(&pFilter->filter.csFilter); LeaveCriticalSection(&pFilter->csRenderLock); @@ -479,15 +481,6 @@ HRESULT WINAPI BaseRendererImpl_EndOfStream(struct strmbase_renderer *iface) return hr; }
-HRESULT WINAPI BaseRendererImpl_EndFlush(struct strmbase_renderer *iface) -{ - TRACE("(%p)\n", iface); - QualityControlRender_Start(iface->qcimpl, iface->stream_start); - RendererPosPassThru_ResetMediaTime(iface->pPosition); - ResetEvent(iface->flush_event); - return S_OK; -} - HRESULT WINAPI BaseRendererImpl_ClearPendingSample(struct strmbase_renderer *iface) { if (iface->pMediaSample) diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index cf209ae892..1dbc9ea4d8 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -569,7 +569,6 @@ struct strmbase_renderer_ops
HRESULT WINAPI BaseRendererImpl_ClearPendingSample(struct strmbase_renderer *filter); HRESULT WINAPI BaseRendererImpl_EndOfStream(struct strmbase_renderer *filter); -HRESULT WINAPI BaseRendererImpl_EndFlush(struct strmbase_renderer *filter); HRESULT WINAPI BaseRendererImpl_Receive(struct strmbase_renderer *filter, IMediaSample *sample);
HRESULT WINAPI strmbase_renderer_init(struct strmbase_renderer *filter, IUnknown *outer,
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/dsoundrender.c | 15 +---------- dlls/strmbase/renderer.c | 52 +++++++++++++++----------------------- include/wine/strmbase.h | 1 - 3 files changed, 21 insertions(+), 47 deletions(-)
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c index 3979853b8b..b6757fa76a 100644 --- a/dlls/quartz/dsoundrender.c +++ b/dlls/quartz/dsoundrender.c @@ -500,20 +500,7 @@ static HRESULT WINAPI DSoundRender_BreakConnect(struct strmbase_renderer *iface) static HRESULT WINAPI DSoundRender_EndOfStream(struct strmbase_renderer *iface) { DSoundRenderImpl *This = impl_from_strmbase_renderer(iface); - HRESULT hr; - - TRACE("(%p)->()\n",iface); - - hr = BaseRendererImpl_EndOfStream(iface); - if (hr != S_OK) - { - ERR("%08x\n", hr); - return hr; - } - - hr = DSoundRender_HandleEndOfStream(This); - - return hr; + return DSoundRender_HandleEndOfStream(This); }
static HRESULT WINAPI DSoundRender_EndFlush(struct strmbase_renderer *iface) diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 5aee4380f2..50bd33715d 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -82,18 +82,29 @@ static HRESULT WINAPI BaseRenderer_InputPin_Disconnect(IPin * iface)
static HRESULT WINAPI BaseRenderer_InputPin_EndOfStream(IPin * iface) { - struct strmbase_renderer *pFilter = impl_from_IPin(iface); - HRESULT hr; + struct strmbase_renderer *filter = impl_from_IPin(iface); + IFilterGraph *graph = filter->filter.filterInfo.pGraph; + IMediaEventSink *event_sink; + HRESULT hr = S_OK;
TRACE("iface %p.\n", iface);
- EnterCriticalSection(&pFilter->csRenderLock); - pFilter->eos = TRUE; - if (pFilter->pFuncsTable->pfnEndOfStream) - hr = pFilter->pFuncsTable->pfnEndOfStream(pFilter); - else - hr = BaseRendererImpl_EndOfStream(pFilter); - LeaveCriticalSection(&pFilter->csRenderLock); + EnterCriticalSection(&filter->csRenderLock); + filter->eos = TRUE; + + if (graph && SUCCEEDED(IFilterGraph_QueryInterface(graph, + &IID_IMediaEventSink, (void **)&event_sink))) + { + IMediaEventSink_Notify(event_sink, EC_COMPLETE, S_OK, + (LONG_PTR)&filter->filter.IBaseFilter_iface); + IMediaEventSink_Release(event_sink); + } + RendererPosPassThru_EOS(filter->pPosition); + SetEvent(filter->state_event); + + if (filter->pFuncsTable->pfnEndOfStream) + hr = filter->pFuncsTable->pfnEndOfStream(filter); + LeaveCriticalSection(&filter->csRenderLock); return hr; }
@@ -458,29 +469,6 @@ static const IBaseFilterVtbl strmbase_renderer_vtbl = BaseFilterImpl_QueryVendorInfo };
-HRESULT WINAPI BaseRendererImpl_EndOfStream(struct strmbase_renderer *iface) -{ - IMediaEventSink* pEventSink; - IFilterGraph *graph; - HRESULT hr = S_OK; - - TRACE("(%p)\n", iface); - - graph = iface->filter.filterInfo.pGraph; - if (graph) - { hr = IFilterGraph_QueryInterface(iface->filter.filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink); - if (SUCCEEDED(hr)) - { - hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, (LONG_PTR)iface); - IMediaEventSink_Release(pEventSink); - } - } - RendererPosPassThru_EOS(iface->pPosition); - SetEvent(iface->state_event); - - return hr; -} - HRESULT WINAPI BaseRendererImpl_ClearPendingSample(struct strmbase_renderer *iface) { if (iface->pMediaSample) diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 1dbc9ea4d8..b08303f93d 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -568,7 +568,6 @@ struct strmbase_renderer_ops };
HRESULT WINAPI BaseRendererImpl_ClearPendingSample(struct strmbase_renderer *filter); -HRESULT WINAPI BaseRendererImpl_EndOfStream(struct strmbase_renderer *filter); HRESULT WINAPI BaseRendererImpl_Receive(struct strmbase_renderer *filter, IMediaSample *sample);
HRESULT WINAPI strmbase_renderer_init(struct strmbase_renderer *filter, IUnknown *outer,
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- There's no need to do this.
Moreover, not holding the stream lock in BeginFlush() means that we no longer need to temporarily drop it in IMemInputPin::Receive(), even while waiting, since there is no longer a risk of deadlock.
The DirectX SDK documentation prescribes that BeginFlush() may take the stream lock, but can only do so after signalling the streaming thread to stop waiting (see the page "Flushing Data"). It also prescribes that the streaming thread hold the streaming lock even while waiting for any necessary events (see the page "Receiving and Delivering Samples").
dlls/strmbase/renderer.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 50bd33715d..0ef9c5b225 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -115,7 +115,6 @@ static HRESULT WINAPI BaseRenderer_InputPin_BeginFlush(IPin * iface)
TRACE("iface %p.\n", iface);
- EnterCriticalSection(&pFilter->csRenderLock); EnterCriticalSection(&pFilter->filter.csFilter); hr = BaseInputPinImpl_BeginFlush(iface); if (SUCCEEDED(hr)) @@ -124,7 +123,6 @@ static HRESULT WINAPI BaseRenderer_InputPin_BeginFlush(IPin * iface) SetEvent(pFilter->flush_event); } LeaveCriticalSection(&pFilter->filter.csFilter); - LeaveCriticalSection(&pFilter->csRenderLock); return hr; }