[PATCH v5 3/8] mf: Setup the topology branches to resolve in _Load.

Sergio Gómez Del Real sdelreal at codeweavers.com
Wed Apr 22 22:28:30 CDT 2020


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

diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 3fe89d0456..d375a3f8e5 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -1728,7 +1728,6 @@ static void test_topology_loader(void)
     ok(hr == S_OK, "Failed to add sink node, hr %#x.\n", hr);
 
     hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
-todo_wine
     ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
 
     hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0);
@@ -1736,6 +1735,7 @@ todo_wine
 
     /* Sink was not resolved. */
     hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
+todo_wine
     ok(hr == MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
 
     hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink);
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
index 72cb6062cc..daeea397d5 100644
--- a/dlls/mf/topology.c
+++ b/dlls/mf/topology.c
@@ -1917,9 +1917,12 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
         IMFTopology **output_topology, IMFTopology *current_topology)
 {
     struct topology *topology = unsafe_impl_from_IMFTopology(input_topology);
-    IMFStreamSink *sink;
+    struct topology_node *(*node_pairs)[2];
+    struct topology *full_topology;
+    IMFTopology *topology_clone;
+    int num_connections;
     HRESULT hr;
-    size_t i;
+    int i, idx;
 
     FIXME("%p, %p, %p, %p.\n", iface, input_topology, output_topology, current_topology);
 
@@ -1929,34 +1932,71 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
     if (!topology || topology->nodes.count < 2)
         return MF_E_TOPO_UNSUPPORTED;
 
-    for (i = 0; i < topology->nodes.count; ++i)
+    num_connections = 0;
+    for (i = 0; i < impl_from_IMFTopology(input_topology)->nodes.count; i++)
     {
-        struct topology_node *node = topology->nodes.nodes[i];
+        struct topology_node *node = impl_from_IMFTopology(input_topology)->nodes.nodes[i];
 
-        switch (node->node_type)
+        if (node->node_type == MF_TOPOLOGY_SOURCESTREAM_NODE)
         {
-            case MF_TOPOLOGY_OUTPUT_NODE:
-                if (node->object)
+            if (node->outputs.count && node->outputs.streams->connection)
+                num_connections++;
+        }
+    }
+
+    if (!num_connections)
+        return MF_E_TOPO_UNSUPPORTED;
+
+    node_pairs = heap_alloc_zero(sizeof(struct topology_node *[2]) * num_connections);
+    if (!node_pairs)
+        return E_OUTOFMEMORY;
+
+    MFCreateTopology(&topology_clone);
+    IMFTopology_CloneFrom(topology_clone, input_topology);
+
+    full_topology = impl_from_IMFTopology(topology_clone);
+
+    idx = 0;
+    for (i = 0; i < full_topology->nodes.count; ++i)
+    {
+        struct topology_node *node = full_topology->nodes.nodes[i];
+
+        if (node->node_type == MF_TOPOLOGY_SOURCESTREAM_NODE)
+        {
+            if (node->outputs.count && node->outputs.streams->connection)
+            {
+                node_pairs[idx][0] = node;
+                if (node->outputs.streams->connection->node_type == MF_TOPOLOGY_TRANSFORM_NODE)
                 {
-                    /* Sinks must be bound beforehand. */
-                    if (FAILED(IUnknown_QueryInterface(node->object, &IID_IMFStreamSink, (void **)&sink)))
-                        return MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED;
-                    IMFStreamSink_Release(sink);
+                    struct topology_node *sink = node->outputs.streams->connection;
+
+                    while (sink && sink->node_type != MF_TOPOLOGY_OUTPUT_NODE && sink->outputs.count)
+                           sink = sink->outputs.streams->connection;
+                    if (!sink || !sink->outputs.count)
+                    {
+                        FIXME("Check for MF_CONNECT_AS_OPTIONAL and MF_CONNECT_AS_OPTIONAL_BRANCH flags.\n");
+                        hr = MF_E_TOPO_UNSUPPORTED;
+                        goto out;
+                    }
+                    node_pairs[idx][1] = sink;
                 }
-                break;
-            case MF_TOPOLOGY_SOURCESTREAM_NODE:
-                if (FAILED(hr = IMFAttributes_GetItem(node->attributes, &MF_TOPONODE_STREAM_DESCRIPTOR, NULL)))
-                    return hr;
-                break;
-            default:
-                ;
+                else if (node->outputs.streams->connection->node_type == MF_TOPOLOGY_OUTPUT_NODE)
+                    node_pairs[idx][1] = node->outputs.streams->connection;
+                else {
+                    FIXME("Tee nodes currently unhandled.\n");
+                    hr = MF_E_TOPO_UNSUPPORTED;
+                    goto out;
+                }
+                idx++;
+            }
         }
     }
 
-    if (FAILED(hr = MFCreateTopology(output_topology)))
-        return hr;
-
-    return IMFTopology_CloneFrom(*output_topology, input_topology);
+    *output_topology = &full_topology->IMFTopology_iface;
+    hr = S_OK;
+out:
+    heap_free(node_pairs);
+    return hr;
 }
 
 static const IMFTopoLoaderVtbl topologyloadervtbl =
-- 
2.17.1




More information about the wine-devel mailing list