From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/mf/topology_loader.c | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/dlls/mf/topology_loader.c b/dlls/mf/topology_loader.c index 9572a2c5407..857e395cc05 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -327,6 +327,7 @@ static void type_enumerator_release(struct connection_context_type_enumerator *e struct connection_context { MF_TOPOLOGY_TYPE up_node_type; + MF_TOPOLOGY_TYPE down_node_type; struct connection_context_type_enumerator up_types; struct connection_context_type_enumerator down_types; BOOL enable_xvp; @@ -348,6 +349,8 @@ static HRESULT connection_context_init(struct connection_context *context, IMFTo if (FAILED(hr = IMFTopologyNode_GetNodeType(branch->up.node, &context->up_node_type))) return hr; + if (FAILED(hr = IMFTopologyNode_GetNodeType(branch->down.node, &context->down_node_type))) + return hr; if (FAILED(hr = topology_node_get_type_handler(branch->up.node, branch->up.stream, TRUE, &context->up_types.handler))) return hr; @@ -817,6 +820,70 @@ static HRESULT topology_branch_connect_independent_outtypes(IMFTopology *topolog return hr; } +static HRESULT topology_branch_connect_indirect_video(IMFTopology *topology, struct topology_branch *branch, + struct connection_context *context) +{ + IMFMediaTypeHandler *down_handler = context->down_types.handler, *up_handler = context->up_types.handler; + IMFMediaType *up_type = NULL, *down_type = NULL; + HRESULT hr = MF_E_TOPO_CODEC_NOT_FOUND; + UINT i, j; + + TRACE("topology %p, branch %s.\n", topology, debugstr_topology_branch(branch)); + + if (context->down_node_type == MF_TOPOLOGY_OUTPUT_NODE) + { + /* output node media types are not enumerated */ + connection_context_init_down_type_enumeration(context); + down_type = context->down_types.current ? context->down_types.current : context->down_types.index0; + + if (!down_type) + goto done; + + for (j = 0; SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(up_handler, j, &up_type)); j++) + { + hr = topology_branch_connect_indirect(topology, branch, context->up_types.enumerate, up_type, down_type); + IMFMediaType_Release(up_type); + if (SUCCEEDED(hr)) + break; + } + } + else + { + /* media types are enumerated for transforms */ + for (i = 0; SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(down_handler, i, &down_type)); i++) + { + for (j = 0; SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(up_handler, j, &up_type)); j++) + { + hr = topology_branch_connect_indirect(topology, branch, context->up_types.enumerate, up_type, down_type); + IMFMediaType_Release(up_type); + if (SUCCEEDED(hr)) + break; + } + + IMFMediaType_Release(down_type); + + if (SUCCEEDED(hr)) + break; + } + } + + if (FAILED(hr)) + { + for (i = 0; SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(up_handler, i, &up_type)); i++) + { + hr = topology_branch_connect_indirect(topology, branch, context->up_types.enumerate, up_type, NULL); + IMFMediaType_Release(up_type); + if (SUCCEEDED(hr)) + break; + } + if (hr == MF_E_NO_MORE_TYPES) + hr = MF_E_TOPO_CODEC_NOT_FOUND; + } + +done: + return hr; +} + static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_METHOD method, struct topology_branch *branch, struct connection_context *context) { @@ -837,6 +904,9 @@ static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_ME if ((method & MF_CONNECT_ALLOW_DECODER) != MF_CONNECT_ALLOW_DECODER) return hr; + if (context->is_video) + return topology_branch_connect_indirect_video(topology, branch, context); + type_enumerator_reset(&context->up_types); while (SUCCEEDED(hr = type_enumerator_get_next_media_type(&context->up_types, &up_type))) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10009