From 3bce180dbdf2b6aa579eede1b467aabc89c4eacb Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 4 Jun 2019 17:54:24 -0500 Subject: [PATCH] qcap/vfwcapture: Use strmbase filter aggregation support. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/qcap/vfwcapture.c | 197 ++++++++++++----------------------------- 1 file changed, 58 insertions(+), 139 deletions(-) diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c index 7c2590025a1..d9d937a4a50 100644 --- a/dlls/qcap/vfwcapture.c +++ b/dlls/qcap/vfwcapture.c @@ -54,23 +54,16 @@ static HRESULT VfwPin_Construct( IBaseFilter *, LPCRITICAL_SECTION, IPin ** ); typedef struct VfwCapture { - IUnknown IUnknown_inner; BaseFilter filter; IAMStreamConfig IAMStreamConfig_iface; IAMVideoProcAmp IAMVideoProcAmp_iface; IPersistPropertyBag IPersistPropertyBag_iface; - IUnknown *outer_unk; BOOL init; Capture *driver_info; IPin * pOutputPin; } VfwCapture; -static inline VfwCapture *impl_from_IUnknown(IUnknown *iface) -{ - return CONTAINING_RECORD(iface, VfwCapture, IUnknown_inner); -} - static inline VfwCapture *impl_from_BaseFilter(BaseFilter *iface) { return CONTAINING_RECORD(iface, VfwCapture, filter); @@ -104,94 +97,6 @@ typedef struct VfwPinImpl VfwCapture *parent; } VfwPinImpl; - -/* VfwCapture inner IUnknown */ -static HRESULT WINAPI unknown_inner_QueryInterface(IUnknown *iface, REFIID riid, void **ret_iface) -{ - VfwCapture *This = impl_from_IUnknown(iface); - - TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ret_iface); - - *ret_iface = NULL; - - if (IsEqualIID(riid, &IID_IUnknown)) - *ret_iface = &This->IUnknown_inner; - else if (IsEqualIID(riid, &IID_IPersist) || IsEqualIID(riid, &IID_IMediaFilter) || - IsEqualIID(riid, &IID_IBaseFilter)) - *ret_iface = &This->filter.IBaseFilter_iface; - else if (IsEqualIID(riid, &IID_IPersistPropertyBag)) - *ret_iface = &This->IPersistPropertyBag_iface; - else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags)) - FIXME("IAMFilterMiscFlags not supported yet!\n"); - else if (IsEqualIID(riid, &IID_ISpecifyPropertyPages)) - FIXME("ISpecifyPropertyPages not supported yet!\n"); - else if (IsEqualIID(riid, &IID_IAMVfwCaptureDialogs)) - FIXME("IAMVfwCaptureDialogs not supported yet!\n"); - else if (IsEqualIID(riid, &IID_IAMStreamConfig)) - *ret_iface = &This->IAMStreamConfig_iface; - else if (IsEqualIID(riid, &IID_IAMVideoProcAmp)) - *ret_iface = &This->IAMVideoProcAmp_iface; - else - WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ret_iface); - - if (!*ret_iface) - return E_NOINTERFACE; - - IUnknown_AddRef((IUnknown*)*ret_iface); - return S_OK; -} - -static ULONG WINAPI unknown_inner_AddRef(IUnknown *iface) -{ - VfwCapture *This = impl_from_IUnknown(iface); - ULONG ref = BaseFilterImpl_AddRef(&This->filter.IBaseFilter_iface); - - TRACE("(%p) ref=%d\n", This, ref); - - return ref; -} - -static ULONG WINAPI unknown_inner_Release(IUnknown *iface) -{ - VfwCapture *This = impl_from_IUnknown(iface); - ULONG ref = InterlockedDecrement(&This->filter.refcount); - - TRACE("(%p) ref=%d\n", This, ref); - - if (!ref) - { - IPin *conn = NULL; - - TRACE("destroying everything\n"); - if (This->init) - { - if (This->filter.state != State_Stopped) - qcap_driver_stop(This->driver_info, &This->filter.state); - qcap_driver_destroy(This->driver_info); - } - IPin_ConnectedTo(This->pOutputPin, &conn); - if (conn) - { - IPin_Disconnect(conn); - IPin_Disconnect(This->pOutputPin); - IPin_Release(conn); - } - IPin_Release(This->pOutputPin); - strmbase_filter_cleanup(&This->filter); - CoTaskMemFree(This); - ObjectRefCount(FALSE); - } - - return ref; -} - -static const IUnknownVtbl unknown_inner_vtbl = -{ - unknown_inner_QueryInterface, - unknown_inner_AddRef, - unknown_inner_Release, -}; - static IPin *vfw_capture_get_pin(BaseFilter *iface, unsigned int index) { VfwCapture *This = impl_from_BaseFilter(iface); @@ -203,36 +108,71 @@ static IPin *vfw_capture_get_pin(BaseFilter *iface, unsigned int index) return This->pOutputPin; } +static void vfw_capture_destroy(BaseFilter *iface) +{ + VfwCapture *filter = impl_from_BaseFilter(iface); + IPin *peer = NULL; + + if (filter->init) + { + if (filter->filter.state != State_Stopped) + qcap_driver_stop(filter->driver_info, &filter->filter.state); + qcap_driver_destroy(filter->driver_info); + } + IPin_ConnectedTo(filter->pOutputPin, &peer); + if (peer) + { + IPin_Disconnect(peer); + IPin_Disconnect(filter->pOutputPin); + IPin_Release(peer); + } + IPin_Release(filter->pOutputPin); + strmbase_filter_cleanup(&filter->filter); + CoTaskMemFree(filter); + ObjectRefCount(FALSE); +} + +static HRESULT vfw_capture_query_interface(BaseFilter *iface, REFIID iid, void **out) +{ + VfwCapture *filter = impl_from_BaseFilter(iface); + + if (IsEqualGUID(iid, &IID_IPersistPropertyBag)) + *out = &filter->IPersistPropertyBag_iface; + else if (IsEqualGUID(iid, &IID_IAMStreamConfig)) + *out = &filter->IAMStreamConfig_iface; + else if (IsEqualGUID(iid, &IID_IAMVideoProcAmp)) + *out = &filter->IAMVideoProcAmp_iface; + else + return E_NOINTERFACE; + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + static const BaseFilterFuncTable BaseFuncTable = { .filter_get_pin = vfw_capture_get_pin, + .filter_destroy = vfw_capture_destroy, + .filter_query_interface = vfw_capture_query_interface, }; -IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr) +IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *outer, HRESULT *phr) { VfwCapture *pVfwCapture; HRESULT hr; - TRACE("%p - %p\n", pUnkOuter, phr); - *phr = E_OUTOFMEMORY; pVfwCapture = CoTaskMemAlloc( sizeof(VfwCapture) ); if (!pVfwCapture) return NULL; - strmbase_filter_init(&pVfwCapture->filter, &VfwCapture_Vtbl, NULL, &CLSID_VfwCapture, + strmbase_filter_init(&pVfwCapture->filter, &VfwCapture_Vtbl, outer, &CLSID_VfwCapture, (DWORD_PTR)(__FILE__ ": VfwCapture.csFilter"), &BaseFuncTable); - pVfwCapture->IUnknown_inner.lpVtbl = &unknown_inner_vtbl; pVfwCapture->IAMStreamConfig_iface.lpVtbl = &IAMStreamConfig_VTable; pVfwCapture->IAMVideoProcAmp_iface.lpVtbl = &IAMVideoProcAmp_VTable; pVfwCapture->IPersistPropertyBag_iface.lpVtbl = &IPersistPropertyBag_VTable; pVfwCapture->init = FALSE; - if (pUnkOuter) - pVfwCapture->outer_unk = pUnkOuter; - else - pVfwCapture->outer_unk = &pVfwCapture->IUnknown_inner; - hr = VfwPin_Construct(&pVfwCapture->filter.IBaseFilter_iface, &pVfwCapture->filter.csFilter, &pVfwCapture->pOutputPin); if (FAILED(hr)) @@ -244,28 +184,7 @@ IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr) ObjectRefCount(TRUE); *phr = S_OK; - return &pVfwCapture->IUnknown_inner; -} - -static HRESULT WINAPI VfwCapture_QueryInterface(IBaseFilter *iface, REFIID riid, void **ret_iface) -{ - VfwCapture *This = impl_from_IBaseFilter(iface); - - return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface); -} - -static ULONG WINAPI VfwCapture_AddRef(IBaseFilter *iface) -{ - VfwCapture *This = impl_from_IBaseFilter(iface); - - return IUnknown_AddRef(This->outer_unk); -} - -static ULONG WINAPI VfwCapture_Release(IBaseFilter * iface) -{ - VfwCapture *This = impl_from_IBaseFilter(iface); - - return IUnknown_Release(This->outer_unk); + return &pVfwCapture->filter.IUnknown_inner; } /** IMediaFilter methods **/ @@ -295,9 +214,9 @@ static HRESULT WINAPI VfwCapture_Run(IBaseFilter * iface, REFERENCE_TIME tStart) static const IBaseFilterVtbl VfwCapture_Vtbl = { - VfwCapture_QueryInterface, - VfwCapture_AddRef, - VfwCapture_Release, + BaseFilterImpl_QueryInterface, + BaseFilterImpl_AddRef, + BaseFilterImpl_Release, BaseFilterImpl_GetClassID, VfwCapture_Stop, VfwCapture_Pause, @@ -318,21 +237,21 @@ static HRESULT WINAPI AMStreamConfig_QueryInterface(IAMStreamConfig *iface, REFI { VfwCapture *This = impl_from_IAMStreamConfig(iface); - return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface); + return IUnknown_QueryInterface(This->filter.outer_unk, riid, ret_iface); } static ULONG WINAPI AMStreamConfig_AddRef( IAMStreamConfig * iface ) { VfwCapture *This = impl_from_IAMStreamConfig(iface); - return IUnknown_AddRef(This->outer_unk); + return IUnknown_AddRef(This->filter.outer_unk); } static ULONG WINAPI AMStreamConfig_Release( IAMStreamConfig * iface ) { VfwCapture *This = impl_from_IAMStreamConfig(iface); - return IUnknown_Release(This->outer_unk); + return IUnknown_Release(This->filter.outer_unk); } static HRESULT WINAPI @@ -420,21 +339,21 @@ static HRESULT WINAPI AMVideoProcAmp_QueryInterface(IAMVideoProcAmp *iface, REFI { VfwCapture *This = impl_from_IAMVideoProcAmp(iface); - return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface); + return IUnknown_QueryInterface(This->filter.outer_unk, riid, ret_iface); } static ULONG WINAPI AMVideoProcAmp_AddRef(IAMVideoProcAmp * iface) { VfwCapture *This = impl_from_IAMVideoProcAmp(iface); - return IUnknown_AddRef(This->outer_unk); + return IUnknown_AddRef(This->filter.outer_unk); } static ULONG WINAPI AMVideoProcAmp_Release(IAMVideoProcAmp * iface) { VfwCapture *This = impl_from_IAMVideoProcAmp(iface); - return IUnknown_Release(This->outer_unk); + return IUnknown_Release(This->filter.outer_unk); } static HRESULT WINAPI @@ -479,21 +398,21 @@ static HRESULT WINAPI PPB_QueryInterface(IPersistPropertyBag *iface, REFIID riid { VfwCapture *This = impl_from_IPersistPropertyBag(iface); - return IUnknown_QueryInterface(This->outer_unk, riid, ret_iface); + return IUnknown_QueryInterface(This->filter.outer_unk, riid, ret_iface); } static ULONG WINAPI PPB_AddRef(IPersistPropertyBag * iface) { VfwCapture *This = impl_from_IPersistPropertyBag(iface); - return IUnknown_AddRef(This->outer_unk); + return IUnknown_AddRef(This->filter.outer_unk); } static ULONG WINAPI PPB_Release(IPersistPropertyBag * iface) { VfwCapture *This = impl_from_IPersistPropertyBag(iface); - return IUnknown_Release(This->outer_unk); + return IUnknown_Release(This->filter.outer_unk); } static HRESULT WINAPI