Module: wine Branch: master Commit: ae3c9e327224e15908acde673b17d650d7a4160d URL: https://gitlab.winehq.org/wine/wine/-/commit/ae3c9e327224e15908acde673b17d65...
Author: Bernhard Kölbl besentv@gmail.com Date: Mon Nov 7 12:29:18 2022 +0100
mf: Set media types for output nodes in the media session.
Instead of the topology loader.
---
dlls/mf/mf_private.h | 1 + dlls/mf/session.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ dlls/mf/tests/mf.c | 4 ---- dlls/mf/topology_loader.c | 29 ++++++++++++++++++++---- 4 files changed, 82 insertions(+), 8 deletions(-)
diff --git a/dlls/mf/mf_private.h b/dlls/mf/mf_private.h index bd1d6c7537b..69923154b79 100644 --- a/dlls/mf/mf_private.h +++ b/dlls/mf/mf_private.h @@ -117,3 +117,4 @@ extern BOOL mf_is_sample_copier_transform(IMFTransform *transform) DECLSPEC_HIDD extern BOOL mf_is_sar_sink(IMFMediaSink *sink) DECLSPEC_HIDDEN; extern HRESULT topology_node_get_object(IMFTopologyNode *node, REFIID riid, void **obj) DECLSPEC_HIDDEN; extern HRESULT topology_node_get_type_handler(IMFTopologyNode *node, DWORD stream, BOOL output, IMFMediaTypeHandler **handler) DECLSPEC_HIDDEN; +extern HRESULT topology_node_init_media_type(IMFTopologyNode *node, DWORD stream, BOOL output, IMFMediaType **type) DECLSPEC_HIDDEN; diff --git a/dlls/mf/session.c b/dlls/mf/session.c index a20d411f17a..b2371763150 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -596,6 +596,60 @@ static HRESULT session_bind_output_nodes(IMFTopology *topology) return hr; }
+static HRESULT session_init_media_types(IMFTopology *topology) +{ + MF_TOPOLOGY_TYPE node_type; + WORD node_count, i, j; + IMFTopologyNode *node; + IMFMediaType *type; + DWORD input_count; + HRESULT hr; + + if (FAILED(hr = IMFTopology_GetNodeCount(topology, &node_count))) + return hr; + + for (i = 0; i < node_count; ++i) + { + if (FAILED(hr = IMFTopology_GetNode(topology, i, &node))) + break; + + if (FAILED(hr = IMFTopologyNode_GetInputCount(node, &input_count)) + || FAILED(hr = IMFTopologyNode_GetNodeType(node, &node_type)) + || node_type != MF_TOPOLOGY_OUTPUT_NODE) + { + IMFTopologyNode_Release(node); + continue; + } + + for (j = 0; j < input_count; ++j) + { + IMFMediaTypeHandler *handler; + IMFTopologyNode *up_node; + DWORD up_output; + + if (SUCCEEDED(hr = IMFTopologyNode_GetInput(node, j, &up_node, &up_output))) + { + hr = topology_node_init_media_type(up_node, up_output, TRUE, &type); + IMFTopologyNode_Release(up_node); + } + if (FAILED(hr)) + break; + + if (SUCCEEDED(hr = topology_node_get_type_handler(node, j, FALSE, &handler))) + { + hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, type); + IMFMediaTypeHandler_Release(handler); + } + + IMFMediaType_Release(type); + } + + IMFTopologyNode_Release(node); + } + + return hr; +} + static void session_set_caps(struct media_session *session, DWORD caps) { DWORD delta = session->caps ^ caps; @@ -1768,6 +1822,8 @@ static void session_set_topology(struct media_session *session, DWORD flags, IMF
if (SUCCEEDED(hr)) hr = IMFTopoLoader_Load(session->topo_loader, topology, &resolved_topology, NULL /* FIXME? */); + if (SUCCEEDED(hr)) + hr = session_init_media_types(resolved_topology);
if (SUCCEEDED(hr)) { diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index ce9a2db55a9..8dd3b35251d 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2263,7 +2263,6 @@ static void test_media_session_events(void) PropVariantClear(&propvar);
ok(handler.enum_count, "got %lu GetMediaTypeByIndex\n", handler.enum_count); - todo_wine ok(handler.set_current_count, "got %lu SetCurrentMediaType\n", handler.set_current_count); handler.enum_count = handler.set_current_count = 0;
@@ -2342,7 +2341,6 @@ static void test_media_session_events(void) PropVariantClear(&propvar);
ok(!handler.enum_count, "got %lu GetMediaTypeByIndex\n", handler.enum_count); - todo_wine ok(handler.set_current_count, "got %lu SetCurrentMediaType\n", handler.set_current_count); handler.enum_count = handler.set_current_count = 0;
@@ -3431,8 +3429,6 @@ todo_wine { ok(handler.enum_count, "got %lu GetMediaTypeByIndex\n", handler.enum_count); else ok(!handler.enum_count, "got %lu GetMediaTypeByIndex\n", handler.enum_count); - - todo_wine_if(test->flags & LOADER_NO_CURRENT_OUTPUT) ok(!handler.set_current_count, "got %lu SetCurrentMediaType\n", handler.set_current_count);
if (handler.current_type) diff --git a/dlls/mf/topology_loader.c b/dlls/mf/topology_loader.c index 273d96a81ba..6b6d39d76d1 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -335,7 +335,7 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC return hr; }
-static HRESULT topology_branch_get_current_type(IMFMediaTypeHandler *handler, IMFMediaType **type) +static HRESULT get_first_supported_media_type(IMFMediaTypeHandler *handler, IMFMediaType **type) { IMFMediaType *media_type; HRESULT hr; @@ -359,12 +359,28 @@ static HRESULT topology_branch_get_current_type(IMFMediaTypeHandler *handler, IM return hr; }
+HRESULT topology_node_init_media_type(IMFTopologyNode *node, DWORD stream, BOOL output, IMFMediaType **type) +{ + IMFMediaTypeHandler *handler; + HRESULT hr; + + if (SUCCEEDED(hr = topology_node_get_type_handler(node, stream, output, &handler))) + { + if (SUCCEEDED(hr = get_first_supported_media_type(handler, type))) + hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, *type); + IMFMediaTypeHandler_Release(handler); + } + + return hr; +} + static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_METHOD method_mask, struct topology_branch *branch, IMFMediaType *up_type) { IMFMediaTypeHandler *down_handler; IMFMediaType *down_type = NULL; MF_CONNECT_METHOD method; + MF_TOPOLOGY_TYPE type; DWORD flags; HRESULT hr;
@@ -377,7 +393,7 @@ static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_ME if (FAILED(hr = topology_node_get_type_handler(branch->down.node, branch->down.stream, FALSE, &down_handler))) return hr;
- if (SUCCEEDED(hr = topology_branch_get_current_type(down_handler, &down_type)) + if (SUCCEEDED(hr = get_first_supported_media_type(down_handler, &down_type)) && IMFMediaType_IsEqual(up_type, down_type, &flags) == S_OK) { TRACE("Connecting branch %s with current type %p.\n", debugstr_topology_branch(branch), up_type); @@ -385,11 +401,16 @@ static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_ME goto done; }
- if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(down_handler, up_type, NULL)) - && SUCCEEDED(hr = IMFMediaTypeHandler_SetCurrentMediaType(down_handler, up_type))) + if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(down_handler, up_type, NULL))) { TRACE("Connected branch %s with upstream type %p.\n", debugstr_topology_branch(branch), up_type); + + if (SUCCEEDED(IMFTopologyNode_GetNodeType(branch->down.node, &type)) && type == MF_TOPOLOGY_TRANSFORM_NODE + && FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(down_handler, up_type))) + WARN("Failed to set transform node media type, hr %#lx\n", hr); + hr = IMFTopologyNode_ConnectOutput(branch->up.node, branch->up.stream, branch->down.node, branch->down.stream); + goto done; }