From cdd40604693e81334de167b52562782e53a820c3 Mon Sep 17 00:00:00 2001 From: Damjan Jovanovic Date: Thu, 28 May 2015 19:04:29 +0200 Subject: [PATCH] qcap: Implement a stubbed SmartTee filter. --- dlls/qcap/Makefile.in | 1 + dlls/qcap/qcap_main.c | 2 +- dlls/qcap/smartteefilter.c | 497 +++++++++++++++++++++++++++++++ dlls/qcap/tests/smartteefilter.c | 26 +- 4 files changed, 512 insertions(+), 14 deletions(-) create mode 100644 dlls/qcap/smartteefilter.c diff --git a/dlls/qcap/Makefile.in b/dlls/qcap/Makefile.in index 1c3243d807e..aa778f4443a 100644 --- a/dlls/qcap/Makefile.in +++ b/dlls/qcap/Makefile.in @@ -8,6 +8,7 @@ C_SRCS = \ capturegraph.c \ enummedia.c \ qcap_main.c \ + smartteefilter.c \ v4l.c \ vfwcapture.c \ yuv.c diff --git a/dlls/qcap/qcap_main.c b/dlls/qcap/qcap_main.c index ddacd62beae..78b84844da6 100644 --- a/dlls/qcap/qcap_main.c +++ b/dlls/qcap/qcap_main.c @@ -132,7 +132,7 @@ FactoryTemplate const g_Templates[] = { },{ wSmartTeeFilter, &CLSID_SmartTee, - NULL, /* FIXME: Implement QCAP_createSmartTeeFilter */ + QCAP_createSmartTeeFilter, NULL },{ wAudioInMixerProp, diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c new file mode 100644 index 00000000000..bf68398f0fd --- /dev/null +++ b/dlls/qcap/smartteefilter.c @@ -0,0 +1,497 @@ +/* + * Implementation of the SmartTee filter + * + * Copyright 2015 Damjan Jovanovic + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "wtypes.h" +#include "wingdi.h" +#include "winuser.h" +#include "dshow.h" + +#include "qcap_main.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(qcap); + +typedef struct { + IUnknown IUnknown_iface; + IUnknown *outerUnknown; + BaseFilter filter; + BaseInputPin *input; + BaseOutputPin *capture; + BaseOutputPin *preview; +} SmartTeeFilter; + +static inline SmartTeeFilter *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, SmartTeeFilter, IUnknown_iface); +} + +static inline SmartTeeFilter *impl_from_BaseFilter(BaseFilter *filter) +{ + return CONTAINING_RECORD(filter, SmartTeeFilter, filter); +} + +static inline SmartTeeFilter *impl_from_IBaseFilter(IBaseFilter *iface) +{ + BaseFilter *filter = CONTAINING_RECORD(iface, BaseFilter, IBaseFilter_iface); + return impl_from_BaseFilter(filter); +} + +static inline SmartTeeFilter *impl_from_BasePin(BasePin *pin) +{ + return impl_from_IBaseFilter(pin->pinInfo.pFilter); +} + +static inline SmartTeeFilter *impl_from_IPin(IPin *iface) +{ + BasePin *bp = CONTAINING_RECORD(iface, BasePin, IPin_iface); + return impl_from_IBaseFilter(bp->pinInfo.pFilter); +} + +static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + SmartTeeFilter *This = impl_from_IUnknown(iface); + if (IsEqualIID(riid, &IID_IUnknown)) { + TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv); + *ppv = &This->IUnknown_iface; + } else if (IsEqualIID(riid, &IID_IPersist)) { + TRACE("(%p)->(IID_IPersist, %p)\n", This, ppv); + *ppv = &This->filter.IBaseFilter_iface; + } else if (IsEqualIID(riid, &IID_IMediaFilter)) { + TRACE("(%p)->(IID_IMediaFilter, %p)\n", This, ppv); + *ppv = &This->filter.IBaseFilter_iface; + } else if (IsEqualIID(riid, &IID_IBaseFilter)) { + TRACE("(%p)->(IID_IBaseFilter, %p)\n", This, ppv); + *ppv = &This->filter.IBaseFilter_iface; + } else { + FIXME("(%p): no interface for %s\n", This, debugstr_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI Unknown_AddRef(IUnknown *iface) +{ + SmartTeeFilter *This = impl_from_IUnknown(iface); + return BaseFilterImpl_AddRef(&This->filter.IBaseFilter_iface); +} + +static ULONG WINAPI Unknown_Release(IUnknown *iface) +{ + SmartTeeFilter *This = impl_from_IUnknown(iface); + ULONG ref = BaseFilterImpl_Release(&This->filter.IBaseFilter_iface); + + TRACE("(%p)->() ref=%d\n", This, ref); + + if (!ref) { + if(This->input) + BaseInputPinImpl_Release(&This->input->pin.IPin_iface); + if(This->capture) + BaseOutputPinImpl_Release(&This->capture->pin.IPin_iface); + if(This->preview) + BaseOutputPinImpl_Release(&This->preview->pin.IPin_iface); + CoTaskMemFree(This); + } + return ref; +} + +static const IUnknownVtbl UnknownVtbl = { + Unknown_QueryInterface, + Unknown_AddRef, + Unknown_Release +}; + +static HRESULT WINAPI SmartTeeFilter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv) +{ + SmartTeeFilter *This = impl_from_IBaseFilter(iface); + return IUnknown_QueryInterface(This->outerUnknown, riid, ppv); +} + +static ULONG WINAPI SmartTeeFilter_AddRef(IBaseFilter *iface) +{ + SmartTeeFilter *This = impl_from_IBaseFilter(iface); + return IUnknown_AddRef(This->outerUnknown); +} + +static ULONG WINAPI SmartTeeFilter_Release(IBaseFilter *iface) +{ + SmartTeeFilter *This = impl_from_IBaseFilter(iface); + return IUnknown_Release(This->outerUnknown); +} + +static HRESULT WINAPI SmartTeeFilter_Stop(IBaseFilter *iface) +{ + SmartTeeFilter *This = impl_from_IBaseFilter(iface); + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI SmartTeeFilter_Pause(IBaseFilter *iface) +{ + SmartTeeFilter *This = impl_from_IBaseFilter(iface); + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI SmartTeeFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart) +{ + FIXME("(%p, %x%08x): stub\n", iface, (ULONG)(tStart >> 32), (ULONG)tStart); + return E_NOTIMPL; +} + +static HRESULT WINAPI SmartTeeFilter_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin) +{ + SmartTeeFilter *This = impl_from_IBaseFilter(iface); + FIXME("(%p)->(%s, %p): stub\n", This, debugstr_w(Id), ppPin); + return VFW_E_NOT_FOUND; +} + +static const IBaseFilterVtbl SmartTeeFilterVtbl = { + SmartTeeFilter_QueryInterface, + SmartTeeFilter_AddRef, + SmartTeeFilter_Release, + BaseFilterImpl_GetClassID, + SmartTeeFilter_Stop, + SmartTeeFilter_Pause, + SmartTeeFilter_Run, + BaseFilterImpl_GetState, + BaseFilterImpl_SetSyncSource, + BaseFilterImpl_GetSyncSource, + BaseFilterImpl_EnumPins, + SmartTeeFilter_FindPin, + BaseFilterImpl_QueryFilterInfo, + BaseFilterImpl_JoinFilterGraph, + BaseFilterImpl_QueryVendorInfo +}; + +static IPin* WINAPI SmartTeeFilter_GetPin(BaseFilter *iface, int pos) +{ + SmartTeeFilter *This = impl_from_BaseFilter(iface); + IPin *ret; + + TRACE("(%p)->(%d)\n", This, pos); + + switch(pos) { + case 0: + ret = &This->input->pin.IPin_iface; + break; + case 1: + ret = &This->capture->pin.IPin_iface; + break; + case 2: + ret = &This->preview->pin.IPin_iface; + break; + default: + TRACE("No pin %d\n", pos); + return NULL; + } + + IPin_AddRef(ret); + return ret; +} + +static LONG WINAPI SmartTeeFilter_GetPinCount(BaseFilter *iface) +{ + return 3; +} +static const BaseFilterFuncTable SmartTeeFilterFuncs = { + SmartTeeFilter_GetPin, + SmartTeeFilter_GetPinCount +}; + +static ULONG WINAPI SmartTeeFilterInput_AddRef(IPin *iface) +{ + SmartTeeFilter *This = impl_from_IPin(iface); + return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface); +} + +static ULONG WINAPI SmartTeeFilterInput_Release(IPin *iface) +{ + SmartTeeFilter *This = impl_from_IPin(iface); + return IBaseFilter_Release(&This->filter.IBaseFilter_iface); +} + + +static const IPinVtbl SmartTeeFilterInputVtbl = { + BaseInputPinImpl_QueryInterface, + SmartTeeFilterInput_AddRef, + SmartTeeFilterInput_Release, + BaseInputPinImpl_Connect, + BaseInputPinImpl_ReceiveConnection, + BasePinImpl_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + BasePinImpl_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + BaseInputPinImpl_EndOfStream, + BaseInputPinImpl_BeginFlush, + BaseInputPinImpl_EndFlush, + BaseInputPinImpl_NewSegment +}; + +static HRESULT WINAPI SmartTeeFilterInput_CheckMediaType(BasePin *base, const AM_MEDIA_TYPE *pmt) +{ + SmartTeeFilter *This = impl_from_BasePin(base); + FIXME("(%p, AM_MEDIA_TYPE(%p)): stub\n", This, pmt); + dump_AM_MEDIA_TYPE(pmt); + return E_NOTIMPL; +} + +static LONG WINAPI SmartTeeFilterInput_GetMediaTypeVersion(BasePin *base) +{ + return 0; +} + +static HRESULT WINAPI SmartTeeFilterInput_GetMediaType(BasePin *base, int iPosition, AM_MEDIA_TYPE *amt) +{ + SmartTeeFilter *This = impl_from_BasePin(base); + FIXME("(%p)->(%d, %p): stub\n", This, iPosition, amt); + return S_FALSE; +} + +static HRESULT WINAPI SmartTeeFilterInput_Receive(BaseInputPin *base, IMediaSample *pSample) +{ + SmartTeeFilter *This = impl_from_BasePin(&base->pin); + FIXME("(%p)->(%p): stub\n", This, pSample); + return E_NOTIMPL; +} + +static const BaseInputPinFuncTable SmartTeeFilterInputFuncs = { + { + SmartTeeFilterInput_CheckMediaType, + NULL, + SmartTeeFilterInput_GetMediaTypeVersion, + SmartTeeFilterInput_GetMediaType + }, + SmartTeeFilterInput_Receive +}; + +static ULONG WINAPI SmartTeeFilterCapture_AddRef(IPin *iface) +{ + SmartTeeFilter *This = impl_from_IPin(iface); + return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface); +} + +static ULONG WINAPI SmartTeeFilterCapture_Release(IPin *iface) +{ + SmartTeeFilter *This = impl_from_IPin(iface); + return IBaseFilter_Release(&This->filter.IBaseFilter_iface); +} + +static const IPinVtbl SmartTeeFilterCaptureVtbl = { + BaseOutputPinImpl_QueryInterface, + SmartTeeFilterCapture_AddRef, + SmartTeeFilterCapture_Release, + BaseOutputPinImpl_Connect, + BaseOutputPinImpl_ReceiveConnection, + BaseOutputPinImpl_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + BasePinImpl_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + BaseOutputPinImpl_EndOfStream, + BaseOutputPinImpl_BeginFlush, + BaseOutputPinImpl_EndFlush, + BasePinImpl_NewSegment +}; + +static LONG WINAPI SmartTeeFilterCapture_GetMediaTypeVersion(BasePin *base) +{ + SmartTeeFilter *This = impl_from_BasePin(base); + TRACE("(%p)\n", This); + return 0; +} + +static HRESULT WINAPI SmartTeeFilterCapture_GetMediaType(BasePin *base, int iPosition, AM_MEDIA_TYPE *amt) +{ + SmartTeeFilter *This = impl_from_BasePin(base); + FIXME("(%p, %d, %p): stub\n", This, iPosition, amt); + return E_NOTIMPL; +} + +static HRESULT WINAPI SmartTeeFilterCapture_DecideBufferSize(BaseOutputPin *base, IMemAllocator *alloc, + ALLOCATOR_PROPERTIES *ppropInputRequest) +{ + SmartTeeFilter *This = impl_from_BasePin(&base->pin); + FIXME("(%p, %p, %p): stub\n", This, alloc, ppropInputRequest); + return E_NOTIMPL; +} + +static HRESULT WINAPI SmartTeeFilterCapture_BreakConnect(BaseOutputPin *base) +{ + SmartTeeFilter *This = impl_from_BasePin(&base->pin); + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static const BaseOutputPinFuncTable SmartTeeFilterCaptureFuncs = { + { + NULL, + BaseOutputPinImpl_AttemptConnection, + SmartTeeFilterCapture_GetMediaTypeVersion, + SmartTeeFilterCapture_GetMediaType + }, + SmartTeeFilterCapture_DecideBufferSize, + BaseOutputPinImpl_DecideAllocator, + SmartTeeFilterCapture_BreakConnect +}; + +static ULONG WINAPI SmartTeeFilterPreview_AddRef(IPin *iface) +{ + SmartTeeFilter *This = impl_from_IPin(iface); + return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface); +} + +static ULONG WINAPI SmartTeeFilterPreview_Release(IPin *iface) +{ + SmartTeeFilter *This = impl_from_IPin(iface); + return IBaseFilter_Release(&This->filter.IBaseFilter_iface); +} + +static const IPinVtbl SmartTeeFilterPreviewVtbl = { + BaseOutputPinImpl_QueryInterface, + SmartTeeFilterPreview_AddRef, + SmartTeeFilterPreview_Release, + BaseOutputPinImpl_Connect, + BaseOutputPinImpl_ReceiveConnection, + BaseOutputPinImpl_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + BasePinImpl_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + BaseOutputPinImpl_EndOfStream, + BaseOutputPinImpl_BeginFlush, + BaseOutputPinImpl_EndFlush, + BasePinImpl_NewSegment +}; + +static LONG WINAPI SmartTeeFilterPreview_GetMediaTypeVersion(BasePin *base) +{ + SmartTeeFilter *This = impl_from_BasePin(base); + TRACE("(%p)\n", This); + return 0; +} + +static HRESULT WINAPI SmartTeeFilterPreview_GetMediaType(BasePin *base, int iPosition, AM_MEDIA_TYPE *amt) +{ + SmartTeeFilter *This = impl_from_BasePin(base); + FIXME("(%p, %d, %p): stub\n", This, iPosition, amt); + return E_NOTIMPL; +} + +static HRESULT WINAPI SmartTeeFilterPreview_DecideBufferSize(BaseOutputPin *base, IMemAllocator *alloc, ALLOCATOR_PROPERTIES *ppropInputRequest) +{ + SmartTeeFilter *This = impl_from_BasePin(&base->pin); + FIXME("(%p, %p, %p): stub\n", This, alloc, ppropInputRequest); + return E_NOTIMPL; +} + +static HRESULT WINAPI SmartTeeFilterPreview_BreakConnect(BaseOutputPin *base) +{ + SmartTeeFilter *This = impl_from_BasePin(&base->pin); + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static const BaseOutputPinFuncTable SmartTeeFilterPreviewFuncs = { + { + NULL, + BaseOutputPinImpl_AttemptConnection, + SmartTeeFilterPreview_GetMediaTypeVersion, + SmartTeeFilterPreview_GetMediaType + }, + SmartTeeFilterPreview_DecideBufferSize, + BaseOutputPinImpl_DecideAllocator, + SmartTeeFilterPreview_BreakConnect +}; +IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr) +{ + PIN_INFO inputPinInfo = {NULL, PINDIR_INPUT, {'I','n','p','u','t',0}}; + PIN_INFO capturePinInfo = {NULL, PINDIR_OUTPUT, {'C','a','p','t','u','r','e',0}}; + PIN_INFO previewPinInfo = {NULL, PINDIR_OUTPUT, {'P','r','e','v','i','e','w',0}}; + HRESULT hr; + SmartTeeFilter *This = NULL; + + TRACE("(%p, %p)\n", outer, phr); + + This = CoTaskMemAlloc(sizeof(*This)); + if (This == NULL) { + hr = E_OUTOFMEMORY; + goto end; + } + memset(This, 0, sizeof(*This)); + This->IUnknown_iface.lpVtbl = &UnknownVtbl; + if (outer) + This->outerUnknown = outer; + else + This->outerUnknown = &This->IUnknown_iface; + + BaseFilter_Init(&This->filter, &SmartTeeFilterVtbl, &CLSID_SmartTee, + (DWORD_PTR)(__FILE__ ": SmartTeeFilter.csFilter"), &SmartTeeFilterFuncs); + + inputPinInfo.pFilter = &This->filter.IBaseFilter_iface; + hr = BaseInputPin_Construct(&SmartTeeFilterInputVtbl, sizeof(BaseInputPin), &inputPinInfo, + &SmartTeeFilterInputFuncs, &This->filter.csFilter, NULL, (IPin**)&This->input); + if (FAILED(hr)) + goto end; + + capturePinInfo.pFilter = &This->filter.IBaseFilter_iface; + hr = BaseOutputPin_Construct(&SmartTeeFilterCaptureVtbl, sizeof(BaseOutputPin), &capturePinInfo, + &SmartTeeFilterCaptureFuncs, &This->filter.csFilter, (IPin**)&This->capture); + if (FAILED(hr)) + goto end; + + previewPinInfo.pFilter = &This->filter.IBaseFilter_iface; + hr = BaseOutputPin_Construct(&SmartTeeFilterPreviewVtbl, sizeof(BaseOutputPin), &previewPinInfo, + &SmartTeeFilterPreviewFuncs, &This->filter.csFilter, (IPin**)&This->preview); + +end: + *phr = hr; + if (SUCCEEDED(hr)) { + if (outer) + return &This->IUnknown_iface; + else + return (IUnknown*)&This->filter.IBaseFilter_iface; + } else { + if (This) + IBaseFilter_Release(&This->filter.IBaseFilter_iface); + return NULL; + } +} diff --git a/dlls/qcap/tests/smartteefilter.c b/dlls/qcap/tests/smartteefilter.c index 83bcff93482..78378e2a468 100644 --- a/dlls/qcap/tests/smartteefilter.c +++ b/dlls/qcap/tests/smartteefilter.c @@ -1010,7 +1010,7 @@ static HRESULT WINAPI SourcePin_Connect(IPin *iface, IPin *pReceivePin, const AM if (pmt && !IsEqualGUID(&pmt->formattype, &GUID_NULL)) return VFW_E_TYPE_NOT_ACCEPTED; hr = IPin_ReceiveConnection(pReceivePin, &This->IPin_iface, &This->mediaType); - ok(SUCCEEDED(hr), "SmartTeeFilter's Input pin's IPin_ReceiveConnection() failed with 0x%08x\n", hr); + todo_wine ok(SUCCEEDED(hr), "SmartTeeFilter's Input pin's IPin_ReceiveConnection() failed with 0x%08x\n", hr); if (SUCCEEDED(hr)) { EnterCriticalSection(&This->cs); hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (void**)&This->memInputPin); @@ -1307,9 +1307,9 @@ static void test_smart_tee_filter_in_graph(IBaseFilter *smartTeeFilter, IPin *in } hr = IGraphBuilder_Connect(graphBuilder, capturePin, &captureSinkFilter->IPin_iface); - ok(hr == VFW_E_NOT_CONNECTED, "connecting Capture pin without first connecting Input pin returned 0x%08x\n", hr); + todo_wine ok(hr == VFW_E_NOT_CONNECTED, "connecting Capture pin without first connecting Input pin returned 0x%08x\n", hr); hr = IGraphBuilder_Connect(graphBuilder, previewPin, &previewSinkFilter->IPin_iface); - ok(hr == VFW_E_NOT_CONNECTED, "connecting Preview pin without first connecting Input pin returned 0x%08x\n", hr); + todo_wine ok(hr == VFW_E_NOT_CONNECTED, "connecting Preview pin without first connecting Input pin returned 0x%08x\n", hr); sourceFilter = create_SourceFilter(); if (sourceFilter == NULL) { @@ -1322,7 +1322,7 @@ static void test_smart_tee_filter_in_graph(IBaseFilter *smartTeeFilter, IPin *in goto end; hr = IGraphBuilder_Connect(graphBuilder, &sourceFilter->IPin_iface, inputPin); - ok(SUCCEEDED(hr), "couldn't connect source filter to Input pin, hr=0x%08x\n", hr); + todo_wine ok(SUCCEEDED(hr), "couldn't connect source filter to Input pin, hr=0x%08x\n", hr); if (FAILED(hr)) goto end; hr = IGraphBuilder_Connect(graphBuilder, capturePin, &captureSinkFilter->IPin_iface); @@ -1384,7 +1384,7 @@ static void test_smart_tee_filter(void) hr = CoCreateInstance(&CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void**)&smartTeeFilter); - todo_wine ok(SUCCEEDED(hr), "couldn't create smart tee filter, hr=0x%08x\n", hr); + ok(SUCCEEDED(hr), "couldn't create smart tee filter, hr=0x%08x\n", hr); if (FAILED(hr)) goto end; @@ -1467,23 +1467,23 @@ static void test_smart_tee_filter(void) ok(!has_interface((IUnknown*)inputPin, &IID_IAMStreamConfig), "IAMStreamConfig shouldn't exist on the input pin\n"); ok(!has_interface((IUnknown*)inputPin, &IID_IAMStreamControl), "IAMStreamControl shouldn't exist on the input pin\n"); ok(!has_interface((IUnknown*)inputPin, &IID_IPropertyBag), "IPropertyBag shouldn't exist on the input pin\n"); - ok(has_interface((IUnknown*)inputPin, &IID_IQualityControl), "IQualityControl should exist on the input pin\n"); + todo_wine ok(has_interface((IUnknown*)inputPin, &IID_IQualityControl), "IQualityControl should exist on the input pin\n"); ok(has_interface((IUnknown*)capturePin, &IID_IUnknown), "IUnknown should exist on the capture pin\n"); ok(!has_interface((IUnknown*)capturePin, &IID_IAsyncReader), "IAsyncReader shouldn't exist on the capture pin\n"); ok(!has_interface((IUnknown*)capturePin, &IID_IKsPropertySet), "IKsPropertySet shouldn't exist on the capture pin\n"); ok(!has_interface((IUnknown*)capturePin, &IID_IAMStreamConfig), "IAMStreamConfig shouldn't exist on the capture pin\n"); - ok(has_interface((IUnknown*)capturePin, &IID_IAMStreamControl), "IAMStreamControl should exist on the capture pin\n"); + todo_wine ok(has_interface((IUnknown*)capturePin, &IID_IAMStreamControl), "IAMStreamControl should exist on the capture pin\n"); ok(!has_interface((IUnknown*)capturePin, &IID_IPropertyBag), "IPropertyBag shouldn't exist on the capture pin\n"); - ok(has_interface((IUnknown*)capturePin, &IID_IQualityControl), "IQualityControl should exist on the capture pin\n"); + todo_wine ok(has_interface((IUnknown*)capturePin, &IID_IQualityControl), "IQualityControl should exist on the capture pin\n"); ok(has_interface((IUnknown*)previewPin, &IID_IUnknown), "IUnknown should exist on the preview pin\n"); ok(!has_interface((IUnknown*)previewPin, &IID_IAsyncReader), "IAsyncReader shouldn't exist on the preview pin\n"); ok(!has_interface((IUnknown*)previewPin, &IID_IKsPropertySet), "IKsPropertySet shouldn't exist on the preview pin\n"); ok(!has_interface((IUnknown*)previewPin, &IID_IAMStreamConfig), "IAMStreamConfig shouldn't exist on the preview pin\n"); - ok(has_interface((IUnknown*)capturePin, &IID_IAMStreamControl), "IAMStreamControl should exist on the preview pin\n"); + todo_wine ok(has_interface((IUnknown*)capturePin, &IID_IAMStreamControl), "IAMStreamControl should exist on the preview pin\n"); ok(!has_interface((IUnknown*)previewPin, &IID_IPropertyBag), "IPropertyBag shouldn't exist on the preview pin\n"); - ok(has_interface((IUnknown*)previewPin, &IID_IQualityControl), "IQualityControl should exist on the preview pin\n"); + todo_wine ok(has_interface((IUnknown*)previewPin, &IID_IQualityControl), "IQualityControl should exist on the preview pin\n"); hr = IPin_QueryInterface(inputPin, &IID_IMemInputPin, (void**)&memInputPin); ok(SUCCEEDED(hr), "couldn't get mem input pin, hr=0x%08x\n", hr); @@ -1502,9 +1502,9 @@ static void test_smart_tee_filter(void) IEnumMediaTypes_Release(enumMediaTypes); enumMediaTypes = NULL; hr = IPin_EnumMediaTypes(capturePin, &enumMediaTypes); - ok(hr == VFW_E_NOT_CONNECTED, "IPin_EnumMediaTypes() failed, hr=0x%08x\n", hr); + todo_wine ok(hr == VFW_E_NOT_CONNECTED, "IPin_EnumMediaTypes() failed, hr=0x%08x\n", hr); hr = IPin_EnumMediaTypes(previewPin, &enumMediaTypes); - ok(hr == VFW_E_NOT_CONNECTED, "IPin_EnumMediaTypes() failed, hr=0x%08x\n", hr); + todo_wine ok(hr == VFW_E_NOT_CONNECTED, "IPin_EnumMediaTypes() failed, hr=0x%08x\n", hr); hr = IPin_QueryInternalConnections(inputPin, NULL, &nPin); ok(hr == E_NOTIMPL, "IPin_QueryInternalConnections() returned hr=0x%08x\n", hr); @@ -1539,7 +1539,7 @@ static void test_smart_tee_filter_aggregation(void) IUnknown *unknown = NULL; HRESULT hr = CoCreateInstance(&CLSID_SmartTee, (IUnknown*)&sourceFilter->IBaseFilter_iface, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&unknown); - todo_wine ok(SUCCEEDED(hr), "SmartTee filter doesn't support aggregation, hr=0x%08x\n", hr); + ok(SUCCEEDED(hr), "SmartTee filter doesn't support aggregation, hr=0x%08x\n", hr); if (unknown) IUnknown_Release(unknown); IBaseFilter_Release(&sourceFilter->IBaseFilter_iface);