Signed-off-by: Anton Baskanov baskanov@gmail.com --- v2: Pass BSTR instead of a C string. --- dlls/quartz/tests/filtergraph.c | 137 ++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+)
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index e4b72958e10..11841f65e61 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -5148,6 +5148,142 @@ 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) +{ + static const WNDCLASSA class = + { + .lpfnWndProc = DefWindowProcA, + .lpszClassName = "quartz_test_window", + }; + 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; + + RegisterClassA(&class); + window = CreateWindowA("quartz_test_window", 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); + UnregisterClassA("quartz_test_window", GetModuleHandleA(NULL)); +} + START_TEST(filtergraph) { CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -5172,6 +5308,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/filtergraph.c | 49 +++++++++++++++++++++++++-------- dlls/quartz/tests/filtergraph.c | 16 +++++------ 2 files changed, 46 insertions(+), 19 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 58038829217..1ccb4f1b3d4 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; @@ -1748,6 +1759,9 @@ static HRESULT graph_start(struct filter_graph *graph, REFERENCE_TIME stream_sta graph->EcCompleteCount = 0; update_render_count(graph);
+ if (graph->notif.disabled) + ResetEvent(graph->evqueue.msg_event); + if (graph->defaultclock && !graph->refClock) IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface);
@@ -4794,6 +4808,9 @@ static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface, LONG *lEventCode return S_OK; }
+ if (This->notif.disabled) + ResetEvent(This->evqueue.msg_event); + *lEventCode = 0; return E_ABORT; } @@ -4890,6 +4907,9 @@ static HRESULT WINAPI MediaEvent_SetNotifyFlags(IMediaEventEx *iface, LONG lNoNo
This->notif.disabled = lNoNotifyFlags;
+ if (lNoNotifyFlags) + EventsQueue_Clear(&This->evqueue); + return S_OK; }
@@ -5288,15 +5308,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 +5334,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 11841f65e61..0bd48c10faf 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -5205,20 +5205,20 @@ 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);
- 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); @@ -5239,7 +5239,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); @@ -5248,9 +5248,9 @@ 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"); + 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); @@ -5267,7 +5267,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);
On 2/14/21 9:13 AM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/quartz/filtergraph.c | 49 +++++++++++++++++++++++++-------- dlls/quartz/tests/filtergraph.c | 16 +++++------ 2 files changed, 46 insertions(+), 19 deletions(-)
This patch does a few things at once, from what I can see:
* don't queue an event if events are disabled, * clear existing events when disabling events, * reset the event when starting, * reset the event when an event is cleared.
Can it be split up accordingly?
Also:
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 58038829217..1ccb4f1b3d4 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; @@ -1748,6 +1759,9 @@ static HRESULT graph_start(struct filter_graph *graph, REFERENCE_TIME stream_sta graph->EcCompleteCount = 0; update_render_count(graph);
- if (graph->notif.disabled)
 ResetEvent(graph->evqueue.msg_event);- if (graph->defaultclock && !graph->refClock) IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface);
 @@ -4794,6 +4808,9 @@ static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface, LONG *lEventCode return S_OK; }
- if (This->notif.disabled)
 ResetEvent(This->evqueue.msg_event);- *lEventCode = 0; return E_ABORT;
 }
I have a suspicion that if you manually set the event while there are no events in the queue and event delivery is enabled, then call IMediaEvent::GetEvent(), that it will reset the event. I.e. that what we really should do here is change the control flow in EventsQueue_GetEvent() a bit.
@@ -4890,6 +4907,9 @@ static HRESULT WINAPI MediaEvent_SetNotifyFlags(IMediaEventEx *iface, LONG lNoNo
This->notif.disabled = lNoNotifyFlags;
- if (lNoNotifyFlags)
 EventsQueue_Clear(&This->evqueue);- return S_OK;
 }
@@ -5288,15 +5308,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 +5334,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 11841f65e61..0bd48c10faf 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -5205,20 +5205,20 @@ 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);
- 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);
@@ -5239,7 +5239,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);
@@ -5248,9 +5248,9 @@ 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");
 
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);
@@ -5267,7 +5267,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);
One more thing that was nagging me, that I just had to check...
On 2/14/21 9:13 AM, Anton Baskanov wrote:
@@ -1748,6 +1759,9 @@ static HRESULT graph_start(struct filter_graph *graph, REFERENCE_TIME stream_sta graph->EcCompleteCount = 0; update_render_count(graph);
- if (graph->notif.disabled)
 ResetEvent(graph->evqueue.msg_event);- if (graph->defaultclock && !graph->refClock) IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface);
 
It seems that if you queue EC_COMPLETE, then stop and restart the graph, that the event gets lost. So this should probably not be keyed on "disabled", and it should probably also clear existing events (just EC_COMPLETE, though, or all of them?)
That deserves tests, of course, and should probably be part of a separate test function [not test_ec_complete(), which is focused on which filters are considered renderers, or test_set_notify_flags(), which is focused on what happens when events are disabled.]
On 2/14/21 9:13 AM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
v2: Pass BSTR instead of a C string.
dlls/quartz/tests/filtergraph.c | 137 ++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+)
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index e4b72958e10..11841f65e61 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -5148,6 +5148,142 @@ 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) +{
- static const WNDCLASSA class =
 - {
 .lpfnWndProc = DefWindowProcA,.lpszClassName = "quartz_test_window",- };
 - 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;
 - RegisterClassA(&class);
 - window = CreateWindowA("quartz_test_window", NULL, WS_OVERLAPPEDWINDOW,
 50, 50, 150, 150, NULL, NULL, NULL, NULL);
You're not doing anything that requires a custom class, so I think you can just use "static" instead, or perhaps a message window.
- 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);
 - UnregisterClassA("quartz_test_window", GetModuleHandleA(NULL));
 +}
START_TEST(filtergraph) { CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -5172,6 +5308,7 @@ START_TEST(filtergraph) test_add_source_filter(); test_window_threading(); test_autoplug_uyvy();
test_set_notify_flags();
CoUninitialize(); test_render_with_multithread();