Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/evr.c | 9 ++------- dlls/mf/main.c | 3 ++- dlls/mf/sar.c | 9 ++------- 3 files changed, 6 insertions(+), 15 deletions(-)
diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c index 64944673d5a..e0ab44f8b05 100644 --- a/dlls/mf/evr.c +++ b/dlls/mf/evr.c @@ -258,15 +258,10 @@ static void evr_shutdown_object(void *user_context, IUnknown *obj) } }
-static void evr_free_private(void *user_context) -{ -} - static const struct activate_funcs evr_activate_funcs = { - evr_create_object, - evr_shutdown_object, - evr_free_private, + .create_object = evr_create_object, + .shutdown_object = evr_shutdown_object, };
/*********************************************************************** diff --git a/dlls/mf/main.c b/dlls/mf/main.c index 8656c6cddf2..62dc1813c7b 100644 --- a/dlls/mf/main.c +++ b/dlls/mf/main.c @@ -91,7 +91,8 @@ static ULONG WINAPI activate_object_Release(IMFActivate *iface)
if (!refcount) { - activate->funcs->free_private(activate->context); + if (activate->funcs->free_private) + activate->funcs->free_private(activate->context); if (activate->object) IUnknown_Release(activate->object); IMFAttributes_Release(activate->attributes); diff --git a/dlls/mf/sar.c b/dlls/mf/sar.c index 8a27c0658c3..6f1f1bd834e 100644 --- a/dlls/mf/sar.c +++ b/dlls/mf/sar.c @@ -1891,15 +1891,10 @@ static void sar_shutdown_object(void *user_context, IUnknown *obj) } }
-static void sar_free_private(void *user_context) -{ -} - static const struct activate_funcs sar_activate_funcs = { - sar_create_object, - sar_shutdown_object, - sar_free_private, + .create_object = sar_create_object, + .shutdown_object = sar_shutdown_object, };
/***********************************************************************
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/Makefile.in | 2 +- dlls/mf/evr.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/Makefile.in b/dlls/mf/Makefile.in index 1d2bfc8a782..b64cdb4a64d 100644 --- a/dlls/mf/Makefile.in +++ b/dlls/mf/Makefile.in @@ -1,6 +1,6 @@ MODULE = mf.dll IMPORTLIB = mf -IMPORTS = advapi32 mfplat ole32 uuid mfuuid +IMPORTS = advapi32 mfplat ole32 uuid mfuuid strmiids
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c index e0ab44f8b05..4166c1dd3e4 100644 --- a/dlls/mf/evr.c +++ b/dlls/mf/evr.c @@ -19,6 +19,7 @@ #define COBJMACROS
#include "mf_private.h" +#include "uuids.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
@@ -32,6 +33,8 @@ struct video_renderer IMFMediaSink IMFMediaSink_iface; IMFMediaSinkPreroll IMFMediaSinkPreroll_iface; LONG refcount; + + IMFTransform *mixer; unsigned int flags; CRITICAL_SECTION cs; }; @@ -90,6 +93,8 @@ static ULONG WINAPI video_renderer_sink_Release(IMFMediaSink *iface)
if (!refcount) { + if (renderer->mixer) + IMFTransform_Release(renderer->mixer); DeleteCriticalSection(&renderer->cs); heap_free(renderer); } @@ -228,9 +233,33 @@ static const IMFMediaSinkPrerollVtbl video_renderer_preroll_vtbl = video_renderer_preroll_NotifyPreroll, };
+static HRESULT video_renderer_create_mixer(IMFAttributes *attributes, IMFTransform **out) +{ + unsigned int flags = 0; + IMFActivate *activate; + CLSID clsid; + HRESULT hr; + + if (SUCCEEDED(IMFAttributes_GetUnknown(attributes, &MF_ACTIVATE_CUSTOM_VIDEO_MIXER_ACTIVATE, + &IID_IMFActivate, (void **)&activate))) + { + IMFAttributes_GetUINT32(attributes, &MF_ACTIVATE_CUSTOM_VIDEO_MIXER_FLAGS, &flags); + hr = IMFActivate_ActivateObject(activate, &IID_IMFTransform, (void **)out); + IMFActivate_Release(activate); + if (FAILED(hr) && !(flags & MF_ACTIVATE_CUSTOM_MIXER_ALLOWFAIL)) + return hr; + } + + if (FAILED(IMFAttributes_GetGUID(attributes, &MF_ACTIVATE_CUSTOM_VIDEO_MIXER_CLSID, &clsid))) + memcpy(&clsid, &CLSID_MFVideoMixer9, sizeof(clsid)); + + return CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)out); +} + static HRESULT evr_create_object(IMFAttributes *attributes, void *user_context, IUnknown **obj) { struct video_renderer *object; + HRESULT hr;
TRACE("%p, %p, %p.\n", attributes, user_context, obj);
@@ -242,9 +271,19 @@ static HRESULT evr_create_object(IMFAttributes *attributes, void *user_context, object->refcount = 1; InitializeCriticalSection(&object->cs);
+ /* Create mixer. */ + if (FAILED(hr = video_renderer_create_mixer(attributes, &object->mixer))) + goto done; + *obj = (IUnknown *)&object->IMFMediaSink_iface;
return S_OK; + +done: + + IMFMediaSink_Release(&object->IMFMediaSink_iface); + + return hr; }
static void evr_shutdown_object(void *user_context, IUnknown *obj)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/evr.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c index 4166c1dd3e4..c3ee38c8292 100644 --- a/dlls/mf/evr.c +++ b/dlls/mf/evr.c @@ -20,6 +20,7 @@
#include "mf_private.h" #include "uuids.h" +#include "evr.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
@@ -35,6 +36,7 @@ struct video_renderer LONG refcount;
IMFTransform *mixer; + IMFVideoPresenter *presenter; unsigned int flags; CRITICAL_SECTION cs; }; @@ -95,6 +97,8 @@ static ULONG WINAPI video_renderer_sink_Release(IMFMediaSink *iface) { if (renderer->mixer) IMFTransform_Release(renderer->mixer); + if (renderer->presenter) + IMFVideoPresenter_Release(renderer->presenter); DeleteCriticalSection(&renderer->cs); heap_free(renderer); } @@ -256,6 +260,29 @@ static HRESULT video_renderer_create_mixer(IMFAttributes *attributes, IMFTransfo return CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)out); }
+static HRESULT video_renderer_create_presenter(IMFAttributes *attributes, IMFVideoPresenter **out) +{ + unsigned int flags = 0; + IMFActivate *activate; + CLSID clsid; + HRESULT hr; + + if (SUCCEEDED(IMFAttributes_GetUnknown(attributes, &MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE, + &IID_IMFActivate, (void **)&activate))) + { + IMFAttributes_GetUINT32(attributes, &MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS, &flags); + hr = IMFActivate_ActivateObject(activate, &IID_IMFVideoPresenter, (void **)out); + IMFActivate_Release(activate); + if (FAILED(hr) && !(flags & MF_ACTIVATE_CUSTOM_PRESENTER_ALLOWFAIL)) + return hr; + } + + if (FAILED(IMFAttributes_GetGUID(attributes, &MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID, &clsid))) + memcpy(&clsid, &CLSID_MFVideoPresenter9, sizeof(clsid)); + + return CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IMFVideoPresenter, (void **)out); +} + static HRESULT evr_create_object(IMFAttributes *attributes, void *user_context, IUnknown **obj) { struct video_renderer *object; @@ -271,10 +298,13 @@ static HRESULT evr_create_object(IMFAttributes *attributes, void *user_context, object->refcount = 1; InitializeCriticalSection(&object->cs);
- /* Create mixer. */ + /* Create mixer and presenter. */ if (FAILED(hr = video_renderer_create_mixer(attributes, &object->mixer))) goto done;
+ if (FAILED(hr = video_renderer_create_presenter(attributes, &object->presenter))) + goto done; + *obj = (IUnknown *)&object->IMFMediaSink_iface;
return S_OK;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/evr.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ dlls/mf/tests/mf.c | 6 ++++++ 2 files changed, 51 insertions(+)
diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c index c3ee38c8292..92f0ff04fab 100644 --- a/dlls/mf/evr.c +++ b/dlls/mf/evr.c @@ -33,6 +33,7 @@ struct video_renderer { IMFMediaSink IMFMediaSink_iface; IMFMediaSinkPreroll IMFMediaSinkPreroll_iface; + IMFVideoRenderer IMFVideoRenderer_iface; LONG refcount;
IMFTransform *mixer; @@ -51,6 +52,11 @@ static struct video_renderer *impl_from_IMFMediaSinkPreroll(IMFMediaSinkPreroll return CONTAINING_RECORD(iface, struct video_renderer, IMFMediaSinkPreroll_iface); }
+static struct video_renderer *impl_from_IMFVideoRenderer(IMFVideoRenderer *iface) +{ + return CONTAINING_RECORD(iface, struct video_renderer, IMFVideoRenderer_iface); +} + static HRESULT WINAPI video_renderer_sink_QueryInterface(IMFMediaSink *iface, REFIID riid, void **obj) { struct video_renderer *renderer = impl_from_IMFMediaSink(iface); @@ -66,6 +72,10 @@ static HRESULT WINAPI video_renderer_sink_QueryInterface(IMFMediaSink *iface, RE { *obj = &renderer->IMFMediaSinkPreroll_iface; } + else if (IsEqualIID(riid, &IID_IMFVideoRenderer)) + { + *obj = &renderer->IMFVideoRenderer_iface; + } else { WARN("Unsupported interface %s.\n", debugstr_guid(riid)); @@ -237,6 +247,40 @@ static const IMFMediaSinkPrerollVtbl video_renderer_preroll_vtbl = video_renderer_preroll_NotifyPreroll, };
+static HRESULT WINAPI video_renderer_QueryInterface(IMFVideoRenderer *iface, REFIID riid, void **obj) +{ + struct video_renderer *renderer = impl_from_IMFVideoRenderer(iface); + return IMFMediaSink_QueryInterface(&renderer->IMFMediaSink_iface, riid, obj); +} + +static ULONG WINAPI video_renderer_AddRef(IMFVideoRenderer *iface) +{ + struct video_renderer *renderer = impl_from_IMFVideoRenderer(iface); + return IMFMediaSink_AddRef(&renderer->IMFMediaSink_iface); +} + +static ULONG WINAPI video_renderer_Release(IMFVideoRenderer *iface) +{ + struct video_renderer *renderer = impl_from_IMFVideoRenderer(iface); + return IMFMediaSink_Release(&renderer->IMFMediaSink_iface); +} + +static HRESULT WINAPI video_renderer_InitializeRenderer(IMFVideoRenderer *iface, IMFTransform *mixer, + IMFVideoPresenter *presenter) +{ + FIXME("%p, %p, %p.\n", iface, mixer, presenter); + + return E_NOTIMPL; +} + +static const IMFVideoRendererVtbl video_renderer_vtbl = +{ + video_renderer_QueryInterface, + video_renderer_AddRef, + video_renderer_Release, + video_renderer_InitializeRenderer, +}; + static HRESULT video_renderer_create_mixer(IMFAttributes *attributes, IMFTransform **out) { unsigned int flags = 0; @@ -295,6 +339,7 @@ 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->refcount = 1; InitializeCriticalSection(&object->cs);
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 691734aa9a9..a66bdcf1ee7 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -41,6 +41,7 @@ DEFINE_GUID(MFVideoFormat_ABGR32, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00, #include "initguid.h" #include "mmdeviceapi.h" #include "audioclient.h" +#include "evr.h"
#include "wine/test.h"
@@ -3226,6 +3227,7 @@ todo_wine
static void test_evr(void) { + IMFVideoRenderer *video_renderer; IMFMediaSinkPreroll *preroll; IMFMediaSink *sink, *sink2; IMFActivate *activate; @@ -3261,6 +3263,10 @@ static void test_evr(void) ok(hr == S_OK, "Unexpected hr %#x.\n", hr); IMFMediaSinkPreroll_Release(preroll);
+ hr = IMFMediaSink_QueryInterface(sink, &IID_IMFVideoRenderer, (void **)&video_renderer); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IMFVideoRenderer_Release(video_renderer); + hr = IMFActivate_ShutdownObject(activate); ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/evr.c | 92 +++++++++++++++++++++++++++++++++++++++-- dlls/mf/main.c | 2 - dlls/mf/mf_private.h | 1 + dlls/mf/samplegrabber.c | 1 - dlls/mf/session.c | 1 - dlls/mf/tests/mf.c | 5 +++ dlls/mf/topology.c | 1 - 7 files changed, 95 insertions(+), 8 deletions(-)
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 <guiddef.h> -#include "mfapi.h" #include "mfidl.h"
#include "wine/debug.h"