From: Bernhard Kölbl besentv@gmail.com
--- dlls/mfmediaengine/main.c | 58 ++++++++++++++++++++++-- dlls/mfmediaengine/tests/mfmediaengine.c | 2 +- 2 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index 63e9a8f07d5..7b28b036911 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -146,6 +146,11 @@ struct media_engine IMFPresentationDescriptor *pd; } presentation; struct + { + IUnknown *video; + BOOL video_optional; + } effects; + struct { LONGLONG pts; SIZE size; @@ -1018,6 +1023,30 @@ static HRESULT media_engine_create_source_node(IMFMediaSource *source, IMFPresen return S_OK; }
+static HRESULT media_engine_create_video_effect(struct media_engine *engine, IMFTopologyNode **node) +{ + HRESULT hr; + + *node = NULL; + + if (!engine->effects.video) + return S_OK; + + if (FAILED(hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, node))) + return hr; + + IMFTopologyNode_SetObject(*node, (IUnknown *)engine->effects.video); + IMFTopologyNode_SetUINT32(*node, &MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE); + + if (engine->effects.video_optional) + IMFTopologyNode_SetUINT32(*node, &MF_TOPONODE_CONNECT_METHOD, MF_CONNECT_AS_OPTIONAL); + + IUnknown_Release(engine->effects.video); + engine->effects.video = NULL; + + return hr; +} + static HRESULT media_engine_create_audio_renderer(struct media_engine *engine, IMFTopologyNode **node) { unsigned int category, role; @@ -1189,7 +1218,7 @@ static HRESULT media_engine_create_topology(struct media_engine *engine, IMFMedi if (SUCCEEDED(hr = MFCreateTopology(&topology))) { IMFTopologyNode *sar_node = NULL, *audio_src = NULL; - IMFTopologyNode *grabber_node = NULL, *video_src = NULL; + IMFTopologyNode *grabber_node = NULL, *video_src = NULL, *video_effect = NULL;
if (engine->flags & MF_MEDIA_ENGINE_REAL_TIME_MODE) IMFTopology_SetUINT32(topology, &MF_LOW_LATENCY, TRUE); @@ -1223,16 +1252,29 @@ static HRESULT media_engine_create_topology(struct media_engine *engine, IMFMedi if (FAILED(hr = media_engine_create_video_renderer(engine, &grabber_node))) WARN("Failed to create video grabber node, hr %#lx.\n", hr);
+ if (FAILED(media_engine_create_video_effect(engine, &video_effect))) + WARN("Failed to create video effect node, hr %#lx.\n", hr); + if (grabber_node && video_src) { IMFTopology_AddNode(topology, video_src); IMFTopology_AddNode(topology, grabber_node); - IMFTopologyNode_ConnectOutput(video_src, 0, grabber_node, 0); + + if (video_effect) + { + IMFTopology_AddNode(topology, video_effect); + IMFTopologyNode_ConnectOutput(video_src, 0, video_effect, 0); + IMFTopologyNode_ConnectOutput(video_effect, 0, grabber_node, 0); + } + else + IMFTopologyNode_ConnectOutput(video_src, 0, grabber_node, 0); }
if (SUCCEEDED(hr)) IMFTopologyNode_GetTopoNodeID(video_src, &engine->video_frame.node_id);
+ if (video_effect) + IMFTopologyNode_Release(video_effect); if (grabber_node) IMFTopologyNode_Release(grabber_node); if (video_src) @@ -2579,9 +2621,17 @@ static HRESULT WINAPI media_engine_IsProtected(IMFMediaEngineEx *iface, BOOL *pr
static HRESULT WINAPI media_engine_InsertVideoEffect(IMFMediaEngineEx *iface, IUnknown *effect, BOOL is_optional) { - FIXME("%p, %p, %d stub.\n", iface, effect, is_optional); + struct media_engine *impl = impl_from_IMFMediaEngineEx(iface); + TRACE("%p, %p, %d.\n", iface, effect, is_optional);
- return E_NOTIMPL; + if (impl->effects.video) + IUnknown_Release(impl->effects.video); + + impl->effects.video = effect; + IUnknown_AddRef(impl->effects.video); + impl->effects.video_optional = is_optional; + + return S_OK; }
static HRESULT WINAPI media_engine_InsertAudioEffect(IMFMediaEngineEx *iface, IUnknown *effect, BOOL is_optional) diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 27c1f017414..16757de99e9 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -1920,7 +1920,7 @@ static void test_video_effect(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaEngineEx_InsertVideoEffect(media_engine_ex, (IUnknown *)&video_effect->IMFTransform_iface, FALSE); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
if (FAILED(hr)) goto done;