Signed-off-by: Sergio Gómez Del Real sdelreal@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 =