Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/mf/tests/mf.c | 5 --- dlls/mf/topology.c | 98 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 90 insertions(+), 13 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 0bcf6a268f..28efe310f6 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 20f351bfb3..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,11 +2138,19 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in IMFTopologyNode_Release(node); }
- if (FAILED(hr = IMFTopology_CloneFrom(context.output_topology, input_topology))) - IMFTopology_Release(context.output_topology); - else - *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; }