From: "Sergio Gómez Del Real" Subject: [PATCH 09/10] mf: Introduce topology_loader_connect_nodes() and topology_loader_connect_direct() helper functions. Message-Id: <20200615014158.6836-9-sdelreal@codeweavers.com> Date: Sun, 14 Jun 2020 20:41:57 -0500 In-Reply-To: <20200615014158.6836-1-sdelreal@codeweavers.com> References: <20200615014158.6836-1-sdelreal@codeweavers.com> Signed-off-by: Sergio Gómez Del Real --- dlls/mf/topology.c | 111 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 5 deletions(-) diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index bb8b9de267..7aaffaf807 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -2016,6 +2016,107 @@ static HRESULT topology_loader_clone_node(struct topoloader_context *context, IM return hr; } +static HRESULT topology_loader_is_mediatype_compatible_with_sink(IMFMediaTypeHandler *sink_mediatype_handler, IMFMediaType *mediatype) +{ + IMFMediaType *sink_mediatype; + HRESULT hr; + + if (FAILED(hr = IMFMediaTypeHandler_GetCurrentMediaType(sink_mediatype_handler, &sink_mediatype))) + hr = IMFMediaTypeHandler_GetMediaTypeByIndex(sink_mediatype_handler, 0, &sink_mediatype); + + if (SUCCEEDED(hr)) + { + DWORD flags; + + if (SUCCEEDED(hr = IMFMediaType_IsEqual(mediatype, sink_mediatype, &flags))) + if (!(flags & MF_MEDIATYPE_EQUAL_FORMAT_DATA)) + hr = MF_E_INVALIDMEDIATYPE; + + IMFMediaType_Release(sink_mediatype); + } + + return hr; +} + +static HRESULT topology_loader_connect_direct(IMFTopologyNode *upstream_node, unsigned int output_index, + IMFTopologyNode *downstream_node, unsigned int input_index, IMFMediaType *output_type) +{ + MF_TOPOLOGY_TYPE node_type; + HRESULT hr; + + IMFTopologyNode_GetNodeType(downstream_node, &node_type); + + if (node_type == MF_TOPOLOGY_TRANSFORM_NODE) + { + IMFTransform *mft; + + if (SUCCEEDED(hr = IMFTopologyNode_GetObject(downstream_node, (IUnknown **)&mft))) + { + hr = IMFTransform_SetInputType(mft, input_index, output_type, 0); + IMFTransform_Release(mft); + } + } + else if (node_type == MF_TOPOLOGY_OUTPUT_NODE) + { + IMFMediaTypeHandler *mediatype_handler; + IMFStreamSink *sink; + + if (SUCCEEDED(hr = IMFTopologyNode_GetObject(downstream_node, (IUnknown **)&sink))) + { + if (SUCCEEDED(hr = IMFStreamSink_GetMediaTypeHandler(sink, &mediatype_handler))) + { + if (SUCCEEDED(hr = topology_loader_is_mediatype_compatible_with_sink(mediatype_handler, output_type))) + IMFMediaTypeHandler_SetCurrentMediaType(mediatype_handler, output_type); + IMFMediaTypeHandler_Release(mediatype_handler); + } + IMFStreamSink_Release(sink); + } + } + else if (node_type == MF_TOPOLOGY_TEE_NODE) + { + FIXME("Tee nodes are not supported.\n"); + hr = MF_E_INVALIDTYPE; + } + else + { + WARN("Unexpected node type %d.\n", node_type); + hr = MF_E_INVALIDTYPE; + } + + if (SUCCEEDED(hr)) + hr = IMFTopologyNode_ConnectOutput(upstream_node, output_index, downstream_node, input_index); + + return hr; +} + +static HRESULT topology_loader_connect_nodes(struct topoloader_context *context, IMFTopologyNode *upstream_node, unsigned int output_index, + IMFTopologyNode *downstream_node, unsigned int input_index, IMFMediaType *output_type, UINT32 connect_method) +{ + HRESULT hr; + GUID major; + + if (FAILED(hr = IMFMediaType_GetMajorType(output_type, &major))) + goto out; + + /* always try first a direct connection */ + if (FAILED(hr = topology_loader_connect_direct(upstream_node, output_index, downstream_node, input_index, output_type)) + && connect_method != MF_CONNECT_DIRECT) + { + switch (connect_method) + { + case MF_CONNECT_ALLOW_CONVERTER: + hr = S_OK; + break; + case MF_CONNECT_ALLOW_DECODER: + hr = S_OK; + break; + } + } + +out: + return hr; +} + static HRESULT topology_loader_connect_source(struct topoloader_context *context, IMFTopologyNode *source_node, IMFTopologyNode *downstream_node, unsigned int input_index) { @@ -2081,8 +2182,8 @@ static HRESULT topology_loader_connect_source(struct topoloader_context *context for (i = 0; i < num_media_types; i++) { IMFMediaTypeHandler_SetCurrentMediaType(mth_src, src_mediatypes[i]); - hr = S_OK; - goto out; + if (SUCCEEDED(hr = topology_loader_connect_nodes(context, source_node, 0, downstream_node, input_index, src_mediatypes[i], method))) + goto out; } } } @@ -2093,8 +2194,8 @@ static HRESULT topology_loader_connect_source(struct topoloader_context *context for (method = MF_CONNECT_DIRECT; method < MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES; method++) { IMFMediaTypeHandler_SetCurrentMediaType(mth_src, src_mediatypes[i]); - hr = S_OK; - goto out; + if (SUCCEEDED(hr = topology_loader_connect_nodes(context, source_node, 0, downstream_node, input_index, src_mediatypes[i], method))) + goto out; } } } @@ -2124,7 +2225,7 @@ static HRESULT topology_loader_connect_transform(struct topoloader_context *cont i = 0; while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, output_index, i++, &mediatype))) { - hr = S_OK; + hr = topology_loader_connect_nodes(context, transform_node, output_index, downstream_node, input_index, mediatype, method); IMFMediaType_Release(mediatype); -- 2.17.1