diff --git a/dlls/strmbase/filter.c b/dlls/strmbase/filter.c index e1885cd935f..ffe506d5171 100644 --- a/dlls/strmbase/filter.c +++ b/dlls/strmbase/filter.c @@ -126,54 +126,82 @@ HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid) HRESULT WINAPI BaseFilterImpl_Stop(IBaseFilter *iface) { struct strmbase_filter *filter = impl_from_IBaseFilter(iface); + HRESULT hr = S_OK; - TRACE("iface %p.\n", iface); + TRACE("filter %p.\n", filter); EnterCriticalSection(&filter->csFilter); - filter->state = State_Stopped; + + if (filter->state == State_Running && filter->ops->filter_stop_stream) + hr = filter->ops->filter_stop_stream(filter); + if (SUCCEEDED(hr) && filter->ops->filter_cleanup_stream) + hr = filter->ops->filter_cleanup_stream(filter); + if (SUCCEEDED(hr)) + filter->state = State_Stopped; + LeaveCriticalSection(&filter->csFilter); - return S_OK; + return hr; } HRESULT WINAPI BaseFilterImpl_Pause(IBaseFilter *iface) { struct strmbase_filter *filter = impl_from_IBaseFilter(iface); + HRESULT hr = S_OK; - TRACE("iface %p.\n", iface); + TRACE("filter %p.\n", filter); EnterCriticalSection(&filter->csFilter); - filter->state = State_Paused; + + if (filter->state == State_Stopped && filter->ops->filter_init_stream) + hr = filter->ops->filter_init_stream(filter); + else if (filter->state == State_Running && filter->ops->filter_stop_stream) + hr = filter->ops->filter_stop_stream(filter); + if (SUCCEEDED(hr)) + filter->state = State_Paused; + LeaveCriticalSection(&filter->csFilter); - return S_OK; + return hr; } HRESULT WINAPI BaseFilterImpl_Run(IBaseFilter *iface, REFERENCE_TIME start) { struct strmbase_filter *filter = impl_from_IBaseFilter(iface); + HRESULT hr = S_OK; - TRACE("iface %p, start %s.\n", iface, debugstr_time(start)); + TRACE("filter %p, start %s.\n", filter, debugstr_time(start)); EnterCriticalSection(&filter->csFilter); - filter->state = State_Running; + + if (filter->state == State_Stopped && filter->ops->filter_init_stream) + hr = filter->ops->filter_init_stream(filter); + if (SUCCEEDED(hr) && filter->ops->filter_start_stream) + hr = filter->ops->filter_start_stream(filter, start); + if (SUCCEEDED(hr)) + filter->state = State_Running; + LeaveCriticalSection(&filter->csFilter); - return S_OK; + return hr; } -HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState ) +HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter *iface, DWORD timeout, FILTER_STATE *state) { - struct strmbase_filter *This = impl_from_IBaseFilter(iface); - TRACE("(%p)->(%d, %p)\n", This, dwMilliSecsTimeout, pState); + struct strmbase_filter *filter = impl_from_IBaseFilter(iface); + HRESULT hr = S_OK; - EnterCriticalSection(&This->csFilter); - { - *pState = This->state; - } - LeaveCriticalSection(&This->csFilter); + TRACE("filter %p, timeout %u, state %p.\n", filter, timeout, state); - return S_OK; + EnterCriticalSection(&filter->csFilter); + + if (filter->ops->filter_wait_state) + hr = filter->ops->filter_wait_state(filter, timeout); + *state = filter->state; + + LeaveCriticalSection(&filter->csFilter); + + return hr; } HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 3f0883fcb66..a4920054e62 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -170,6 +170,12 @@ struct strmbase_filter_ops IPin *(*filter_get_pin)(struct strmbase_filter *iface, unsigned int index); void (*filter_destroy)(struct strmbase_filter *iface); HRESULT (*filter_query_interface)(struct strmbase_filter *iface, REFIID iid, void **out); + + HRESULT (*filter_init_stream)(struct strmbase_filter *iface); + HRESULT (*filter_start_stream)(struct strmbase_filter *iface, REFERENCE_TIME time); + HRESULT (*filter_stop_stream)(struct strmbase_filter *iface); + HRESULT (*filter_cleanup_stream)(struct strmbase_filter *iface); + HRESULT (*filter_wait_state)(struct strmbase_filter *iface, DWORD timeout); }; HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv);