Signed-off-by: Anton Baskanov baskanov@gmail.com --- v2: Pass BSTR instead of a C string. --- dlls/quartz/tests/filtergraph.c | 130 ++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+)
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index e4b72958e10..835a735667a 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -5148,6 +5148,135 @@ static void test_autoplug_uyvy(void) ok(source_pin.ref == 1, "Got outstanding refcount %d.\n", source_pin.ref); }
+static void test_set_notify_flags(void) +{ + IFilterGraph2 *graph = create_graph(); + IMediaEventSink *media_event_sink; + IMediaControl *media_control; + IMediaEventEx *media_event; + struct testfilter filter; + LONG_PTR param1, param2; + HANDLE event; + HWND window; + BSTR status; + HRESULT hr; + ULONG ref; + LONG code; + MSG msg; + + window = CreateWindowA("static", NULL, WS_OVERLAPPEDWINDOW, + 50, 50, 150, 150, NULL, NULL, NULL, NULL); + ok(!!window, "Failed to create window.\n"); + status = SysAllocString(L"status"); + + hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEventEx, (void **)&media_event); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEventSink, (void **)&media_event_sink); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + testfilter_init(&filter, NULL, 0); + filter.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl; + filter.misc_flags = AM_FILTER_MISC_FLAGS_IS_RENDERER; + + hr = IFilterGraph2_AddFilter(graph, &filter.IBaseFilter_iface, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaEventEx_GetEventHandle(media_event, (OAEVENT *)&event); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaEventEx_SetNotifyWindow(media_event, (OAHWND)window, WM_USER, 0); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Run(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n"); + + while (PeekMessageA(&msg, window, WM_USER, WM_USER, PM_REMOVE)); + + hr = IMediaEventEx_SetNotifyFlags(media_event, AM_MEDIAEVENT_NONOTIFY); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + + hr = IMediaEventEx_GetEvent(media_event, &code, ¶m1, ¶m2, 50); + todo_wine ok(hr == E_ABORT, "Got hr %#x.\n", hr); + + hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + + ok(!PeekMessageA(&msg, window, WM_USER, WM_USER, PM_REMOVE), "Window should not be notified.\n"); + + hr = IMediaEventEx_GetEvent(media_event, &code, ¶m1, ¶m2, 50); + todo_wine ok(hr == E_ABORT, "Got hr %#x.\n", hr); + + hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK, + (LONG_PTR)&filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n"); + + hr = IMediaControl_Stop(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n"); + + hr = IMediaControl_Pause(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n"); + + hr = IMediaControl_Run(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + + hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK, + (LONG_PTR)&filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n"); + + hr = IMediaEventEx_GetEvent(media_event, &code, ¶m1, ¶m2, 50); + todo_wine ok(hr == E_ABORT, "Got hr %#x.\n", hr); + + todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + + hr = IMediaEventEx_SetNotifyFlags(media_event, 0); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Stop(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaControl_Run(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK, + (LONG_PTR)&filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaEventEx_SetNotifyFlags(media_event, AM_MEDIAEVENT_NONOTIFY); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + + hr = IMediaControl_Stop(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + IMediaControl_Release(media_control); + IMediaEventEx_Release(media_event); + IMediaEventSink_Release(media_event_sink); + ref = IFilterGraph2_Release(graph); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ok(filter.ref == 1, "Got outstanding refcount %d.\n", filter.ref); + + SysFreeString(status); + DestroyWindow(window); +} + START_TEST(filtergraph) { CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -5172,6 +5301,7 @@ START_TEST(filtergraph) test_add_source_filter(); test_window_threading(); test_autoplug_uyvy(); + test_set_notify_flags();
CoUninitialize(); test_render_with_multithread();
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/quartz/tests/filtergraph.c | 129 ++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+)
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 835a735667a..7d4cfce2628 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -5277,6 +5277,134 @@ static void test_set_notify_flags(void) DestroyWindow(window); }
+#define check_events(a, b, c, d) check_events_(__LINE__, a, b, c, d) +static void check_events_(unsigned int line, IMediaEventEx *media_event, + int expected_ec_complete_count, int expected_ec_status_count, BOOL todo) +{ + int ec_complete_count = 0; + int ec_status_count = 0; + LONG_PTR param1, param2; + HRESULT hr; + LONG code; + for (;;) + { + hr = IMediaEventEx_GetEvent(media_event, &code, ¶m1, ¶m2, 50); + if (hr != S_OK) + break; + if (code == EC_COMPLETE) + ++ec_complete_count; + if (code == EC_STATUS) + ++ec_status_count; + } + ok(hr == E_ABORT, "Got hr %#x.\n", hr); + todo_wine_if(todo) ok_(__FILE__, line)(ec_complete_count == expected_ec_complete_count, + "Expected %d EC_COMPLETE events.\n", expected_ec_complete_count); + ok_(__FILE__, line)(ec_status_count == expected_ec_status_count, + "Expected %d EC_STATUS events.\n", expected_ec_status_count); +} + +static void test_events(void) +{ + IFilterGraph2 *graph = create_graph(); + IMediaEventSink *media_event_sink; + IMediaControl *media_control; + IMediaEventEx *media_event; + struct testfilter filter; + LONG_PTR param1, param2; + HANDLE event; + BSTR status; + HRESULT hr; + ULONG ref; + LONG code; + + status = SysAllocString(L"status"); + + hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEventEx, (void **)&media_event); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEventSink, (void **)&media_event_sink); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + testfilter_init(&filter, NULL, 0); + filter.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl; + filter.misc_flags = AM_FILTER_MISC_FLAGS_IS_RENDERER; + + hr = IFilterGraph2_AddFilter(graph, &filter.IBaseFilter_iface, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaEventEx_GetEventHandle(media_event, (OAEVENT *)&event); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Run(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK, + (LONG_PTR)&filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Stop(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + check_events(media_event, 1, 2, FALSE); + + hr = IMediaControl_Run(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK, + (LONG_PTR)&filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Stop(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaControl_Run(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + check_events(media_event, 0, 2, TRUE); + + hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK, + (LONG_PTR)&filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Stop(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaControl_Pause(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + check_events(media_event, 1, 2, FALSE); + + SetEvent(event); + + hr = IMediaEventEx_GetEvent(media_event, &code, ¶m1, ¶m2, 50); + ok(hr == E_ABORT, "Got hr %#x.\n", hr); + + todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + + hr = IMediaControl_Stop(media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + IMediaControl_Release(media_control); + IMediaEventEx_Release(media_event); + IMediaEventSink_Release(media_event_sink); + ref = IFilterGraph2_Release(graph); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ok(filter.ref == 1, "Got outstanding refcount %d.\n", filter.ref); + + SysFreeString(status); +} + START_TEST(filtergraph) { CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -5302,6 +5430,7 @@ START_TEST(filtergraph) test_window_threading(); test_autoplug_uyvy(); test_set_notify_flags(); + test_events();
CoUninitialize(); test_render_with_multithread();
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=85717
Your paranoid android.
=== w864 (32 bit report) ===
quartz: filtergraph.c:3613: Test failed: Got state 2. filtergraph.c:3614: Test failed: Got state 2.
=== w1064_2qxl (64 bit report) ===
quartz: filtergraph.c:529: Test failed: didn't get EOS filtergraph.c:533: Test failed: expected f4240, got 0 filtergraph.c:3613: Test failed: Got state 2. filtergraph.c:3614: Test failed: Got state 2.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/quartz/filtergraph.c | 29 ++++++++++++++++++----------- dlls/quartz/tests/filtergraph.c | 6 +++--- 2 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 58038829217..8c1cd6232e4 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -5288,15 +5288,22 @@ static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, LONG EventCo TRACE("Process EC_COMPLETE notification\n"); if (++This->EcCompleteCount == This->nRenderers) { - evt.lEventCode = EC_COMPLETE; - evt.lParam1 = S_OK; - evt.lParam2 = 0; - TRACE("Send EC_COMPLETE to app\n"); - EventsQueue_PutEvent(&This->evqueue, &evt); - if (!This->notif.disabled && This->notif.hWnd) - { - TRACE("Send Window message\n"); - PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance); + if (!This->notif.disabled) + { + evt.lEventCode = EC_COMPLETE; + evt.lParam1 = S_OK; + evt.lParam2 = 0; + TRACE("Send EC_COMPLETE to app\n"); + EventsQueue_PutEvent(&This->evqueue, &evt); + if (This->notif.hWnd) + { + TRACE("Send Window message\n"); + PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance); + } + } + else + { + SetEvent(This->evqueue.msg_event); } This->CompletionStatus = EC_COMPLETE; This->got_ec_complete = 1; @@ -5307,13 +5314,13 @@ static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, LONG EventCo { /* FIXME: Not handled yet */ } - else + else if (!This->notif.disabled) { evt.lEventCode = EventCode; evt.lParam1 = EventParam1; evt.lParam2 = EventParam2; EventsQueue_PutEvent(&This->evqueue, &evt); - if (!This->notif.disabled && This->notif.hWnd) + if (This->notif.hWnd) PostMessageW(This->notif.hWnd, This->notif.msg, 0, This->notif.instance); }
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 7d4cfce2628..55c70702e47 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -5207,12 +5207,12 @@ static void test_set_notify_flags(void) hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status); ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
ok(!PeekMessageA(&msg, window, WM_USER, WM_USER, PM_REMOVE), "Window should not be notified.\n");
hr = IMediaEventEx_GetEvent(media_event, &code, ¶m1, ¶m2, 50); - todo_wine ok(hr == E_ABORT, "Got hr %#x.\n", hr); + ok(hr == E_ABORT, "Got hr %#x.\n", hr);
hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK, (LONG_PTR)&filter.IBaseFilter_iface); @@ -5242,7 +5242,7 @@ static void test_set_notify_flags(void) ok(WaitForSingleObject(event, 0) == 0, "Event should be signaled.\n");
hr = IMediaEventEx_GetEvent(media_event, &code, ¶m1, ¶m2, 50); - todo_wine ok(hr == E_ABORT, "Got hr %#x.\n", hr); + ok(hr == E_ABORT, "Got hr %#x.\n", hr);
todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/quartz/filtergraph.c | 14 ++++++++++++++ dlls/quartz/tests/filtergraph.c | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 8c1cd6232e4..32041f09756 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -142,6 +142,17 @@ static BOOL EventsQueue_GetEvent(EventsQueue* omr, Event* evt, LONG msTimeOut) return TRUE; }
+static void EventsQueue_Clear(EventsQueue* omr) +{ + EnterCriticalSection(&omr->msg_crst); + + omr->msg_toget = 0; + omr->msg_tosave = 0; + ResetEvent(omr->msg_event); + + LeaveCriticalSection(&omr->msg_crst); +} + #define MAX_ITF_CACHE_ENTRIES 3 typedef struct _ITF_CACHE_ENTRY { const IID* riid; @@ -4890,6 +4901,9 @@ static HRESULT WINAPI MediaEvent_SetNotifyFlags(IMediaEventEx *iface, LONG lNoNo
This->notif.disabled = lNoNotifyFlags;
+ if (lNoNotifyFlags) + EventsQueue_Clear(&This->evqueue); + return S_OK; }
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 55c70702e47..131e817511f 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -5199,10 +5199,10 @@ static void test_set_notify_flags(void) hr = IMediaEventEx_SetNotifyFlags(media_event, AM_MEDIAEVENT_NONOTIFY); ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
hr = IMediaEventEx_GetEvent(media_event, &code, ¶m1, ¶m2, 50); - todo_wine ok(hr == E_ABORT, "Got hr %#x.\n", hr); + ok(hr == E_ABORT, "Got hr %#x.\n", hr);
hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -5261,7 +5261,7 @@ static void test_set_notify_flags(void) hr = IMediaEventEx_SetNotifyFlags(media_event, AM_MEDIAEVENT_NONOTIFY); ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
hr = IMediaControl_Stop(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=85719
Your paranoid android.
=== w1064 (32 bit report) ===
quartz: filtergraph.c:533: Test failed: expected 524874, got 0
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/quartz/filtergraph.c | 1 + dlls/quartz/tests/filtergraph.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 32041f09756..d00d8898002 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -127,6 +127,7 @@ static BOOL EventsQueue_GetEvent(EventsQueue* omr, Event* evt, LONG msTimeOut)
if (omr->msg_toget == omr->msg_tosave) /* buffer empty ? */ { + ResetEvent(omr->msg_event); LeaveCriticalSection(&omr->msg_crst); return FALSE; } diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 131e817511f..2fa8675bae9 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -5244,7 +5244,7 @@ static void test_set_notify_flags(void) hr = IMediaEventEx_GetEvent(media_event, &code, ¶m1, ¶m2, 50); ok(hr == E_ABORT, "Got hr %#x.\n", hr);
- todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
hr = IMediaEventEx_SetNotifyFlags(media_event, 0); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -5390,7 +5390,7 @@ static void test_events(void) hr = IMediaEventEx_GetEvent(media_event, &code, ¶m1, ¶m2, 50); ok(hr == E_ABORT, "Got hr %#x.\n", hr);
- todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
hr = IMediaControl_Stop(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr);
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/quartz/filtergraph.c | 28 ++++++++++++++++++++++++++++ dlls/quartz/tests/filtergraph.c | 14 +++++++------- 2 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index d00d8898002..8705759c02d 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -154,6 +154,32 @@ static void EventsQueue_Clear(EventsQueue* omr) LeaveCriticalSection(&omr->msg_crst); }
+static void EventsQueue_RemoveEvent(EventsQueue* omr, LONG code) +{ + int write_pos; + int read_pos; + + EnterCriticalSection(&omr->msg_crst); + + write_pos = omr->msg_toget; + read_pos = omr->msg_toget; + while (read_pos != omr->msg_tosave) + { + if (omr->messages[read_pos].lEventCode != code) + { + omr->messages[write_pos] = omr->messages[read_pos]; + write_pos = (write_pos + 1 < omr->ring_buffer_size) ? write_pos + 1 : 0; + } + read_pos = (read_pos + 1 < omr->ring_buffer_size) ? read_pos + 1 : 0; + } + omr->msg_tosave = write_pos; + + if (omr->msg_toget == omr->msg_tosave) + ResetEvent(omr->msg_event); + + LeaveCriticalSection(&omr->msg_crst); +} + #define MAX_ITF_CACHE_ENTRIES 3 typedef struct _ITF_CACHE_ENTRY { const IID* riid; @@ -1760,6 +1786,8 @@ static HRESULT graph_start(struct filter_graph *graph, REFERENCE_TIME stream_sta graph->EcCompleteCount = 0; update_render_count(graph);
+ EventsQueue_RemoveEvent(&graph->evqueue, EC_COMPLETE); + if (graph->defaultclock && !graph->refClock) IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface);
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 2fa8675bae9..ae48d252851 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -5233,7 +5233,7 @@ static void test_set_notify_flags(void) hr = IMediaControl_Run(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n"); + ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
hr = IMediaEventSink_Notify(media_event_sink, EC_COMPLETE, S_OK, (LONG_PTR)&filter.IBaseFilter_iface); @@ -5277,9 +5277,9 @@ static void test_set_notify_flags(void) DestroyWindow(window); }
-#define check_events(a, b, c, d) check_events_(__LINE__, a, b, c, d) +#define check_events(a, b, c) check_events_(__LINE__, a, b, c) static void check_events_(unsigned int line, IMediaEventEx *media_event, - int expected_ec_complete_count, int expected_ec_status_count, BOOL todo) + int expected_ec_complete_count, int expected_ec_status_count) { int ec_complete_count = 0; int ec_status_count = 0; @@ -5297,7 +5297,7 @@ static void check_events_(unsigned int line, IMediaEventEx *media_event, ++ec_status_count; } ok(hr == E_ABORT, "Got hr %#x.\n", hr); - todo_wine_if(todo) ok_(__FILE__, line)(ec_complete_count == expected_ec_complete_count, + ok_(__FILE__, line)(ec_complete_count == expected_ec_complete_count, "Expected %d EC_COMPLETE events.\n", expected_ec_complete_count); ok_(__FILE__, line)(ec_status_count == expected_ec_status_count, "Expected %d EC_STATUS events.\n", expected_ec_status_count); @@ -5350,7 +5350,7 @@ static void test_events(void) hr = IMediaControl_Stop(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr);
- check_events(media_event, 1, 2, FALSE); + check_events(media_event, 1, 2);
hr = IMediaControl_Run(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -5368,7 +5368,7 @@ static void test_events(void) hr = IMediaControl_Run(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr);
- check_events(media_event, 0, 2, TRUE); + check_events(media_event, 0, 2);
hr = IMediaEventSink_Notify(media_event_sink, EC_STATUS, (LONG_PTR)status, (LONG_PTR)status); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -5383,7 +5383,7 @@ static void test_events(void) hr = IMediaControl_Pause(media_control); ok(hr == S_OK, "Got hr %#x.\n", hr);
- check_events(media_event, 1, 2, FALSE); + check_events(media_event, 1, 2);
SetEvent(event);