From 7ef5f3be5aaf6317414826a5b979a6c288b13697 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Fri, 17 May 2019 00:31:06 -0500 Subject: [PATCH] amstream: Reimplement IBaseFilter methods in the media stream filter. In the long (or even short) term we probably want to decouple amstream from strmbase entirely. The fact that pins and filters belong to separate objects (and either one can even be provided by the application) prevents us from performing some helpful restructuring. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/amstream/mediastreamfilter.c | 225 +++++++++++++++++++----------- 1 file changed, 144 insertions(+), 81 deletions(-) diff --git a/dlls/amstream/mediastreamfilter.c b/dlls/amstream/mediastreamfilter.c index e9f98b63ca7..2daffeabdbe 100644 --- a/dlls/amstream/mediastreamfilter.c +++ b/dlls/amstream/mediastreamfilter.c @@ -18,19 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "wine/debug.h" - #define COBJMACROS - -#include "winbase.h" -#include "wingdi.h" -#include "dshow.h" - -#include "wine/strmbase.h" - #include "amstream_private.h" - -#include "ddstream.h" +#include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(amstream); @@ -171,18 +161,22 @@ static const IEnumPinsVtbl enum_pins_vtbl = }; typedef struct { - BaseFilter filter; + IMediaStreamFilter IMediaStreamFilter_iface; + LONG refcount; + CRITICAL_SECTION cs; + + IReferenceClock *clock; + WCHAR name[128]; + IFilterGraph *graph; ULONG nb_streams; IAMMediaStream** streams; } IMediaStreamFilterImpl; static inline IMediaStreamFilterImpl *impl_from_IMediaStreamFilter(IMediaStreamFilter *iface) { - return CONTAINING_RECORD(iface, IMediaStreamFilterImpl, filter); + return CONTAINING_RECORD(iface, IMediaStreamFilterImpl, IMediaStreamFilter_iface); } -/*** IUnknown methods ***/ - static HRESULT WINAPI MediaStreamFilterImpl_QueryInterface(IMediaStreamFilter *iface, REFIID riid, void **ret_iface) { TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ret_iface); @@ -207,47 +201,45 @@ static HRESULT WINAPI MediaStreamFilterImpl_QueryInterface(IMediaStreamFilter *i static ULONG WINAPI MediaStreamFilterImpl_AddRef(IMediaStreamFilter *iface) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - ULONG ref = BaseFilterImpl_AddRef(&This->filter.IBaseFilter_iface); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + ULONG refcount = InterlockedIncrement(&filter->refcount); - TRACE("(%p)->(): new ref = %u\n", iface, ref); + TRACE("%p increasing refcount to %u.\n", iface, refcount); - return ref; + return refcount; } static ULONG WINAPI MediaStreamFilterImpl_Release(IMediaStreamFilter *iface) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - ULONG ref = InterlockedDecrement(&This->filter.refCount); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + ULONG refcount = InterlockedDecrement(&filter->refcount); + unsigned int i; - TRACE("(%p)->(): new ref = %u\n", iface, ref); + TRACE("%p decreasing refcount to %u.\n", iface, refcount); - if (!ref) + if (!refcount) { - ULONG i; - for (i = 0; i < This->nb_streams; i++) + for (i = 0; i < filter->nb_streams; ++i) { - IAMMediaStream_JoinFilter(This->streams[i], NULL); - IAMMediaStream_Release(This->streams[i]); + IAMMediaStream_JoinFilter(filter->streams[i], NULL); + IAMMediaStream_Release(filter->streams[i]); } - CoTaskMemFree(This->streams); - BaseFilter_Destroy(&This->filter); - HeapFree(GetProcessHeap(), 0, This); + heap_free(filter->streams); + if (filter->clock) + IReferenceClock_Release(filter->clock); + DeleteCriticalSection(&filter->cs); + heap_free(filter); } - return ref; + return refcount; } -/*** IPersist methods ***/ - static HRESULT WINAPI MediaStreamFilterImpl_GetClassID(IMediaStreamFilter *iface, CLSID *clsid) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_GetClassID(&This->filter.IBaseFilter_iface, clsid); + *clsid = CLSID_MediaStreamFilter; + return S_OK; } -/*** IBaseFilter methods ***/ - static HRESULT WINAPI MediaStreamFilterImpl_Stop(IMediaStreamFilter *iface) { FIXME("(%p)->(): Stub!\n", iface); @@ -269,22 +261,48 @@ static HRESULT WINAPI MediaStreamFilterImpl_Run(IMediaStreamFilter *iface, REFER return E_NOTIMPL; } -static HRESULT WINAPI MediaStreamFilterImpl_GetState(IMediaStreamFilter *iface, DWORD ms_timeout, FILTER_STATE *state) +static HRESULT WINAPI MediaStreamFilterImpl_GetState(IMediaStreamFilter *iface, DWORD timeout, FILTER_STATE *state) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_GetState(&This->filter.IBaseFilter_iface, ms_timeout, state); + FIXME("iface %p, timeout %u, state %p, stub!\n", iface, timeout, state); + + *state = State_Stopped; + return S_OK; } static HRESULT WINAPI MediaStreamFilterImpl_SetSyncSource(IMediaStreamFilter *iface, IReferenceClock *clock) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_SetSyncSource(&This->filter.IBaseFilter_iface, clock); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + + TRACE("iface %p, clock %p.\n", iface, clock); + + EnterCriticalSection(&filter->cs); + + if (clock) + IReferenceClock_AddRef(clock); + if (filter->clock) + IReferenceClock_Release(filter->clock); + filter->clock = clock; + + LeaveCriticalSection(&filter->cs); + + return S_OK; } static HRESULT WINAPI MediaStreamFilterImpl_GetSyncSource(IMediaStreamFilter *iface, IReferenceClock **clock) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_GetSyncSource(&This->filter.IBaseFilter_iface, clock); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + + TRACE("iface %p, clock %p.\n", iface, clock); + + EnterCriticalSection(&filter->cs); + + if (filter->clock) + IReferenceClock_AddRef(filter->clock); + *clock = filter->clock; + + LeaveCriticalSection(&filter->cs); + + return S_OK; } static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface, IEnumPins **enum_pins) @@ -295,6 +313,8 @@ static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface, TRACE("iface %p, enum_pins %p.\n", iface, enum_pins); + EnterCriticalSection(&filter->cs); + if (!enum_pins) return E_POINTER; @@ -316,32 +336,91 @@ static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface, WARN("Stream %p does not support IPin.\n", filter->streams[i]); } + LeaveCriticalSection(&filter->cs); + *enum_pins = &object->IEnumPins_iface; return S_OK; } -static HRESULT WINAPI MediaStreamFilterImpl_FindPin(IMediaStreamFilter *iface, LPCWSTR id, IPin **pin) +static HRESULT WINAPI MediaStreamFilterImpl_FindPin(IMediaStreamFilter *iface, const WCHAR *id, IPin **out) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_FindPin(&This->filter.IBaseFilter_iface, id, pin); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + unsigned int i; + WCHAR *ret_id; + IPin *pin; + + TRACE("iface %p, id %s, out %p.\n", iface, debugstr_w(id), out); + + EnterCriticalSection(&filter->cs); + + for (i = 0; i < filter->nb_streams; ++i) + { + if (FAILED(IAMMediaStream_QueryInterface(filter->streams[i], &IID_IPin, (void **)&pin))) + { + WARN("Stream %p does not support IPin.\n", filter->streams[i]); + continue; + } + + if (SUCCEEDED(IPin_QueryId(pin, &ret_id))) + { + if (!lstrcmpW(id, ret_id)) + { + CoTaskMemFree(ret_id); + *out = pin; + return S_OK; + } + CoTaskMemFree(ret_id); + } + IPin_Release(pin); + } + + LeaveCriticalSection(&filter->cs); + + return VFW_E_NOT_FOUND; } static HRESULT WINAPI MediaStreamFilterImpl_QueryFilterInfo(IMediaStreamFilter *iface, FILTER_INFO *info) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_QueryFilterInfo(&This->filter.IBaseFilter_iface, info); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + + TRACE("iface %p, info %p.\n", iface, info); + + EnterCriticalSection(&filter->cs); + + lstrcpyW(info->achName, filter->name); + if (filter->graph) + IFilterGraph_AddRef(filter->graph); + info->pGraph = filter->graph; + + LeaveCriticalSection(&filter->cs); + + return S_OK; } -static HRESULT WINAPI MediaStreamFilterImpl_JoinFilterGraph(IMediaStreamFilter *iface, IFilterGraph *graph, LPCWSTR name) +static HRESULT WINAPI MediaStreamFilterImpl_JoinFilterGraph(IMediaStreamFilter *iface, + IFilterGraph *graph, const WCHAR *name) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_JoinFilterGraph(&This->filter.IBaseFilter_iface, graph, name); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + + TRACE("iface %p, graph %p, name.%s.\n", iface, graph, debugstr_w(name)); + + EnterCriticalSection(&filter->cs); + + if (name) + lstrcpynW(filter->name, name, ARRAY_SIZE(filter->name)); + else + filter->name[0] = 0; + filter->graph = graph; + + LeaveCriticalSection(&filter->cs); + + return S_OK; } static HRESULT WINAPI MediaStreamFilterImpl_QueryVendorInfo(IMediaStreamFilter *iface, LPWSTR *vendor_info) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_QueryVendorInfo(&This->filter.IBaseFilter_iface, vendor_info); + WARN("iface %p, vendor_info %p, stub!\n", iface, vendor_info); + return E_NOTIMPL; } /*** IMediaStreamFilter methods ***/ @@ -470,40 +549,24 @@ static const IMediaStreamFilterVtbl MediaStreamFilter_Vtbl = MediaStreamFilterImpl_EndOfStream }; -static IPin* WINAPI MediaStreamFilterImpl_GetPin(BaseFilter *iface, int pos) +HRESULT MediaStreamFilter_create(IUnknown *outer, void **out) { - IMediaStreamFilterImpl* This = (IMediaStreamFilterImpl*)iface; + IMediaStreamFilterImpl *object; - if (pos < This->nb_streams) - { - IPin *pin = NULL; - IAMMediaStream_QueryInterface(This->streams[pos], &IID_IPin, (void **)&pin); - return pin; - } + TRACE("outer %p, out %p.\n", outer, out); - return NULL; -} - -static const BaseFilterFuncTable BaseFuncTable = { - MediaStreamFilterImpl_GetPin, -}; - -HRESULT MediaStreamFilter_create(IUnknown *pUnkOuter, void **ppObj) -{ - IMediaStreamFilterImpl* object; - - TRACE("(%p,%p)\n", pUnkOuter, ppObj); - - if( pUnkOuter ) + if (outer) return CLASS_E_NOAGGREGATION; - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IMediaStreamFilterImpl)); - if (!object) + if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; - BaseFilter_Init(&object->filter, (IBaseFilterVtbl*)&MediaStreamFilter_Vtbl, &CLSID_MediaStreamFilter, (DWORD_PTR)(__FILE__ ": MediaStreamFilterImpl.csFilter"), &BaseFuncTable); - - *ppObj = &object->filter.IBaseFilter_iface; + object->IMediaStreamFilter_iface.lpVtbl = &MediaStreamFilter_Vtbl; + object->refcount = 1; + InitializeCriticalSection(&object->cs); + object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MediaStreamFilter.cs"); + TRACE("Created media stream filter %p.\n", object); + *out = &object->IMediaStreamFilter_iface; return S_OK; }