From: Paul Gofman pgofman@codeweavers.com
--- dlls/qcap/tests/videocapture.c | 154 +++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+)
diff --git a/dlls/qcap/tests/videocapture.c b/dlls/qcap/tests/videocapture.c index cb74c20481f..a7f6eea666a 100644 --- a/dlls/qcap/tests/videocapture.c +++ b/dlls/qcap/tests/videocapture.c @@ -20,6 +20,7 @@
#define COBJMACROS #include "dshow.h" +#include "mferror.h" #include "wine/test.h" #include "wine/strmbase.h"
@@ -649,6 +650,158 @@ static void test_connection(IMoniker *moniker) ok(!ref, "Got outstanding refcount %ld.\n", ref); }
+static void test_multiple_objects(IMoniker *moniker) +{ + struct testfilter testsink, testsink2; + IAMStreamConfig *config, *config2; + IMediaControl *control, *control2; + IFilterGraph2 *graph, *graph2; + IBaseFilter *filter, *filter2; + IEnumPins *enum_pins; + OAFilterState state; + IPin *pin, *pin2; + HRESULT hr; + DWORD ret; + ULONG ref; + + hr = IMoniker_BindToObject(moniker, NULL, NULL, &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "got %#lx.\n", hr); + hr = IMoniker_BindToObject(moniker, NULL, NULL, &IID_IBaseFilter, (void **)&filter2); + todo_wine ok(hr == S_OK, "got %#lx.\n", hr); + if (FAILED(hr)) + { + IBaseFilter_Release(filter); + return; + } + ok(filter != filter2, "got same objects.\n"); + + hr = IBaseFilter_EnumPins(filter, &enum_pins); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + pin = NULL; + while (IEnumPins_Next(enum_pins, 1, &pin, NULL) == S_OK) + { + PIN_DIRECTION dir; + IPin_QueryDirection(pin, &dir); + if (dir == PINDIR_OUTPUT) + break; + IPin_Release(pin); + } + IEnumPins_Release(enum_pins); + ok(!!pin, "got NULL.\n"); + + hr = IBaseFilter_EnumPins(filter2, &enum_pins); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + pin2 = NULL; + while (IEnumPins_Next(enum_pins, 1, &pin2, NULL) == S_OK) + { + PIN_DIRECTION dir; + IPin_QueryDirection(pin2, &dir); + if (dir == PINDIR_OUTPUT) + break; + IPin_Release(pin2); + } + IEnumPins_Release(enum_pins); + ok(!!pin2, "got NULL.\n"); + + CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterGraph2, (void **)&graph); + IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control); + testfilter_init(&testsink); + IFilterGraph2_AddFilter(graph, &testsink.filter.IBaseFilter_iface, L"sink"); + IFilterGraph2_AddFilter(graph, filter, L"source"); + hr = IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **)&config); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterGraph2, (void **)&graph2); + IFilterGraph2_QueryInterface(graph2, &IID_IMediaControl, (void **)&control2); + testfilter_init(&testsink2); + IFilterGraph2_AddFilter(graph2, &testsink2.filter.IBaseFilter_iface, L"sink"); + IFilterGraph2_AddFilter(graph2, filter2, L"source"); + hr = IPin_QueryInterface(pin2, &IID_IAMStreamConfig, (void **)&config2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IFilterGraph2_ConnectDirect(graph, pin, &testsink.sink.pin.IPin_iface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IFilterGraph2_ConnectDirect(graph2, pin2, &testsink2.sink.pin.IPin_iface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IMediaControl_Run(control); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Running, "Got state %lu.\n", state); + + hr = IBaseFilter_Pause(filter2); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (FAILED(hr)) + goto cleanup; + + hr = IMediaControl_Run(control2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IMediaControl_GetState(control2, 0, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Running, "Got state %lu.\n", state); + + ret = WaitForSingleObject(testsink2.got_sample, 5000); + ok(!ret, "Got %lu.\n", ret); + + if (0) + { + /* times out on Windows unless a sample was received before IMediaControl_Run(control2) which is unlikely. */ + ret = WaitForSingleObject(testsink.got_sample, 5000); + ok(ret == WAIT_TIMEOUT, "Got %lu.\n", ret); + } + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Running, "Got state %lu.\n", state); + hr = IMediaControl_GetState(control2, 0, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Running, "Got state %lu.\n", state); + + hr = IMediaControl_Pause(control); + ok(hr == MF_E_VIDEO_RECORDING_DEVICE_PREEMPTED, "Got hr %#lx.\n", hr); + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Stopped, "Got state %lu.\n", state); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Stopped, "Got state %lu.\n", state); + + hr = IMediaControl_Pause(control2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IMediaControl_GetState(control2, 0, &state); + ok(hr == VFW_S_CANT_CUE, "Got hr %#lx.\n", hr); + ok(state == State_Paused, "Got state %lu.\n", state); + hr = IMediaControl_Stop(control2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IMediaControl_GetState(control2, 0, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Stopped, "Got state %lu.\n", state); + +cleanup: + IAMStreamConfig_Release(config); + IMediaControl_Release(control); + ref = IFilterGraph2_Release(graph); + ok(!ref, "Got outstanding refcount %ld.\n", ref); + + IPin_Release(pin); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %ld.\n", ref); + + IAMStreamConfig_Release(config2); + IMediaControl_Release(control2); + ref = IFilterGraph2_Release(graph2); + ok(!ref, "Got outstanding refcount %ld.\n", ref); + IPin_Release(pin2); + ref = IBaseFilter_Release(filter2); + ok(!ref, "Got outstanding refcount %ld.\n", ref); +} + START_TEST(videocapture) { ICreateDevEnum *dev_enum; @@ -698,6 +851,7 @@ START_TEST(videocapture) ok(!ref, "Got outstanding refcount %ld.\n", ref);
test_connection(moniker); + test_multiple_objects(moniker);
IMoniker_Release(moniker); }