diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c index 92f0ff04fab..bb21ccdd25a 100644 --- a/dlls/mf/evr.c +++ b/dlls/mf/evr.c @@ -34,8 +34,10 @@ struct video_renderer IMFMediaSink IMFMediaSink_iface; IMFMediaSinkPreroll IMFMediaSinkPreroll_iface; IMFVideoRenderer IMFVideoRenderer_iface; + IMFMediaEventGenerator IMFMediaEventGenerator_iface; LONG refcount; + IMFMediaEventQueue *event_queue; IMFTransform *mixer; IMFVideoPresenter *presenter; unsigned int flags; @@ -57,6 +59,11 @@ static struct video_renderer *impl_from_IMFVideoRenderer(IMFVideoRenderer *iface return CONTAINING_RECORD(iface, struct video_renderer, IMFVideoRenderer_iface); } +static struct video_renderer *impl_from_IMFMediaEventGenerator(IMFMediaEventGenerator *iface) +{ + return CONTAINING_RECORD(iface, struct video_renderer, IMFMediaEventGenerator_iface); +} + static HRESULT WINAPI video_renderer_sink_QueryInterface(IMFMediaSink *iface, REFIID riid, void **obj) { struct video_renderer *renderer = impl_from_IMFMediaSink(iface); @@ -76,6 +83,10 @@ static HRESULT WINAPI video_renderer_sink_QueryInterface(IMFMediaSink *iface, RE { *obj = &renderer->IMFVideoRenderer_iface; } + else if (IsEqualIID(riid, &IID_IMFMediaEventGenerator)) + { + *obj = &renderer->IMFMediaEventGenerator_iface; + } else { WARN("Unsupported interface %s.\n", debugstr_guid(riid)); @@ -105,6 +116,8 @@ static ULONG WINAPI video_renderer_sink_Release(IMFMediaSink *iface) if (!refcount) { + if (renderer->event_queue) + IMFMediaEventQueue_Release(renderer->event_queue); if (renderer->mixer) IMFTransform_Release(renderer->mixer); if (renderer->presenter) @@ -193,6 +206,7 @@ static HRESULT WINAPI video_renderer_sink_Shutdown(IMFMediaSink *iface) EnterCriticalSection(&renderer->cs); renderer->flags |= EVR_SHUT_DOWN; + IMFMediaEventQueue_Shutdown(renderer->event_queue); LeaveCriticalSection(&renderer->cs); return S_OK; @@ -281,6 +295,74 @@ static const IMFVideoRendererVtbl video_renderer_vtbl = video_renderer_InitializeRenderer, }; +static HRESULT WINAPI video_renderer_events_QueryInterface(IMFMediaEventGenerator *iface, REFIID riid, void **obj) +{ + struct video_renderer *renderer = impl_from_IMFMediaEventGenerator(iface); + return IMFMediaSink_QueryInterface(&renderer->IMFMediaSink_iface, riid, obj); +} + +static ULONG WINAPI video_renderer_events_AddRef(IMFMediaEventGenerator *iface) +{ + struct video_renderer *renderer = impl_from_IMFMediaEventGenerator(iface); + return IMFMediaSink_AddRef(&renderer->IMFMediaSink_iface); +} + +static ULONG WINAPI video_renderer_events_Release(IMFMediaEventGenerator *iface) +{ + struct video_renderer *renderer = impl_from_IMFMediaEventGenerator(iface); + return IMFMediaSink_Release(&renderer->IMFMediaSink_iface); +} + +static HRESULT WINAPI video_renderer_events_GetEvent(IMFMediaEventGenerator *iface, DWORD flags, IMFMediaEvent **event) +{ + struct video_renderer *renderer = impl_from_IMFMediaEventGenerator(iface); + + TRACE("%p, %#x, %p.\n", iface, flags, event); + + return IMFMediaEventQueue_GetEvent(renderer->event_queue, flags, event); +} + +static HRESULT WINAPI video_renderer_events_BeginGetEvent(IMFMediaEventGenerator *iface, IMFAsyncCallback *callback, + IUnknown *state) +{ + struct video_renderer *renderer = impl_from_IMFMediaEventGenerator(iface); + + TRACE("%p, %p, %p.\n", iface, callback, state); + + return IMFMediaEventQueue_BeginGetEvent(renderer->event_queue, callback, state); +} + +static HRESULT WINAPI video_renderer_events_EndGetEvent(IMFMediaEventGenerator *iface, IMFAsyncResult *result, + IMFMediaEvent **event) +{ + struct video_renderer *renderer = impl_from_IMFMediaEventGenerator(iface); + + TRACE("%p, %p, %p.\n", iface, result, event); + + return IMFMediaEventQueue_EndGetEvent(renderer->event_queue, result, event); +} + +static HRESULT WINAPI video_renderer_events_QueueEvent(IMFMediaEventGenerator *iface, MediaEventType event_type, + REFGUID ext_type, HRESULT hr, const PROPVARIANT *value) +{ + struct video_renderer *renderer = impl_from_IMFMediaEventGenerator(iface); + + TRACE("%p, %u, %s, %#x, %p.\n", iface, event_type, debugstr_guid(ext_type), hr, value); + + return IMFMediaEventQueue_QueueEventParamVar(renderer->event_queue, event_type, ext_type, hr, value); +} + +static const IMFMediaEventGeneratorVtbl video_renderer_events_vtbl = +{ + video_renderer_events_QueryInterface, + video_renderer_events_AddRef, + video_renderer_events_Release, + video_renderer_events_GetEvent, + video_renderer_events_BeginGetEvent, + video_renderer_events_EndGetEvent, + video_renderer_events_QueueEvent, +}; + static HRESULT video_renderer_create_mixer(IMFAttributes *attributes, IMFTransform **out) { unsigned int flags = 0; @@ -340,21 +422,25 @@ static HRESULT evr_create_object(IMFAttributes *attributes, void *user_context, object->IMFMediaSink_iface.lpVtbl = &video_renderer_sink_vtbl; object->IMFMediaSinkPreroll_iface.lpVtbl = &video_renderer_preroll_vtbl; object->IMFVideoRenderer_iface.lpVtbl = &video_renderer_vtbl; + object->IMFMediaEventGenerator_iface.lpVtbl = &video_renderer_events_vtbl; object->refcount = 1; InitializeCriticalSection(&object->cs); + if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) + goto failed; + /* Create mixer and presenter. */ if (FAILED(hr = video_renderer_create_mixer(attributes, &object->mixer))) - goto done; + goto failed; if (FAILED(hr = video_renderer_create_presenter(attributes, &object->presenter))) - goto done; + goto failed; *obj = (IUnknown *)&object->IMFMediaSink_iface; return S_OK; -done: +failed: IMFMediaSink_Release(&object->IMFMediaSink_iface); diff --git a/dlls/mf/main.c b/dlls/mf/main.c index 62dc1813c7b..53264258137 100644 --- a/dlls/mf/main.c +++ b/dlls/mf/main.c @@ -26,8 +26,6 @@ #include "mfidl.h" #include "rpcproxy.h" -#include "mfapi.h" - #include "mf_private.h" #include "wine/debug.h" diff --git a/dlls/mf/mf_private.h b/dlls/mf/mf_private.h index f4356219731..66d970dfce5 100644 --- a/dlls/mf/mf_private.h +++ b/dlls/mf/mf_private.h @@ -18,6 +18,7 @@ #include "mferror.h" #include "mfidl.h" +#include "mfapi.h" #include "wine/heap.h" #include "wine/debug.h" diff --git a/dlls/mf/samplegrabber.c b/dlls/mf/samplegrabber.c index cbf7453d04d..566ee2f2930 100644 --- a/dlls/mf/samplegrabber.c +++ b/dlls/mf/samplegrabber.c @@ -18,7 +18,6 @@ #define COBJMACROS -#include "mfapi.h" #include "mfidl.h" #include "mf_private.h" diff --git a/dlls/mf/session.c b/dlls/mf/session.c index d0365ea8564..e2a6b868caf 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -24,7 +24,6 @@ #include "windef.h" #include "winbase.h" #include "mfidl.h" -#include "mfapi.h" #include "wine/debug.h" #include "wine/heap.h" diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index a66bdcf1ee7..5d9ccc5408d 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -3227,6 +3227,7 @@ todo_wine static void test_evr(void) { + IMFMediaEventGenerator *ev_generator; IMFVideoRenderer *video_renderer; IMFMediaSinkPreroll *preroll; IMFMediaSink *sink, *sink2; @@ -3267,6 +3268,10 @@ static void test_evr(void) ok(hr == S_OK, "Unexpected hr %#x.\n", hr); IMFVideoRenderer_Release(video_renderer); + hr = IMFMediaSink_QueryInterface(sink, &IID_IMFMediaEventGenerator, (void **)&ev_generator); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IMFMediaEventGenerator_Release(ev_generator); + hr = IMFActivate_ShutdownObject(activate); ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index f4cc30a9fc6..abe66c45fd4 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -26,7 +26,6 @@ #undef INITGUID #include -#include "mfapi.h" #include "mfidl.h" #include "wine/debug.h"