qcap/tests: Add more tests for ICaptureGraphBuilder2::RenderStream().
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9d5a829034
commit
18462a2f16
|
@ -39,6 +39,7 @@ struct testsource
|
|||
{
|
||||
struct strmbase_source pin;
|
||||
IKsPropertySet IKsPropertySet_iface;
|
||||
GUID category;
|
||||
BOOL has_iface;
|
||||
};
|
||||
|
||||
|
@ -54,6 +55,8 @@ struct testfilter
|
|||
struct testsource source1, source2;
|
||||
struct testsink sink1, sink2;
|
||||
BOOL filter_has_iface;
|
||||
GUID source_type;
|
||||
const GUID *sink_type;
|
||||
};
|
||||
|
||||
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
|
||||
|
@ -141,7 +144,9 @@ static HRESULT WINAPI property_set_Set(IKsPropertySet *iface, REFGUID set, DWORD
|
|||
static HRESULT WINAPI property_set_Get(IKsPropertySet *iface, REFGUID set, DWORD id,
|
||||
void *instance_data, DWORD instance_size, void *property_data, DWORD property_size, DWORD *ret_size)
|
||||
{
|
||||
if (winetest_debug > 1) trace("Get()\n");
|
||||
struct testsource *pin = impl_from_IKsPropertySet(iface);
|
||||
|
||||
if (winetest_debug > 1) trace("%s->Get()\n", debugstr_w(pin->pin.pin.name));
|
||||
|
||||
ok(IsEqualGUID(set, &ROPSETID_Pin), "Got set %s.\n", debugstr_guid(set));
|
||||
ok(id == AMPROPERTY_PIN_CATEGORY, "Got id %#x.\n", id);
|
||||
|
@ -149,7 +154,7 @@ static HRESULT WINAPI property_set_Get(IKsPropertySet *iface, REFGUID set, DWORD
|
|||
ok(!instance_size, "Got instance size %u.\n", instance_size);
|
||||
ok(property_size == sizeof(GUID), "Got property size %u.\n", property_size);
|
||||
ok(!!ret_size, "Expected non-NULL return size.\n");
|
||||
memcpy(property_data, &PIN_CATEGORY_CAPTURE, sizeof(GUID));
|
||||
memcpy(property_data, &pin->category, sizeof(GUID));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -196,18 +201,21 @@ static HRESULT testsource_query_accept(struct strmbase_pin *iface, const AM_MEDI
|
|||
|
||||
static HRESULT testsource_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt)
|
||||
{
|
||||
struct testfilter *filter = impl_from_strmbase_filter(iface->filter);
|
||||
|
||||
if (!index)
|
||||
{
|
||||
memset(mt, 0, sizeof(*mt));
|
||||
mt->majortype = testtype;
|
||||
mt->majortype = filter->source_type;
|
||||
return S_OK;
|
||||
}
|
||||
return VFW_S_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface,
|
||||
IMemInputPin *input, IMemAllocator **allocator)
|
||||
static HRESULT WINAPI testsource_DecideBufferSize(struct strmbase_source *iface,
|
||||
IMemAllocator *allocator, ALLOCATOR_PROPERTIES *props)
|
||||
{
|
||||
props->cBuffers = props->cbAlign = props->cbBuffer = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -217,7 +225,8 @@ static const struct strmbase_source_ops testsource_ops =
|
|||
.base.pin_query_accept = testsource_query_accept,
|
||||
.base.pin_get_media_type = testsource_get_media_type,
|
||||
.pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
|
||||
.pfnDecideAllocator = testsource_DecideAllocator,
|
||||
.pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
|
||||
.pfnDecideBufferSize = testsource_DecideBufferSize,
|
||||
};
|
||||
|
||||
static struct testsink *impl_sink_from_strmbase_pin(struct strmbase_pin *iface)
|
||||
|
@ -244,6 +253,10 @@ static HRESULT testsink_query_interface(struct strmbase_pin *iface, REFIID iid,
|
|||
|
||||
static HRESULT testsink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
|
||||
{
|
||||
struct testfilter *filter = impl_from_strmbase_filter(iface->filter);
|
||||
|
||||
if (filter->sink_type && !IsEqualGUID(&mt->majortype, filter->sink_type))
|
||||
return S_FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -466,6 +479,7 @@ static void test_find_interface(void)
|
|||
ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
|
||||
|
||||
filter2.source1.IKsPropertySet_iface.lpVtbl = &property_set_vtbl;
|
||||
filter2.source1.category = PIN_CATEGORY_CAPTURE;
|
||||
hr = ICaptureGraphBuilder2_FindInterface(capture_graph, &PIN_CATEGORY_CAPTURE, NULL,
|
||||
&filter2.filter.IBaseFilter_iface, &testiid, (void **)&unk);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
@ -493,6 +507,8 @@ static void test_find_interface(void)
|
|||
|
||||
/* Test with a media type. */
|
||||
|
||||
filter1.source_type = filter2.source_type = testtype;
|
||||
|
||||
reset_interfaces(&filter1);
|
||||
reset_interfaces(&filter2);
|
||||
reset_interfaces(&filter3);
|
||||
|
@ -623,6 +639,7 @@ static void test_find_pin(void)
|
|||
/* Test categories. */
|
||||
|
||||
filter1.source1.IKsPropertySet_iface.lpVtbl = &property_set_vtbl;
|
||||
filter1.source1.category = PIN_CATEGORY_CAPTURE;
|
||||
|
||||
hr = ICaptureGraphBuilder2_FindPin(capture_graph, (IUnknown *)&filter1.filter.IBaseFilter_iface,
|
||||
PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, NULL, FALSE, 0, &pin);
|
||||
|
@ -644,12 +661,432 @@ static void test_find_pin(void)
|
|||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
}
|
||||
|
||||
static void disconnect_pins(IGraphBuilder *graph, struct testsource *pin)
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = IGraphBuilder_Disconnect(graph, pin->pin.pin.peer);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IGraphBuilder_Disconnect(graph, &pin->pin.pin.IPin_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
static void check_smart_tee_pin_(int line, IPin *pin, const WCHAR *name)
|
||||
{
|
||||
PIN_INFO info;
|
||||
GUID clsid;
|
||||
|
||||
IPin_QueryPinInfo(pin, &info);
|
||||
ok_(__FILE__, line)(!wcscmp(info.achName, name), "Got name %s.\n", debugstr_w(info.achName));
|
||||
IBaseFilter_GetClassID(info.pFilter, &clsid);
|
||||
ok_(__FILE__, line)(IsEqualGUID(&clsid, &CLSID_SmartTee), "Got CLSID %s.\n", debugstr_guid(&clsid));
|
||||
IBaseFilter_Release(info.pFilter);
|
||||
}
|
||||
#define check_smart_tee_pin(pin, name) check_smart_tee_pin_(__LINE__, pin, name)
|
||||
|
||||
static void test_render_stream(void)
|
||||
{
|
||||
static const GUID source_type = {0x1111};
|
||||
static const GUID sink1_type = {0x8888};
|
||||
static const GUID bad_type = {0x4444};
|
||||
|
||||
ICaptureGraphBuilder2 *capture_graph = create_capture_graph();
|
||||
struct testfilter source, transform, sink, identity;
|
||||
IGraphBuilder *graph;
|
||||
HRESULT hr;
|
||||
ULONG ref;
|
||||
|
||||
CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, (void **)&graph);
|
||||
hr = ICaptureGraphBuilder2_SetFiltergraph(capture_graph, graph);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
testfilter_init(&source);
|
||||
testfilter_init(&transform);
|
||||
testfilter_init(&sink);
|
||||
testfilter_init(&identity);
|
||||
IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
|
||||
IGraphBuilder_AddFilter(graph, &transform.filter.IBaseFilter_iface, L"transform");
|
||||
IGraphBuilder_AddFilter(graph, &sink.filter.IBaseFilter_iface, L"sink");
|
||||
|
||||
source.source_type = source_type;
|
||||
transform.sink_type = &source_type;
|
||||
transform.source_type = sink1_type;
|
||||
sink.sink_type = &sink1_type;
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(!source.source2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
todo_wine ok(source.source2.pin.pin.peer == &transform.sink2.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
todo_wine ok(transform.source2.pin.pin.peer == &sink.sink2.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == E_FAIL, "Got hr %#x.\n", hr);
|
||||
|
||||
todo_wine disconnect_pins(graph, &source.source2);
|
||||
todo_wine disconnect_pins(graph, &transform.source2);
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&transform.source2.pin.pin.IPin_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source2.pin.pin.peer == &sink.sink2.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(!source.source2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_FAIL, "Got hr %#x.\n", hr);
|
||||
|
||||
disconnect_pins(graph, &transform.source2);
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &transform.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
todo_wine ok(source.source2.pin.pin.peer == &transform.sink2.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
todo_wine ok(source.source2.pin.pin.peer == &transform.sink2.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
todo_wine ok(transform.source2.pin.pin.peer == &sink.sink2.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
todo_wine disconnect_pins(graph, &source.source2);
|
||||
todo_wine disconnect_pins(graph, &transform.source2);
|
||||
|
||||
/* Test from a source pin. */
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.source1.pin.pin.IPin_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
todo_wine ok(transform.source2.pin.pin.peer == &sink.sink2.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(!source.source2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
todo_wine disconnect_pins(graph, &transform.source2);
|
||||
|
||||
/* Only the first eligible source is tried. */
|
||||
source.source_type = bad_type;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x.\n", hr);
|
||||
source.source_type = source_type;
|
||||
|
||||
disconnect_pins(graph, &transform.source1);
|
||||
disconnect_pins(graph, &source.source1);
|
||||
|
||||
/* Test intermediate filters. */
|
||||
|
||||
IGraphBuilder_AddFilter(graph, &identity.filter.IBaseFilter_iface, L"identity");
|
||||
identity.source_type = source_type;
|
||||
identity.sink_type = &source_type;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface,
|
||||
&identity.filter.IBaseFilter_iface, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &identity.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(identity.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
disconnect_pins(graph, &source.source1);
|
||||
disconnect_pins(graph, &identity.source1);
|
||||
disconnect_pins(graph, &transform.source1);
|
||||
|
||||
identity.sink_type = &bad_type;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface,
|
||||
&identity.filter.IBaseFilter_iface, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == E_FAIL, "Got hr %#x.\n", hr);
|
||||
ok(!source.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!identity.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!transform.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
identity.source_type = sink1_type;
|
||||
identity.sink_type = &sink1_type;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface,
|
||||
&identity.filter.IBaseFilter_iface, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &identity.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(identity.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
disconnect_pins(graph, &source.source1);
|
||||
disconnect_pins(graph, &transform.source1);
|
||||
disconnect_pins(graph, &identity.source1);
|
||||
|
||||
identity.source_type = bad_type;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface,
|
||||
&identity.filter.IBaseFilter_iface, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &identity.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(!identity.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
disconnect_pins(graph, &source.source1);
|
||||
disconnect_pins(graph, &transform.source1);
|
||||
|
||||
/* Test media types. */
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, &bad_type,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(!source.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!source.source2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, &sink1_type,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(!source.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!source.source2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
identity.source_type = sink1_type;
|
||||
identity.sink_type = &sink1_type;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, &sink1_type,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface,
|
||||
&identity.filter.IBaseFilter_iface, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(!source.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!source.source2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, &source_type,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(!source.source2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, NULL, &sink1_type,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
todo_wine ok(transform.source2.pin.pin.peer == &sink.sink2.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(!source.source2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
disconnect_pins(graph, &source.source1);
|
||||
disconnect_pins(graph, &transform.source1);
|
||||
todo_wine disconnect_pins(graph, &transform.source2);
|
||||
|
||||
/* Test categories. */
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CC, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
ok(!source.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!source.source2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
source.source1.IKsPropertySet_iface.lpVtbl = &property_set_vtbl;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CC, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
ok(!source.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!source.source2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
source.source1.category = PIN_CATEGORY_CC;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CC, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(!source.source2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
ok(!sink.sink2.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
disconnect_pins(graph, &transform.source1);
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CC, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(!transform.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
transform.source1.IKsPropertySet_iface.lpVtbl = &property_set_vtbl;
|
||||
transform.source1.category = PIN_CATEGORY_CC;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CC, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
todo_wine ok(!transform.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
todo_wine ok(!sink.sink1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
if (0)
|
||||
{
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CC, NULL,
|
||||
(IUnknown *)&source.source1.pin.pin.IPin_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
disconnect_pins(graph, &source.source1);
|
||||
|
||||
/* Test the CAPTURE and PREVIEW categories. */
|
||||
|
||||
source.source1.IKsPropertySet_iface.lpVtbl = transform.source1.IKsPropertySet_iface.lpVtbl = NULL;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CAPTURE, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_PREVIEW, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
|
||||
source.source1.IKsPropertySet_iface.lpVtbl = &property_set_vtbl;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CAPTURE, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_PREVIEW, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
|
||||
source.source1.category = PIN_CATEGORY_PREVIEW;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CAPTURE, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
ok(!source.source1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
todo_wine ok(!sink.sink1.pin.pin.peer, "Pin should not be connected.\n");
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_PREVIEW, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
todo_wine ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
disconnect_pins(graph, &transform.source1);
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_PREVIEW, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(hr == E_FAIL, "Got hr %#x.\n", hr);
|
||||
todo_wine disconnect_pins(graph, &source.source1);
|
||||
|
||||
source.source1.category = PIN_CATEGORY_CAPTURE;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CAPTURE, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
check_smart_tee_pin(source.source1.pin.pin.peer, L"Input");
|
||||
check_smart_tee_pin(transform.sink1.pin.pin.peer, L"Capture");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
|
||||
if (0)
|
||||
{
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CAPTURE, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_PREVIEW, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == VFW_S_NOPREVIEWPIN, "Got hr %#x.\n", hr);
|
||||
check_smart_tee_pin(source.source1.pin.pin.peer, L"Input");
|
||||
check_smart_tee_pin(transform.sink1.pin.pin.peer, L"Capture");
|
||||
check_smart_tee_pin(transform.sink2.pin.pin.peer, L"Preview");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source2.pin.pin.peer == &sink.sink2.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
|
||||
disconnect_pins(graph, &source.source1);
|
||||
IGraphBuilder_RemoveFilter(graph, &transform.filter.IBaseFilter_iface);
|
||||
IGraphBuilder_AddFilter(graph, &transform.filter.IBaseFilter_iface, L"transform");
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CC, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_PREVIEW, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == VFW_S_NOPREVIEWPIN, "Got hr %#x.\n", hr);
|
||||
check_smart_tee_pin(source.source1.pin.pin.peer, L"Input");
|
||||
check_smart_tee_pin(transform.sink1.pin.pin.peer, L"Preview");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
|
||||
if (0)
|
||||
{
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_PREVIEW, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
disconnect_pins(graph, &source.source1);
|
||||
IGraphBuilder_RemoveFilter(graph, &transform.filter.IBaseFilter_iface);
|
||||
IGraphBuilder_AddFilter(graph, &transform.filter.IBaseFilter_iface, L"transform");
|
||||
|
||||
/* Test from the pin. */
|
||||
|
||||
source.source1.category = PIN_CATEGORY_CAPTURE;
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CAPTURE, NULL,
|
||||
(IUnknown *)&source.source1.pin.pin.IPin_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
todo_wine check_smart_tee_pin(source.source1.pin.pin.peer, L"Input");
|
||||
todo_wine check_smart_tee_pin(transform.sink1.pin.pin.peer, L"Capture");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
disconnect_pins(graph, &source.source1);
|
||||
IGraphBuilder_RemoveFilter(graph, &transform.filter.IBaseFilter_iface);
|
||||
IGraphBuilder_AddFilter(graph, &transform.filter.IBaseFilter_iface, L"transform");
|
||||
|
||||
/* Test when both CAPTURE and PREVIEW are available. */
|
||||
|
||||
source.source2.IKsPropertySet_iface.lpVtbl = &property_set_vtbl;
|
||||
source.source2.category = PIN_CATEGORY_PREVIEW;
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CAPTURE, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source1.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
disconnect_pins(graph, &source.source1);
|
||||
disconnect_pins(graph, &transform.source1);
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_PREVIEW, NULL,
|
||||
(IUnknown *)&source.filter.IBaseFilter_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(source.source2.pin.pin.peer == &transform.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
disconnect_pins(graph, &source.source2);
|
||||
disconnect_pins(graph, &transform.source1);
|
||||
|
||||
hr = ICaptureGraphBuilder2_RenderStream(capture_graph, &PIN_CATEGORY_CAPTURE, NULL,
|
||||
(IUnknown *)&source.source1.pin.pin.IPin_iface, NULL, &sink.filter.IBaseFilter_iface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
todo_wine check_smart_tee_pin(source.source1.pin.pin.peer, L"Input");
|
||||
todo_wine check_smart_tee_pin(transform.sink1.pin.pin.peer, L"Capture");
|
||||
ok(transform.source1.pin.pin.peer == &sink.sink1.pin.pin.IPin_iface, "Got wrong connection.\n");
|
||||
disconnect_pins(graph, &source.source1);
|
||||
disconnect_pins(graph, &transform.source1);
|
||||
|
||||
ref = ICaptureGraphBuilder2_Release(capture_graph);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
ref = IGraphBuilder_Release(graph);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
ref = IBaseFilter_Release(&transform.filter.IBaseFilter_iface);
|
||||
todo_wine ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
ref = IBaseFilter_Release(&sink.filter.IBaseFilter_iface);
|
||||
todo_wine ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
}
|
||||
|
||||
START_TEST(capturegraph)
|
||||
{
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
|
||||
test_find_interface();
|
||||
test_find_pin();
|
||||
test_render_stream();
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
|
|
@ -2012,30 +2012,6 @@ static SourceFilter* create_video_SourceFilter(void)
|
|||
return This;
|
||||
}
|
||||
|
||||
static SourceFilter* create_audio_SourceFilter(void)
|
||||
{
|
||||
SourceFilter *This = create_SourceFilter();
|
||||
if (!This)
|
||||
return NULL;
|
||||
This->mediaType.majortype = MEDIATYPE_Audio;
|
||||
This->mediaType.subtype = MEDIASUBTYPE_PCM;
|
||||
This->mediaType.bFixedSizeSamples = FALSE;
|
||||
This->mediaType.bTemporalCompression = FALSE;
|
||||
This->mediaType.lSampleSize = 0;
|
||||
This->mediaType.formattype = FORMAT_WaveFormatEx;
|
||||
This->mediaType.pUnk = NULL;
|
||||
This->mediaType.cbFormat = sizeof(WAVEFORMATEX);
|
||||
This->mediaType.pbFormat = (BYTE*) &This->audioInfo;
|
||||
This->audioInfo.wFormatTag = WAVE_FORMAT_PCM;
|
||||
This->audioInfo.nChannels = 1;
|
||||
This->audioInfo.nSamplesPerSec = 8000;
|
||||
This->audioInfo.nAvgBytesPerSec = 16000;
|
||||
This->audioInfo.nBlockAlign = 2;
|
||||
This->audioInfo.wBitsPerSample = 16;
|
||||
This->audioInfo.cbSize = 0;
|
||||
return This;
|
||||
}
|
||||
|
||||
static void test_smart_tee_filter_in_graph(IBaseFilter *smartTeeFilter, IPin *inputPin,
|
||||
IPin *capturePin, IPin *previewPin)
|
||||
{
|
||||
|
@ -2298,207 +2274,6 @@ static void test_unconnected_filter_state(void)
|
|||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
}
|
||||
|
||||
static HRESULT get_connected_filter_classid(IPin *pin, GUID *guid)
|
||||
{
|
||||
IPin *connectedPin = NULL;
|
||||
PIN_INFO connectedPinInfo;
|
||||
HRESULT hr = IPin_ConnectedTo(pin, &connectedPin);
|
||||
ok(SUCCEEDED(hr), "IPin_ConnectedTo() failed, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
hr = IPin_QueryPinInfo(connectedPin, &connectedPinInfo);
|
||||
ok(SUCCEEDED(hr), "IPin_QueryPinInfo() failed, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
if (connectedPinInfo.pFilter) {
|
||||
hr = IBaseFilter_GetClassID(connectedPinInfo.pFilter, guid);
|
||||
ok(SUCCEEDED(hr), "IBaseFilter_GetClassID() failed, hr=0x%08x\n", hr);
|
||||
IBaseFilter_Release(connectedPinInfo.pFilter);
|
||||
}
|
||||
end:
|
||||
if (connectedPin)
|
||||
IPin_Release(connectedPin);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static void test_audio_preview(ICaptureGraphBuilder2 *captureGraphBuilder, IGraphBuilder *graphBuilder,
|
||||
SourceFilter *audioSource, IBaseFilter *nullRenderer)
|
||||
{
|
||||
GUID clsid;
|
||||
HRESULT hr = ICaptureGraphBuilder2_RenderStream(captureGraphBuilder, &PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio,
|
||||
(IUnknown*)&audioSource->IBaseFilter_iface, NULL, nullRenderer);
|
||||
ok(hr == VFW_S_NOPREVIEWPIN, "ICaptureGraphBuilder2_RenderStream() returned hr=0x%08x\n", hr);
|
||||
hr = get_connected_filter_classid(&audioSource->IPin_iface, &clsid);
|
||||
if (FAILED(hr))
|
||||
return;
|
||||
ok(IsEqualIID(&clsid, &CLSID_SmartTee), "unexpected connected filter %s\n",
|
||||
wine_dbgstr_guid(&clsid));
|
||||
}
|
||||
|
||||
static void test_audio_capture(ICaptureGraphBuilder2 *captureGraphBuilder, IGraphBuilder *graphBuilder,
|
||||
SourceFilter *audioSource, IBaseFilter *nullRenderer)
|
||||
{
|
||||
GUID clsid;
|
||||
HRESULT hr = ICaptureGraphBuilder2_RenderStream(captureGraphBuilder, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio,
|
||||
(IUnknown*)&audioSource->IBaseFilter_iface, NULL, nullRenderer);
|
||||
ok(hr == S_OK, "ICaptureGraphBuilder2_RenderStream() returned hr=0x%08x\n", hr);
|
||||
hr = get_connected_filter_classid(&audioSource->IPin_iface, &clsid);
|
||||
if (FAILED(hr))
|
||||
return;
|
||||
ok(IsEqualIID(&clsid, &CLSID_SmartTee), "unexpected connected filter %s\n",
|
||||
wine_dbgstr_guid(&clsid));
|
||||
}
|
||||
|
||||
static void test_video_preview(ICaptureGraphBuilder2 *captureGraphBuilder, IGraphBuilder *graphBuilder,
|
||||
SourceFilter *videoSource, IBaseFilter *nullRenderer)
|
||||
{
|
||||
GUID clsid;
|
||||
HRESULT hr = ICaptureGraphBuilder2_RenderStream(captureGraphBuilder, &PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
|
||||
(IUnknown*)&videoSource->IBaseFilter_iface, NULL, nullRenderer);
|
||||
ok(hr == VFW_S_NOPREVIEWPIN, "ICaptureGraphBuilder2_RenderStream() failed, hr=0x%08x\n", hr);
|
||||
hr = get_connected_filter_classid(&videoSource->IPin_iface, &clsid);
|
||||
if (FAILED(hr))
|
||||
return;
|
||||
ok(IsEqualIID(&clsid, &CLSID_SmartTee), "unexpected connected filter %s\n",
|
||||
wine_dbgstr_guid(&clsid));
|
||||
}
|
||||
|
||||
static void test_video_capture(ICaptureGraphBuilder2 *captureGraphBuilder, IGraphBuilder *graphBuilder,
|
||||
SourceFilter *videoSource, IBaseFilter *nullRenderer)
|
||||
{
|
||||
GUID clsid;
|
||||
HRESULT hr = ICaptureGraphBuilder2_RenderStream(captureGraphBuilder, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
|
||||
(IUnknown*)&videoSource->IBaseFilter_iface, NULL, nullRenderer);
|
||||
ok(hr == S_OK, "ICaptureGraphBuilder2_RenderStream() failed, hr=0x%08x\n", hr);
|
||||
hr = get_connected_filter_classid(&videoSource->IPin_iface, &clsid);
|
||||
if (FAILED(hr))
|
||||
return;
|
||||
ok(IsEqualIID(&clsid, &CLSID_SmartTee), "unexpected connected filter %s\n",
|
||||
wine_dbgstr_guid(&clsid));
|
||||
}
|
||||
|
||||
static void test_audio_smart_tee_filter_auto_insertion(
|
||||
void (*test_function)(ICaptureGraphBuilder2 *cgb, IGraphBuilder *gb,
|
||||
SourceFilter *audioSource, IBaseFilter *nullRenderer))
|
||||
{
|
||||
HRESULT hr;
|
||||
ICaptureGraphBuilder2 *captureGraphBuilder = NULL;
|
||||
IGraphBuilder *graphBuilder = NULL;
|
||||
IBaseFilter *nullRenderer = NULL;
|
||||
SourceFilter *audioSource = NULL;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_ICaptureGraphBuilder2, (void**)&captureGraphBuilder);
|
||||
ok(SUCCEEDED(hr), "couldn't create capture graph builder, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder,
|
||||
(LPVOID*)&graphBuilder);
|
||||
ok(SUCCEEDED(hr), "couldn't create graph builder, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
|
||||
hr = ICaptureGraphBuilder2_SetFiltergraph(captureGraphBuilder, graphBuilder);
|
||||
ok(SUCCEEDED(hr), "ICaptureGraphBuilder2_SetFilterGraph() failed, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IBaseFilter, (LPVOID*)&nullRenderer);
|
||||
ok(SUCCEEDED(hr) ||
|
||||
/* Windows 2008: http://stackoverflow.com/questions/29410348/initialize-nullrender-failed-with-error-regdb-e-classnotreg-on-win2008-r2 */
|
||||
broken(hr == REGDB_E_CLASSNOTREG), "couldn't create NullRenderer, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
hr = IGraphBuilder_AddFilter(graphBuilder, nullRenderer, NULL);
|
||||
ok(SUCCEEDED(hr), "IGraphBuilder_AddFilter() failed, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
|
||||
audioSource = create_audio_SourceFilter();
|
||||
ok(audioSource != NULL, "couldn't create audio source\n");
|
||||
if (audioSource == NULL)
|
||||
goto end;
|
||||
hr = IGraphBuilder_AddFilter(graphBuilder, &audioSource->IBaseFilter_iface, NULL);
|
||||
ok(SUCCEEDED(hr), "IGraphBuilder_AddFilter() failed, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
|
||||
test_function(captureGraphBuilder, graphBuilder, audioSource, nullRenderer);
|
||||
|
||||
end:
|
||||
if (nullRenderer)
|
||||
IBaseFilter_Release(nullRenderer);
|
||||
if (audioSource)
|
||||
IBaseFilter_Release(&audioSource->IBaseFilter_iface);
|
||||
if (captureGraphBuilder)
|
||||
ICaptureGraphBuilder2_Release(captureGraphBuilder);
|
||||
if (graphBuilder)
|
||||
IGraphBuilder_Release(graphBuilder);
|
||||
}
|
||||
|
||||
static void test_video_smart_tee_filter_auto_insertion(
|
||||
void (*test_function)(ICaptureGraphBuilder2 *cgb, IGraphBuilder *gb,
|
||||
SourceFilter *videoSource, IBaseFilter *nullRenderer))
|
||||
{
|
||||
HRESULT hr;
|
||||
ICaptureGraphBuilder2 *captureGraphBuilder = NULL;
|
||||
IGraphBuilder *graphBuilder = NULL;
|
||||
IBaseFilter *nullRenderer = NULL;
|
||||
SourceFilter *videoSource = NULL;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_ICaptureGraphBuilder2, (void**)&captureGraphBuilder);
|
||||
ok(SUCCEEDED(hr), "couldn't create capture graph builder, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder,
|
||||
(LPVOID*)&graphBuilder);
|
||||
ok(SUCCEEDED(hr), "couldn't create graph builder, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
|
||||
hr = ICaptureGraphBuilder2_SetFiltergraph(captureGraphBuilder, graphBuilder);
|
||||
ok(SUCCEEDED(hr), "ICaptureGraphBuilder2_SetFilterGraph() failed, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
|
||||
hr = CoCreateInstance(&CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IBaseFilter, (LPVOID*)&nullRenderer);
|
||||
ok(SUCCEEDED(hr) ||
|
||||
/* Windows 2008: http://stackoverflow.com/questions/29410348/initialize-nullrender-failed-with-error-regdb-e-classnotreg-on-win2008-r2 */
|
||||
broken(hr == REGDB_E_CLASSNOTREG), "couldn't create NullRenderer, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
hr = IGraphBuilder_AddFilter(graphBuilder, nullRenderer, NULL);
|
||||
ok(SUCCEEDED(hr), "IGraphBuilder_AddFilter() failed, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
|
||||
videoSource = create_video_SourceFilter();
|
||||
ok(videoSource != NULL, "couldn't create audio source\n");
|
||||
if (videoSource == NULL)
|
||||
goto end;
|
||||
hr = IGraphBuilder_AddFilter(graphBuilder, &videoSource->IBaseFilter_iface, NULL);
|
||||
ok(SUCCEEDED(hr), "IGraphBuilder_AddFilter() failed, hr=0x%08x\n", hr);
|
||||
if (FAILED(hr))
|
||||
goto end;
|
||||
|
||||
test_function(captureGraphBuilder, graphBuilder, videoSource, nullRenderer);
|
||||
|
||||
end:
|
||||
if (nullRenderer)
|
||||
IBaseFilter_Release(nullRenderer);
|
||||
if (videoSource)
|
||||
IBaseFilter_Release(&videoSource->IBaseFilter_iface);
|
||||
if (captureGraphBuilder)
|
||||
ICaptureGraphBuilder2_Release(captureGraphBuilder);
|
||||
if (graphBuilder)
|
||||
IGraphBuilder_Release(graphBuilder);
|
||||
}
|
||||
|
||||
struct testfilter
|
||||
{
|
||||
struct strmbase_filter filter;
|
||||
|
@ -3005,12 +2780,6 @@ START_TEST(smartteefilter)
|
|||
|
||||
test_smart_tee_filter();
|
||||
|
||||
test_audio_smart_tee_filter_auto_insertion(test_audio_preview);
|
||||
test_audio_smart_tee_filter_auto_insertion(test_audio_capture);
|
||||
|
||||
test_video_smart_tee_filter_auto_insertion(test_video_preview);
|
||||
test_video_smart_tee_filter_auto_insertion(test_video_capture);
|
||||
|
||||
CloseHandle(event);
|
||||
CoUninitialize();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue