Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/renderer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 3a5fa19ace..9908e693e7 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -461,6 +461,7 @@ out: HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface) { BaseRenderer *This = impl_from_IBaseFilter(iface); + HRESULT hr = S_OK;
TRACE("(%p)->()\n", This);
@@ -471,7 +472,10 @@ HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface) if (This->filter.state == State_Stopped) { if (This->sink.pin.peer) + { ResetEvent(This->state_event); + hr = S_FALSE; + } This->sink.end_of_stream = FALSE; } else if (This->sink.pin.peer && This->pFuncsTable->renderer_stop_stream) @@ -485,7 +489,7 @@ HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface) } LeaveCriticalSection(&This->csRenderLock);
- return S_OK; + return hr; }
HRESULT WINAPI BaseRendererImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock)
This event was at various times used for several different purposes. The only current use is apparently to prevent stale samples from being rendered after IPin::EndFlush() completes, but in practice there's actually no foolproof way to prevent this race in the video renderer. On the other hand, as long as the filter driving the graph can ensure this, there's no need to do so.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- This event has a rather long and tortured history:
* It was introduced in acb2ff2da to ensure that the filter window had been created when CreateRenderingSubsystem() returned; this was removed in 3b5198c82;
* It was reused in 9985f2efc to implement state change [viz. waiting for a sample during IBaseFilter::Pause()];
* It was reused again in 351165e30 to fix "a race condition". What that race condition is is not specfied, but it would seem to prevent a stale sample from rendering after IPin::EndFlush() had run;
* Most, but not all of the code for state change was removed in 896be1355, in favor of strmbase's "evComplete" event (later renamed to "state_event").
The only legitimate purpose this event is serving, then, is to prevent Receive() and flushing from racing with each other.
The documentation is not very clear, and almost contradicts itself, when advising how to actually avoid such races. In the documentation for IPin::BeginFlush() it says that the filter:
"1. Passes the IPin::BeginFlush call downstream. 2. Sets an internal flag that causes all data-streaming methods to fail, such as IMemInputPin::Receive. 3. Returns from any blocked calls to the Receive method."
which weakly implies that the filter should ensure that Receive() actually does return, and in the "Flushing Data" page we receive pseudocode for BeginFlush() that specifically ensures that the streaming thread has returned:
// At this point, the Receive method can't be blocked. Make sure // it finishes, by taking the streaming lock. (Not necessary if this // is the last step.)
But "Not necessary if this is the last step" is kind of ambiguous.
On the other hand, the "Flushing" page states quite explicitly that it's the responsibility of EndFlush() to wait for "all queued samples to be discarded".
In theory, as long as BeginFlush() really does unblock everything that needs to be unblocked, it would be enough for the most upstream filter in the chain to wait for its streaming thread to be unblocked. In fact it could even do that in EndFlush(), though better not to so as to avoid spinning sending samples.
In fact, that's actually not only the least we can do, but it's also the best. Since there's a gap between entering Receive() and doing anything else, we can get an ABA and render an old sample. The only filter that can actually prevent this is the one driving the graph.
GStreamer acts in roughly this way; the GstBaseParse class grabs the stream lock while flushing, and downstream filters don't bother to do their own synchronization.
dlls/quartz/videorenderer.c | 36 ------------------------------------ 1 file changed, 36 deletions(-)
diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c index a11c2047a6..be66d52c42 100644 --- a/dlls/quartz/videorenderer.c +++ b/dlls/quartz/videorenderer.c @@ -46,7 +46,6 @@ typedef struct VideoRendererImpl
BOOL init;
- HANDLE hEvent; RECT SourceRect; RECT DestRect; RECT WindowPos; @@ -218,11 +217,9 @@ static HRESULT WINAPI VideoRenderer_DoRenderSample(BaseRenderer* iface, IMediaSa } #endif
- SetEvent(This->hEvent); if (This->renderer.filter.state == State_Paused) { VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream); - SetEvent(This->hEvent); if (This->renderer.filter.state == State_Paused) { /* Flushing */ @@ -287,34 +284,12 @@ static HRESULT WINAPI VideoRenderer_CheckMediaType(BaseRenderer *iface, const AM return S_FALSE; }
-static HRESULT WINAPI VideoRenderer_EndFlush(BaseRenderer* iface) -{ - VideoRendererImpl *This = impl_from_BaseRenderer(iface); - - TRACE("(%p)->()\n", iface); - - if (This->renderer.pMediaSample) { - ResetEvent(This->hEvent); - LeaveCriticalSection(&iface->filter.csFilter); - LeaveCriticalSection(&iface->csRenderLock); - WaitForSingleObject(This->hEvent, INFINITE); - EnterCriticalSection(&iface->csRenderLock); - EnterCriticalSection(&iface->filter.csFilter); - } - if (This->renderer.filter.state == State_Paused) { - ResetEvent(This->hEvent); - } - - return BaseRendererImpl_EndFlush(iface); -} - static void video_renderer_destroy(BaseRenderer *iface) { VideoRendererImpl *filter = impl_from_BaseRenderer(iface);
BaseControlWindow_Destroy(&filter->baseControlWindow); BaseControlVideo_Destroy(&filter->baseControlVideo); - CloseHandle(filter->hEvent);
strmbase_renderer_cleanup(&filter->renderer); CoTaskMemFree(filter); @@ -354,7 +329,6 @@ static void video_renderer_stop_stream(BaseRenderer *iface)
TRACE("(%p)->()\n", This);
- SetEvent(This->hEvent); if (This->baseControlWindow.AutoShow) /* Black it out */ RedrawWindow(This->baseControlWindow.baseWindow.hWnd, NULL, NULL, RDW_INVALIDATE|RDW_ERASE); @@ -370,10 +344,7 @@ static void video_renderer_start_stream(BaseRenderer *iface) && (This->renderer.filter.state == State_Stopped || !This->renderer.sink.end_of_stream)) { if (This->renderer.filter.state == State_Stopped) - { - ResetEvent(This->hEvent); VideoRenderer_AutoShowWindow(This); - } } }
@@ -409,7 +380,6 @@ static const BaseRendererFuncTable BaseFuncTable = .renderer_start_stream = video_renderer_start_stream, .renderer_stop_stream = video_renderer_stop_stream, .pfnShouldDrawSampleNow = VideoRenderer_ShouldDrawSampleNow, - .pfnEndFlush = VideoRenderer_EndFlush, .renderer_destroy = video_renderer_destroy, .renderer_query_interface = video_renderer_query_interface, .renderer_pin_query_interface = video_renderer_pin_query_interface, @@ -594,7 +564,6 @@ static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface) if (This->renderer.filter.state == State_Stopped) { This->renderer.sink.end_of_stream = 0; - ResetEvent(This->hEvent); VideoRenderer_AutoShowWindow(This); }
@@ -858,13 +827,8 @@ HRESULT VideoRenderer_create(IUnknown *outer, void **out) if (FAILED(hr)) goto fail;
- pVideoRenderer->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - if (FAILED(hr = BaseWindowImpl_PrepareWindow(&pVideoRenderer->baseControlWindow.baseWindow))) - { - CloseHandle(pVideoRenderer->hEvent); goto fail; - }
*out = &pVideoRenderer->renderer.filter.IUnknown_inner; return S_OK;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/renderer.c | 5 +++++ include/wine/strmbase.h | 1 + 2 files changed, 6 insertions(+)
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 9908e693e7..0f714c2a88 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -438,6 +438,9 @@ HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart) if (This->filter.state == State_Running) goto out;
+ if (This->filter.state == State_Stopped && This->pFuncsTable->renderer_init_stream) + This->pFuncsTable->renderer_init_stream(This); + SetEvent(This->state_event);
if (This->sink.pin.peer) @@ -477,6 +480,8 @@ HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface) hr = S_FALSE; } This->sink.end_of_stream = FALSE; + if (This->pFuncsTable->renderer_init_stream) + This->pFuncsTable->renderer_init_stream(This); } else if (This->sink.pin.peer && This->pFuncsTable->renderer_stop_stream) This->pFuncsTable->renderer_stop_stream(This); diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 74c8f4721b..f9136fadff 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -550,6 +550,7 @@ typedef HRESULT (WINAPI *BaseRenderer_CompleteConnect) (BaseRenderer *This, IPin typedef struct BaseRendererFuncTable { BaseRenderer_CheckMediaType pfnCheckMediaType; BaseRenderer_DoRenderSample pfnDoRenderSample; + void (*renderer_init_stream)(BaseRenderer *iface); void (*renderer_start_stream)(BaseRenderer *iface); void (*renderer_stop_stream)(BaseRenderer *iface); BaseRenderer_ShouldDrawSampleNow pfnShouldDrawSampleNow;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/videorenderer.c | 42 +++++-------------------------------- 1 file changed, 5 insertions(+), 37 deletions(-)
diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c index be66d52c42..24b76e6e47 100644 --- a/dlls/quartz/videorenderer.c +++ b/dlls/quartz/videorenderer.c @@ -334,18 +334,11 @@ static void video_renderer_stop_stream(BaseRenderer *iface) RedrawWindow(This->baseControlWindow.baseWindow.hWnd, NULL, NULL, RDW_INVALIDATE|RDW_ERASE); }
-static void video_renderer_start_stream(BaseRenderer *iface) +static void video_renderer_init_stream(BaseRenderer *iface) { - VideoRendererImpl *This = impl_from_BaseRenderer(iface); + VideoRendererImpl *filter = impl_from_BaseRenderer(iface);
- TRACE("(%p)\n", This); - - if (This->renderer.sink.pin.peer - && (This->renderer.filter.state == State_Stopped || !This->renderer.sink.end_of_stream)) - { - if (This->renderer.filter.state == State_Stopped) - VideoRenderer_AutoShowWindow(This); - } + VideoRenderer_AutoShowWindow(filter); }
static RECT WINAPI VideoRenderer_GetDefaultRect(BaseWindow *iface) @@ -377,7 +370,7 @@ static const BaseRendererFuncTable BaseFuncTable = { .pfnCheckMediaType = VideoRenderer_CheckMediaType, .pfnDoRenderSample = VideoRenderer_DoRenderSample, - .renderer_start_stream = video_renderer_start_stream, + .renderer_init_stream = video_renderer_init_stream, .renderer_stop_stream = video_renderer_stop_stream, .pfnShouldDrawSampleNow = VideoRenderer_ShouldDrawSampleNow, .renderer_destroy = video_renderer_destroy, @@ -550,31 +543,6 @@ static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = { VideoRenderer_SetTargetRect };
-/** IMediaFilter methods **/ - -static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface) -{ - VideoRendererImpl *This = impl_from_IBaseFilter(iface); - - TRACE("(%p/%p)->()\n", This, iface); - - EnterCriticalSection(&This->renderer.csRenderLock); - if (This->renderer.filter.state != State_Paused) - { - if (This->renderer.filter.state == State_Stopped) - { - This->renderer.sink.end_of_stream = 0; - VideoRenderer_AutoShowWindow(This); - } - - ResetEvent(This->renderer.flush_event); - This->renderer.filter.state = State_Paused; - } - LeaveCriticalSection(&This->renderer.csRenderLock); - - return S_OK; -} - static const IBaseFilterVtbl VideoRenderer_Vtbl = { BaseFilterImpl_QueryInterface, @@ -582,7 +550,7 @@ static const IBaseFilterVtbl VideoRenderer_Vtbl = BaseFilterImpl_Release, BaseFilterImpl_GetClassID, BaseRendererImpl_Stop, - VideoRenderer_Pause, + BaseRendererImpl_Pause, BaseRendererImpl_Run, BaseRendererImpl_GetState, BaseRendererImpl_SetSyncSource,
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/evr/evr.c | 21 +-------------------- dlls/qedit/nullrenderer.c | 21 +-------------------- dlls/quartz/dsoundrender.c | 22 +--------------------- dlls/quartz/videorenderer.c | 23 ++--------------------- dlls/quartz/vmr9.c | 21 +-------------------- dlls/strmbase/renderer.c | 37 ++++++++++++++++++++++++++++--------- include/wine/strmbase.h | 10 ++-------- 7 files changed, 36 insertions(+), 119 deletions(-)
diff --git a/dlls/evr/evr.c b/dlls/evr/evr.c index 94f88ffeca..8bd38c243d 100644 --- a/dlls/evr/evr.c +++ b/dlls/evr/evr.c @@ -36,25 +36,6 @@ typedef struct BaseRenderer renderer; } evr_filter;
-static const IBaseFilterVtbl basefilter_vtbl = -{ - BaseFilterImpl_QueryInterface, - BaseFilterImpl_AddRef, - BaseFilterImpl_Release, - BaseFilterImpl_GetClassID, - BaseRendererImpl_Stop, - BaseRendererImpl_Pause, - BaseRendererImpl_Run, - BaseRendererImpl_GetState, - BaseRendererImpl_SetSyncSource, - BaseFilterImpl_GetSyncSource, - BaseFilterImpl_EnumPins, - BaseFilterImpl_FindPin, - BaseFilterImpl_QueryFilterInfo, - BaseFilterImpl_JoinFilterGraph, - BaseFilterImpl_QueryVendorInfo -}; - static inline evr_filter *impl_from_BaseRenderer(BaseRenderer *iface) { return CONTAINING_RECORD(iface, evr_filter, renderer); @@ -98,7 +79,7 @@ HRESULT evr_filter_create(IUnknown *outer, void **out) if (!object) return E_OUTOFMEMORY;
- strmbase_renderer_init(&object->renderer, &basefilter_vtbl, outer, + strmbase_renderer_init(&object->renderer, outer, &CLSID_EnhancedVideoRenderer, sink_name, &renderer_ops);
*out = &object->renderer.filter.IUnknown_inner; diff --git a/dlls/qedit/nullrenderer.c b/dlls/qedit/nullrenderer.c index 2c9aff8bc0..ee68e6244c 100644 --- a/dlls/qedit/nullrenderer.c +++ b/dlls/qedit/nullrenderer.c @@ -62,25 +62,6 @@ static const BaseRendererFuncTable RendererFuncTable = .renderer_destroy = null_renderer_destroy, };
-static const IBaseFilterVtbl NullRenderer_Vtbl = -{ - BaseFilterImpl_QueryInterface, - BaseFilterImpl_AddRef, - BaseFilterImpl_Release, - BaseFilterImpl_GetClassID, - BaseRendererImpl_Stop, - BaseRendererImpl_Pause, - BaseRendererImpl_Run, - BaseRendererImpl_GetState, - BaseRendererImpl_SetSyncSource, - BaseFilterImpl_GetSyncSource, - BaseFilterImpl_EnumPins, - BaseFilterImpl_FindPin, - BaseFilterImpl_QueryFilterInfo, - BaseFilterImpl_JoinFilterGraph, - BaseFilterImpl_QueryVendorInfo -}; - HRESULT NullRenderer_create(IUnknown *outer, void **out) { static const WCHAR sink_name[] = {'I','n',0}; @@ -92,7 +73,7 @@ HRESULT NullRenderer_create(IUnknown *outer, void **out)
pNullRenderer = CoTaskMemAlloc(sizeof(NullRendererImpl));
- hr = strmbase_renderer_init(&pNullRenderer->renderer, &NullRenderer_Vtbl, outer, + hr = strmbase_renderer_init(&pNullRenderer->renderer, outer, &CLSID_NullRenderer, sink_name, &RendererFuncTable);
if (FAILED(hr)) diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c index 6ba6e4c7ae..c0ff8ca5af 100644 --- a/dlls/quartz/dsoundrender.c +++ b/dlls/quartz/dsoundrender.c @@ -39,7 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); */ static const REFERENCE_TIME DSoundRenderer_Max_Fill = 150 * 10000;
-static const IBaseFilterVtbl DSoundRender_Vtbl; static const IBasicAudioVtbl IBasicAudio_Vtbl; static const IReferenceClockVtbl IReferenceClock_Vtbl; static const IAMDirectSoundVtbl IAMDirectSound_Vtbl; @@ -610,7 +609,7 @@ HRESULT DSoundRender_create(IUnknown *outer, void **out) return E_OUTOFMEMORY; ZeroMemory(pDSoundRender, sizeof(DSoundRenderImpl));
- hr = strmbase_renderer_init(&pDSoundRender->renderer, &DSoundRender_Vtbl, + hr = strmbase_renderer_init(&pDSoundRender->renderer, outer, &CLSID_DSoundRender, sink_name, &BaseFuncTable);
pDSoundRender->IBasicAudio_iface.lpVtbl = &IBasicAudio_Vtbl; @@ -652,25 +651,6 @@ HRESULT DSoundRender_create(IUnknown *outer, void **out) return hr; }
-static const IBaseFilterVtbl DSoundRender_Vtbl = -{ - BaseFilterImpl_QueryInterface, - BaseFilterImpl_AddRef, - BaseFilterImpl_Release, - BaseFilterImpl_GetClassID, - BaseRendererImpl_Stop, - BaseRendererImpl_Pause, - BaseRendererImpl_Run, - BaseRendererImpl_GetState, - BaseRendererImpl_SetSyncSource, - BaseFilterImpl_GetSyncSource, - BaseFilterImpl_EnumPins, - BaseFilterImpl_FindPin, - BaseFilterImpl_QueryFilterInfo, - BaseFilterImpl_JoinFilterGraph, - BaseFilterImpl_QueryVendorInfo -}; - /*** IUnknown methods ***/ static HRESULT WINAPI Basicaudio_QueryInterface(IBasicAudio *iface, REFIID riid, diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c index 24b76e6e47..48b845a14b 100644 --- a/dlls/quartz/videorenderer.c +++ b/dlls/quartz/videorenderer.c @@ -543,25 +543,6 @@ static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = { VideoRenderer_SetTargetRect };
-static const IBaseFilterVtbl VideoRenderer_Vtbl = -{ - BaseFilterImpl_QueryInterface, - BaseFilterImpl_AddRef, - BaseFilterImpl_Release, - BaseFilterImpl_GetClassID, - BaseRendererImpl_Stop, - BaseRendererImpl_Pause, - BaseRendererImpl_Run, - BaseRendererImpl_GetState, - BaseRendererImpl_SetSyncSource, - BaseFilterImpl_GetSyncSource, - BaseFilterImpl_EnumPins, - BaseFilterImpl_FindPin, - BaseFilterImpl_QueryFilterInfo, - BaseFilterImpl_JoinFilterGraph, - BaseFilterImpl_QueryVendorInfo -}; - static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface, LONG *FullScreenMode) { @@ -777,8 +758,8 @@ HRESULT VideoRenderer_create(IUnknown *outer, void **out)
pVideoRenderer->IOverlay_iface.lpVtbl = &overlay_vtbl;
- hr = strmbase_renderer_init(&pVideoRenderer->renderer, &VideoRenderer_Vtbl, - outer, &CLSID_VideoRenderer, sink_name, &BaseFuncTable); + hr = strmbase_renderer_init(&pVideoRenderer->renderer, outer, + &CLSID_VideoRenderer, sink_name, &BaseFuncTable);
if (FAILED(hr)) goto fail; diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c index c3b948f599..d631165d1b 100644 --- a/dlls/quartz/vmr9.c +++ b/dlls/quartz/vmr9.c @@ -758,25 +758,6 @@ static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = { VMR9_SetTargetRect };
-static const IBaseFilterVtbl VMR_Vtbl = -{ - BaseFilterImpl_QueryInterface, - BaseFilterImpl_AddRef, - BaseFilterImpl_Release, - BaseFilterImpl_GetClassID, - BaseRendererImpl_Stop, - BaseRendererImpl_Pause, - BaseRendererImpl_Run, - BaseRendererImpl_GetState, - BaseRendererImpl_SetSyncSource, - BaseFilterImpl_GetSyncSource, - BaseFilterImpl_EnumPins, - BaseFilterImpl_FindPin, - BaseFilterImpl_QueryFilterInfo, - BaseFilterImpl_JoinFilterGraph, - BaseFilterImpl_QueryVendorInfo -}; - static const IVideoWindowVtbl IVideoWindow_VTable = { BaseControlWindowImpl_QueryInterface, @@ -2247,7 +2228,7 @@ static HRESULT vmr_create(IUnknown *outer, void **out, const CLSID *clsid) pVMR->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl; pVMR->IOverlay_iface.lpVtbl = &overlay_vtbl;
- hr = strmbase_renderer_init(&pVMR->renderer, &VMR_Vtbl, outer, clsid, sink_name, &BaseFuncTable); + hr = strmbase_renderer_init(&pVMR->renderer, outer, clsid, sink_name, &BaseFuncTable); if (FAILED(hr)) goto fail;
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 0f714c2a88..86c4f7d1d7 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -250,15 +250,15 @@ static const BaseInputPinFuncTable input_BaseInputFuncTable = .pfnReceive = BaseRenderer_Receive, };
+static const IBaseFilterVtbl strmbase_renderer_vtbl;
-HRESULT WINAPI strmbase_renderer_init(BaseRenderer *filter, const IBaseFilterVtbl *vtbl, - IUnknown *outer, const CLSID *clsid, const WCHAR *sink_name, - const BaseRendererFuncTable *pBaseFuncsTable) +HRESULT WINAPI strmbase_renderer_init(BaseRenderer *filter, IUnknown *outer, + const CLSID *clsid, const WCHAR *sink_name, const BaseRendererFuncTable *pBaseFuncsTable) { HRESULT hr;
memset(filter, 0, sizeof(*filter)); - strmbase_filter_init(&filter->filter, vtbl, outer, clsid, &filter_ops); + strmbase_filter_init(&filter->filter, &strmbase_renderer_vtbl, outer, clsid, &filter_ops);
filter->pFuncsTable = pBaseFuncsTable;
@@ -407,7 +407,7 @@ HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSamp return hr; }
-HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface) +static HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter *iface) { BaseRenderer *This = impl_from_IBaseFilter(iface);
@@ -427,7 +427,7 @@ HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface) return S_OK; }
-HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart) +static HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter *iface, REFERENCE_TIME tStart) { BaseRenderer *This = impl_from_IBaseFilter(iface);
@@ -461,7 +461,7 @@ out: return S_OK; }
-HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface) +static HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter *iface) { BaseRenderer *This = impl_from_IBaseFilter(iface); HRESULT hr = S_OK; @@ -497,7 +497,7 @@ HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface) return hr; }
-HRESULT WINAPI BaseRendererImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock) +static HRESULT WINAPI BaseRendererImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock) { BaseRenderer *This = impl_from_IBaseFilter(iface); HRESULT hr; @@ -510,7 +510,7 @@ HRESULT WINAPI BaseRendererImpl_SetSyncSource(IBaseFilter *iface, IReferenceCloc }
-HRESULT WINAPI BaseRendererImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) +static HRESULT WINAPI BaseRendererImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) { HRESULT hr; BaseRenderer *This = impl_from_IBaseFilter(iface); @@ -527,6 +527,25 @@ HRESULT WINAPI BaseRendererImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsT return hr; }
+static const IBaseFilterVtbl strmbase_renderer_vtbl = +{ + BaseFilterImpl_QueryInterface, + BaseFilterImpl_AddRef, + BaseFilterImpl_Release, + BaseFilterImpl_GetClassID, + BaseRendererImpl_Stop, + BaseRendererImpl_Pause, + BaseRendererImpl_Run, + BaseRendererImpl_GetState, + BaseRendererImpl_SetSyncSource, + BaseFilterImpl_GetSyncSource, + BaseFilterImpl_EnumPins, + BaseFilterImpl_FindPin, + BaseFilterImpl_QueryFilterInfo, + BaseFilterImpl_JoinFilterGraph, + BaseFilterImpl_QueryVendorInfo +}; + HRESULT WINAPI BaseRendererImpl_EndOfStream(BaseRenderer* iface) { IMediaEventSink* pEventSink; diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index f9136fadff..acfe6d8ab4 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -565,19 +565,13 @@ typedef struct BaseRendererFuncTable { } BaseRendererFuncTable;
HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSample); -HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface); -HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart); -HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface); -HRESULT WINAPI BaseRendererImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock); -HRESULT WINAPI BaseRendererImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState); HRESULT WINAPI BaseRendererImpl_EndOfStream(BaseRenderer* iface); HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer* iface); HRESULT WINAPI BaseRendererImpl_EndFlush(BaseRenderer* iface); HRESULT WINAPI BaseRendererImpl_ClearPendingSample(BaseRenderer *iface);
-HRESULT WINAPI strmbase_renderer_init(BaseRenderer *filter, const IBaseFilterVtbl *vtbl, - IUnknown *outer, const CLSID *clsid, const WCHAR *sink_name, - const BaseRendererFuncTable *func_table); +HRESULT WINAPI strmbase_renderer_init(BaseRenderer *filter, IUnknown *outer, + const CLSID *clsid, const WCHAR *sink_name, const BaseRendererFuncTable *func_table); void strmbase_renderer_cleanup(BaseRenderer *filter);
/* Dll Functions */