qcap/vfwcapture: Use strmbase filter aggregation support.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c52bc25dd8
commit
3bce180dbd
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue