[PATCH 06/10] mf: Introduce topology_loader_resolve_nodes() for use by _Load().

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


Signed-off-by: Sergio Gómez Del Real <sdelreal at codeweavers.com>
---
 dlls/mf/tests/mf.c |  5 ---
 dlls/mf/topology.c | 96 +++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 90 insertions(+), 11 deletions(-)

diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index cfee1ca0ae..6d0a3176ac 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -1874,20 +1874,15 @@ todo_wine
     hr = E_FAIL;
     hr = IMFTopology_GetCount(full_topology, &count);
     ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
-todo_wine
     ok(count == 1, "Unexpected count %u.\n", count);
 
     hr = IMFTopology_GetItemByIndex(full_topology, 0, &guid, NULL);
-todo_wine {
     ok(hr == S_OK, "Failed to get attribute key, hr %#x.\n", hr);
     ok(IsEqualGUID(&guid, &MF_TOPOLOGY_RESOLUTION_STATUS), "Unexpected key %s.\n", wine_dbgstr_guid(&guid));
-}
     value = 0xdeadbeef;
     hr = IMFTopology_GetUINT32(full_topology, &MF_TOPOLOGY_RESOLUTION_STATUS, &value);
-todo_wine {
     ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
     ok(value == MF_TOPOLOGY_RESOLUTION_SUCCEEDED, "Unexpected value %#x.\n", value);
-}
 
     IMFTopology_Release(full_topology);
   
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
index 03aa967d9e..c51a739aa8 100644
--- a/dlls/mf/topology.c
+++ b/dlls/mf/topology.c
@@ -1965,6 +1965,26 @@ static int topology_loader_get_branch_depth(IMFTopologyNode *node, int level)
     return max_level;
 }
 
+static IMFTopologyNode *topology_loader_get_node_for_marker(struct topoloader_context *context, TOPOID *id)
+{
+    IMFTopologyNode *node;
+    unsigned short i = 0;
+    unsigned int value;
+
+    while (SUCCEEDED(IMFTopology_GetNode(context->output_topology, i++, &node)))
+    {
+        if (SUCCEEDED(IMFTopologyNode_GetUINT32(node, &context->key, &value)) && value == context->marker)
+        {
+            IMFTopologyNode_GetTopoNodeID(node, id);
+            return node;
+        }
+        IMFTopologyNode_Release(node);
+    }
+
+    *id = 0;
+    return NULL;
+}
+
 static HRESULT topology_loader_clone_node(struct topoloader_context *context, IMFTopologyNode *node, IMFTopologyNode **ret,
         unsigned int marker)
 {
@@ -1996,8 +2016,62 @@ static HRESULT topology_loader_clone_node(struct topoloader_context *context, IM
     return hr;
 }
 
+static HRESULT topology_loader_resolve_nodes(struct topoloader_context *context)
+{
+    IMFTopologyNode *node, *downstream_node, *orig_node, *orig_downstream_node;
+    MF_TOPOLOGY_TYPE node_type;
+    unsigned int input_index;
+    HRESULT hr = E_FAIL;
+    TOPOID id;
+    int i;
+
+    while ((node = topology_loader_get_node_for_marker(context, &id)))
+    {
+        IMFTopology_GetNodeByID(context->input_topology, id, &orig_node);
+
+        IMFTopologyNode_GetNodeType(node, &node_type);
+
+        i = 0;
+        /* traverse output streams of node and connect them to their downstreams */
+        while (SUCCEEDED(IMFTopologyNode_GetOutput(orig_node, i, &orig_downstream_node, &input_index)))
+        {
+            IMFTopologyNode_GetTopoNodeID(orig_downstream_node, &id);
+            if (FAILED(IMFTopology_GetNodeByID(context->output_topology, id, &downstream_node)))
+                topology_loader_clone_node(context, orig_downstream_node, &downstream_node, context->marker + 1);
+
+            switch (node_type)
+            {
+                case MF_TOPOLOGY_SOURCESTREAM_NODE:
+                    hr = S_OK;
+                    break;
+                case MF_TOPOLOGY_TRANSFORM_NODE:
+                    hr = S_OK;
+                    break;
+                case MF_TOPOLOGY_TEE_NODE:
+                    FIXME("Tee node unsupported.\n");
+                    break;
+                default:
+                    WARN("Unexpected node type %d.\n", node_type);
+            }
+
+            IMFTopologyNode_Release(orig_downstream_node);
+            IMFTopologyNode_Release(downstream_node);
+
+            if (FAILED(hr))
+                goto out;
+            i++;
+        }
+
+        IMFTopologyNode_DeleteItem(node, &context->key);
+        IMFTopologyNode_Release(node);
+    }
+
+out:
+    return hr;
+}
+
 static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *input_topology,
-        IMFTopology **output_topology, IMFTopology *current_topology)
+        IMFTopology **ret_topology, IMFTopology *current_topology)
 {
     struct topoloader_context context = { 0 };
     unsigned short i, max_branch_depth = 0;
@@ -2008,7 +2082,7 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
     WORD count;
     HRESULT hr;
 
-    FIXME("%p, %p, %p, %p.\n", iface, input_topology, output_topology, current_topology);
+    TRACE("%p, %p, %p, %p.\n", iface, input_topology, ret_topology, current_topology);
 
     if (current_topology)
         FIXME("Current topology instance is ignored.\n");
@@ -2018,7 +2092,7 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
         || count < 2)
     {
         hr = MF_E_TOPO_UNSUPPORTED;
-        return hr;
+        goto out;
     }
 
     context.input_topology = input_topology;
@@ -2054,7 +2128,7 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
                     IMFTopologyNode_Release(node);
                     IUnknown_Release(object);
                     hr = MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED;
-                    return hr;
+                    goto out;
                 }
                 IMFStreamSink_Release(sink);
                 IUnknown_Release(object);
@@ -2064,9 +2138,19 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
         IMFTopologyNode_Release(node);
     }
 
-    if (SUCCEEDED(hr = IMFTopology_CloneFrom(context.output_topology, input_topology)))
-        *output_topology = context.output_topology;
+    for (context.marker = 0; context.marker < max_branch_depth; ++context.marker)
+    {
+        if (FAILED(hr = topology_loader_resolve_nodes(&context)))
+            break;
+    }
+
+    if (SUCCEEDED(hr))
+    {
+        IMFTopology_SetUINT32(context.output_topology, &MF_TOPOLOGY_RESOLUTION_STATUS, MF_TOPOLOGY_RESOLUTION_SUCCEEDED);
+        *ret_topology = context.output_topology;
+    }
 
+out:
     return hr;
 }
 
-- 
2.17.1




More information about the wine-devel mailing list