Adapted from the video renderer tests.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- I had this patch in my local tree since a while, but never got around to finishing it.
dlls/qedit/tests/nullrenderer.c | 464 ++++++++++++++++++++++++++++++++ 1 file changed, 464 insertions(+)
diff --git a/dlls/qedit/tests/nullrenderer.c b/dlls/qedit/tests/nullrenderer.c index 8f26e4716ec..3285e22e5c7 100644 --- a/dlls/qedit/tests/nullrenderer.c +++ b/dlls/qedit/tests/nullrenderer.c @@ -20,6 +20,7 @@
#define COBJMACROS #include "dshow.h" +#include "wine/strmbase.h" #include "wine/test.h"
static IBaseFilter *create_null_renderer(void) @@ -420,6 +421,468 @@ static void test_enum_media_types(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+struct testfilter +{ + struct strmbase_filter filter; + struct strmbase_source source; +}; + +static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface) +{ + return CONTAINING_RECORD(iface, struct testfilter, filter); +} + +static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index) +{ + struct testfilter *filter = impl_from_strmbase_filter(iface); + if (!index) + return &filter->source.pin; + return NULL; +} + +static void testfilter_destroy(struct strmbase_filter *iface) +{ + struct testfilter *filter = impl_from_strmbase_filter(iface); + strmbase_source_cleanup(&filter->source); + strmbase_filter_cleanup(&filter->filter); +} + +static const struct strmbase_filter_ops testfilter_ops = +{ + .filter_get_pin = testfilter_get_pin, + .filter_destroy = testfilter_destroy, +}; + +static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, + IMemInputPin *peer, IMemAllocator **allocator) +{ + return S_OK; +} + +static const struct strmbase_source_ops testsource_ops = +{ + .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, + .pfnDecideAllocator = testsource_DecideAllocator, +}; + +static void testfilter_init(struct testfilter *filter) +{ + static const GUID clsid = {0xabacab}; + strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); + strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops); +} + +static void test_allocator(IMemInputPin *input) +{ + IMemAllocator *req_allocator, *ret_allocator; + ALLOCATOR_PROPERTIES props; + HRESULT hr; + + hr = IMemInputPin_GetAllocatorRequirements(input, &props); + ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr); + + hr = IMemInputPin_GetAllocator(input, &ret_allocator); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + + if (hr == S_OK) + { + hr = IMemAllocator_GetProperties(ret_allocator, &props); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!props.cBuffers, "Got %d buffers.\n", props.cBuffers); + ok(!props.cbBuffer, "Got size %d.\n", props.cbBuffer); + ok(!props.cbAlign, "Got alignment %d.\n", props.cbAlign); + ok(!props.cbPrefix, "Got prefix %d.\n", props.cbPrefix); + + hr = IMemInputPin_NotifyAllocator(input, ret_allocator, TRUE); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IMemAllocator_Release(ret_allocator); + } + + hr = IMemInputPin_NotifyAllocator(input, NULL, TRUE); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, + &IID_IMemAllocator, (void **)&req_allocator); + + hr = IMemInputPin_NotifyAllocator(input, req_allocator, TRUE); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMemInputPin_GetAllocator(input, &ret_allocator); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(ret_allocator == req_allocator, "Allocators didn't match.\n"); + + IMemAllocator_Release(req_allocator); + IMemAllocator_Release(ret_allocator); +} + +struct frame_thread_params +{ + IMemInputPin *sink; + IMediaSample *sample; +}; + +static DWORD WINAPI frame_thread(void *arg) +{ + struct frame_thread_params *params = arg; + HRESULT hr; + + if (winetest_debug > 1) trace("%04x: Sending frame.\n", GetCurrentThreadId()); + hr = IMemInputPin_Receive(params->sink, params->sample); + if (winetest_debug > 1) trace("%04x: Returned %#x.\n", GetCurrentThreadId(), hr); + IMediaSample_Release(params->sample); + free(params); + return hr; +} + +static HANDLE send_frame_time(IMemInputPin *sink, REFERENCE_TIME start_time, unsigned char color) +{ + struct frame_thread_params *params = malloc(sizeof(*params)); + IMemAllocator *allocator; + REFERENCE_TIME end_time; + IMediaSample *sample; + HANDLE thread; + HRESULT hr; + BYTE *data; + + hr = IMemInputPin_GetAllocator(sink, &allocator); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaSample_GetPointer(sample, &data); + ok(hr == S_OK, "Got hr %#x.\n", hr); + memset(data, color, 32 * 16 * 2); + + hr = IMediaSample_SetActualDataLength(sample, 32 * 16 * 2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + start_time *= 10000000; + end_time = start_time + 10000000; + hr = IMediaSample_SetTime(sample, &start_time, &end_time); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + params->sink = sink; + params->sample = sample; + thread = CreateThread(NULL, 0, frame_thread, params, 0, NULL); + + IMemAllocator_Release(allocator); + return thread; +} + +static HANDLE send_frame(IMemInputPin *sink) +{ + return send_frame_time(sink, 0, 0x55); /* purple */ +} + +static HRESULT join_thread_(int line, HANDLE thread) +{ + DWORD ret; + ok_(__FILE__, line)(!WaitForSingleObject(thread, 1000), "Wait failed.\n"); + GetExitCodeThread(thread, &ret); + CloseHandle(thread); + return ret; +} +#define join_thread(a) join_thread_(__LINE__, a) + +static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) +{ + IMemAllocator *allocator; + IMediaControl *control; + IMediaSample *sample; + OAFilterState state; + HANDLE thread; + HRESULT hr; + + IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control); + + thread = send_frame(input); + hr = join_thread(thread); + todo_wine ok(hr == E_FAIL, "Got hr %#x.\n", hr); + + /* The renderer is not fully paused until it receives a sample. The thread + * sending the sample blocks in IMemInputPin_Receive() until the filter is + * stopped or run. */ + + hr = IMediaControl_Pause(control); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + + thread = send_frame(input); + + hr = IMediaControl_GetState(control, 1000, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + todo_wine ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n"); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = join_thread(thread); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + /* The sink will decommit our allocator for us when stopping, and recommit + * it when pausing. */ + hr = IMemInputPin_GetAllocator(input, &allocator); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0); + todo_wine ok(hr == VFW_E_NOT_COMMITTED, "Got hr %#x.\n", hr); + if (hr == S_OK) IMediaSample_Release(sample); + + hr = IMemAllocator_Commit(allocator); + ok(hr == S_OK, "Got hr %#x.\n", hr); + thread = send_frame(input); + hr = join_thread(thread); + todo_wine ok(hr == E_FAIL, "Got hr %#x.\n", hr); + + hr = IMediaControl_Pause(control); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + + thread = send_frame(input); + + hr = IMediaControl_GetState(control, 1000, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + todo_wine ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n"); + + hr = IMediaControl_Run(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = join_thread(thread); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + thread = send_frame(input); + hr = join_thread(thread); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Pause(control); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + + thread = send_frame(input); + + hr = IMediaControl_GetState(control, 1000, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + todo_wine ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n"); + + hr = IMediaControl_Run(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = join_thread(thread); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Pause(control); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(state == State_Paused, "Got state %u.\n", state); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Pause(control); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(state == State_Paused, "Got state %u.\n", state); + + hr = IMediaControl_Run(control); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(state == State_Running, "Got state %u.\n", state); + + thread = send_frame(input); + hr = join_thread(thread); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + IMemAllocator_Release(allocator); + IMediaControl_Release(control); +} + +static void test_flushing(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph) +{ + IMediaControl *control; + OAFilterState state; + HANDLE thread; + HRESULT hr; + + IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control); + + hr = IMediaControl_Pause(control); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + thread = send_frame(input); + todo_wine ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n"); + + hr = IMediaControl_GetState(control, 0, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_BeginFlush(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = join_thread(thread); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + thread = send_frame(input); + hr = join_thread(thread); + todo_wine ok(hr == E_FAIL, "Got hr %#x.\n", hr); + + hr = IPin_EndFlush(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + /* We dropped the sample we were holding, so now we need a new one... */ + + hr = IMediaControl_GetState(control, 0, &state); + todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + + thread = send_frame(input); + todo_wine ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n"); + + hr = IMediaControl_Run(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = join_thread(thread); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_BeginFlush(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = join_thread(send_frame(input)); + todo_wine ok(hr == E_FAIL, "Got hr %#x.\n", hr); + + hr = IPin_EndFlush(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = join_thread(send_frame(input)); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + IMediaControl_Release(control); +} + +static void test_connect_pin(void) +{ + static const AM_MEDIA_TYPE req_mt = + { + .majortype = {0x111}, + .subtype = {0x222}, + .formattype = {0x333}, + }; + ALLOCATOR_PROPERTIES req_props = {1, 32 * 16 * 4, 1, 0}, ret_props; + IBaseFilter *filter = create_null_renderer(); + struct testfilter source; + IMemAllocator *allocator; + IFilterGraph2 *graph; + IMemInputPin *input; + AM_MEDIA_TYPE mt; + IPin *pin, *peer; + HRESULT hr; + ULONG ref; + + testfilter_init(&source); + + CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterGraph2, (void **)&graph); + IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source"); + IFilterGraph2_AddFilter(graph, filter, L"sink"); + + IBaseFilter_FindPin(filter, L"In", &pin); + + peer = (IPin *)0xdeadbeef; + hr = IPin_ConnectedTo(pin, &peer); + ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + ok(!peer, "Got peer %p.\n", peer); + + hr = IPin_ConnectionMediaType(pin, &mt); + ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + + hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_ConnectedTo(pin, &peer); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(peer == &source.source.pin.IPin_iface, "Got peer %p.\n", peer); + IPin_Release(peer); + + hr = IPin_ConnectionMediaType(pin, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!memcmp(&mt, &req_mt, sizeof(AM_MEDIA_TYPE)), "Media types didn't match.\n"); + + IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input); + + test_allocator(input); + + hr = IMemInputPin_GetAllocator(input, &allocator); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n"); + hr = IMemAllocator_Commit(allocator); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IMemAllocator_Release(allocator); + + hr = IMemInputPin_ReceiveCanBlock(input); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + test_filter_state(input, graph); + test_flushing(pin, input, graph); + + hr = IFilterGraph2_Disconnect(graph, pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph2_Disconnect(graph, pin); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(source.source.pin.peer == pin, "Got peer %p.\n", peer); + IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface); + + peer = (IPin *)0xdeadbeef; + hr = IPin_ConnectedTo(pin, &peer); + ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + ok(!peer, "Got peer %p.\n", peer); + + hr = IPin_ConnectionMediaType(pin, &mt); + ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + + IMemInputPin_Release(input); + IPin_Release(pin); + ref = IFilterGraph2_Release(graph); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + START_TEST(nullrenderer) { IBaseFilter *filter; @@ -443,6 +906,7 @@ START_TEST(nullrenderer) test_aggregation(); test_media_types(); test_enum_media_types(); + test_connect_pin();
CoUninitialize(); }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/nullrenderer.c | 24 ++++++++++++++++++++++++ dlls/qedit/tests/nullrenderer.c | 10 +++++----- 2 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/dlls/qedit/nullrenderer.c b/dlls/qedit/nullrenderer.c index c64d5e2987c..a8594eade8b 100644 --- a/dlls/qedit/nullrenderer.c +++ b/dlls/qedit/nullrenderer.c @@ -29,6 +29,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(qedit); struct null_renderer { struct strmbase_renderer renderer; + HANDLE run_event; };
static struct null_renderer *impl_from_strmbase_renderer(struct strmbase_renderer *iface) @@ -41,7 +42,14 @@ static HRESULT WINAPI NullRenderer_DoRenderSample(struct strmbase_renderer *ifac struct null_renderer *filter = impl_from_strmbase_renderer(iface);
if (filter->renderer.filter.state == State_Paused) + { + const HANDLE events[2] = {filter->run_event, filter->renderer.flush_event}; + SetEvent(filter->renderer.state_event); + LeaveCriticalSection(&filter->renderer.csRenderLock); + WaitForMultipleObjects(2, events, FALSE, INFINITE); + EnterCriticalSection(&filter->renderer.csRenderLock); + }
return S_OK; } @@ -56,14 +64,29 @@ static void null_renderer_destroy(struct strmbase_renderer *iface) { struct null_renderer *filter = impl_from_strmbase_renderer(iface);
+ CloseHandle(filter->run_event); strmbase_renderer_cleanup(&filter->renderer); free(filter); }
+static void null_renderer_start_stream(struct strmbase_renderer *iface) +{ + struct null_renderer *filter = impl_from_strmbase_renderer(iface); + SetEvent(filter->run_event); +} + +static void null_renderer_stop_stream(struct strmbase_renderer *iface) +{ + struct null_renderer *filter = impl_from_strmbase_renderer(iface); + ResetEvent(filter->run_event); +} + static const struct strmbase_renderer_ops renderer_ops = { .pfnCheckMediaType = NullRenderer_CheckMediaType, .pfnDoRenderSample = NullRenderer_DoRenderSample, + .renderer_start_stream = null_renderer_start_stream, + .renderer_stop_stream = null_renderer_stop_stream, .renderer_destroy = null_renderer_destroy, };
@@ -75,6 +98,7 @@ HRESULT null_renderer_create(IUnknown *outer, IUnknown **out) return E_OUTOFMEMORY;
strmbase_renderer_init(&object->renderer, outer, &CLSID_NullRenderer, L"In", &renderer_ops); + object->run_event = CreateEventW(NULL, TRUE, FALSE, NULL);
TRACE("Created null renderer %p.\n", object); *out = &object->renderer.filter.IUnknown_inner; diff --git a/dlls/qedit/tests/nullrenderer.c b/dlls/qedit/tests/nullrenderer.c index 3285e22e5c7..754228d770b 100644 --- a/dlls/qedit/tests/nullrenderer.c +++ b/dlls/qedit/tests/nullrenderer.c @@ -615,7 +615,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) hr = IMediaControl_GetState(control, 1000, &state); ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n"); + ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Stop(control); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -648,7 +648,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) hr = IMediaControl_GetState(control, 1000, &state); ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n"); + ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -674,7 +674,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) hr = IMediaControl_GetState(control, 1000, &state); ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n"); + ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -742,7 +742,7 @@ static void test_flushing(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_FALSE, "Got hr %#x.\n", hr);
thread = send_frame(input); - todo_wine ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n"); + ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -766,7 +766,7 @@ static void test_flushing(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph) todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
thread = send_frame(input); - todo_wine ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n"); + ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); ok(hr == S_OK, "Got hr %#x.\n", hr);