From: Ziqing Hui zhui@codeweavers.com
--- dlls/qasf/tests/dmowrapper.c | 101 ++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 2 deletions(-)
diff --git a/dlls/qasf/tests/dmowrapper.c b/dlls/qasf/tests/dmowrapper.c index 9fade2f7f1f..632b7e2e558 100644 --- a/dlls/qasf/tests/dmowrapper.c +++ b/dlls/qasf/tests/dmowrapper.c @@ -1122,6 +1122,7 @@ struct testfilter struct strmbase_sink sink; const AM_MEDIA_TYPE *sink_mt; unsigned int got_new_segment, got_eos, got_begin_flush, got_end_flush; + HANDLE event; };
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface) @@ -1145,6 +1146,7 @@ static void testfilter_destroy(struct strmbase_filter *iface) strmbase_source_cleanup(&filter->source); strmbase_sink_cleanup(&filter->sink); strmbase_filter_cleanup(&filter->filter); + CloseHandle(filter->event); }
static const struct strmbase_filter_ops testfilter_ops = @@ -1199,6 +1201,7 @@ static HRESULT testsink_get_media_type(struct strmbase_pin *iface, unsigned int
static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample *sample) { + struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter); REFERENCE_TIME start, stop; LONG len, i; HRESULT hr; @@ -1257,6 +1260,9 @@ static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample if (testmode == 10) testmode = 11;
+ if (testmode == 13 && got_Receive > 1) + WaitForSingleObject(filter->event, INFINITE); + return S_OK; }
@@ -1311,6 +1317,7 @@ static void testfilter_init(struct testfilter *filter) strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); strmbase_source_init(&filter->source, &filter->filter, L"source", &testsource_ops); strmbase_sink_init(&filter->sink, &filter->filter, L"sink", &testsink_ops, NULL); + filter->event = CreateEventA(NULL, TRUE, FALSE, NULL); }
static void test_sink_allocator(IMemInputPin *input) @@ -1518,15 +1525,46 @@ static void test_filter_state(IMediaControl *control) ok(state == State_Stopped, "Got state %lu.\n", state); }
+struct receive_proc_arg +{ + IMemInputPin *input_pin; + IMediaSample *sample; +}; + +static DWORD WINAPI receive_proc(void *arg) +{ + struct receive_proc_arg *proc_arg = arg; + HRESULT hr; + + hr = IMemInputPin_Receive(proc_arg->input_pin, proc_arg->sample); + ok(hr == S_OK, "Receive returned %#lx.\n", hr); + + return 0; +} + +static DWORD WINAPI stop_filter_proc(void *arg) +{ + IBaseFilter *filter = arg; + HRESULT hr; + + hr = IBaseFilter_Stop(filter); + ok(hr == S_OK, "Stop returned %#lx.\n", hr); + + return 0; +} + static void test_sample_processing(IMediaControl *control, IMemInputPin *input, - struct testfilter *testsink) + struct testfilter *testsink, IBaseFilter *dmo_filter) { + struct receive_proc_arg receive_proc_arg; + HANDLE stop_thread, receive_thread; REFERENCE_TIME start, stop; IMemAllocator *allocator; IMediaSample *sample; LONG size, i; HRESULT hr; BYTE *data; + DWORD ret;
hr = IMemInputPin_ReceiveCanBlock(input); ok(hr == S_OK, "Got hr %#lx.\n", hr); @@ -1661,6 +1699,65 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input, ok(got_Discontinuity == 1, "Got %u calls to Discontinuity().\n", got_Discontinuity); got_ProcessInput = got_ProcessOutput = got_Receive = got_Discontinuity = 0;
+ /* Test receive with downstream input allocator decommitted. */ + hr = IMemAllocator_Decommit(testsink->sink.pAllocator); + ok(hr == S_OK, "Decommit returned %#lx.\n", hr); + hr = IMemInputPin_Receive(input, sample); + todo_wine + ok(hr == VFW_E_NOT_COMMITTED, "Receive returned %#lx.\n", hr); + todo_wine + ok(got_ProcessInput == 0, "Got %u calls to ProcessInput().\n", got_ProcessInput); + ok(got_ProcessOutput == 0, "Got %u calls to ProcessOutput().\n", got_ProcessOutput); + ok(got_Receive == 0, "Got %u calls to Receive().\n", got_Receive); + ok(got_Discontinuity == 1, "Got %u calls to Discontinuity().\n", got_Discontinuity); + hr = IMemAllocator_Commit(testsink->sink.pAllocator); + ok(hr == S_OK, "Commit returned %#lx.\n", hr); + got_ProcessInput = got_ProcessOutput = got_Receive = got_Discontinuity = 0; + + /* Test receive with filter stopped. */ + hr = IBaseFilter_Stop(dmo_filter); + ok(hr == S_OK, "Stop returned %#lx.\n", hr); + hr = IMemInputPin_Receive(input, sample); + todo_wine + ok(hr == VFW_E_WRONG_STATE, "Receive returned %#lx.\n", hr); + todo_wine + ok(got_ProcessInput == 0, "Got %u calls to ProcessInput().\n", got_ProcessInput); + ok(got_ProcessOutput == 0, "Got %u calls to ProcessOutput().\n", got_ProcessOutput); + ok(got_Receive == 0, "Got %u calls to Receive().\n", got_Receive); + todo_wine + ok(got_Discontinuity == 0, "Got %u calls to Discontinuity().\n", got_Discontinuity); + hr = IMediaControl_Run(control); + ok(hr == S_OK, "Run returned %#lx.\n", hr); + got_ProcessInput = got_ProcessOutput = got_Receive = got_Discontinuity = 0; + + /* Test stop filter during receiving. */ + testmode = 13; + /* Call Receive() in new thread, it will be blocked + * by event waiting in testsink_Receive(). */ + receive_proc_arg.input_pin = input; + receive_proc_arg.sample = sample; + receive_thread = CreateThread(NULL, 0, receive_proc, &receive_proc_arg, 0, NULL); + ok(!!receive_thread, "CreateThread returned NULL thread.\n"); + ret = WaitForSingleObject(receive_thread, 200); + ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %#lx.\n", ret); + /* Call Stop() in new thread, it will be blocked + * because Receive() is still processing. */ + stop_thread = CreateThread(NULL, 0, stop_filter_proc, dmo_filter, 0, NULL); + ok(!!stop_thread, "CreateThread returned NULL thread.\n"); + ret = WaitForSingleObject(stop_thread, 200); + todo_wine + ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %#lx.\n", ret); + /* Signal event to end Receive(). */ + SetEvent(testsink->event); + ret = WaitForSingleObject(receive_thread, 200); + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx.\n", ret); + ret = WaitForSingleObject(stop_thread, 200); + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %#lx.\n", ret); + got_ProcessInput = got_ProcessOutput = got_Receive = got_Discontinuity = 0; + + testmode = 0; + CloseHandle(stop_thread); + CloseHandle(receive_thread); hr = IMediaControl_Stop(control); ok(hr == S_OK, "Got hr %#lx.\n", hr); IMediaSample_Release(sample); @@ -1882,7 +1979,7 @@ static void test_connect_pin(void) ok(hr == S_OK, "Got hr %#lx.\n", hr);
test_filter_state(control); - test_sample_processing(control, meminput, &testsink); + test_sample_processing(control, meminput, &testsink, filter);
/* Streaming event tests are more interesting if multiple source pins are * connected. */