[PATCH 09/10] mf: Introduce topology_loader_connect_nodes() and topology_loader_connect_direct() helper functions.

Sergio Gómez Del Real sdelreal at codeweavers.com
Sun Jun 14 20:41:57 CDT 2020


Signed-off-by: Sergio Gómez Del Real <sdelreal at codeweavers.com>
---
 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




More information about the wine-devel mailing list