Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/mf/topology.c | 110 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+)
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index 3ca781e12f..ba4675bb13 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -2447,6 +2447,116 @@ static HRESULT topology_loader_build_topologies_from_input_mediatype(IMFTopology } }
+ /* if couldn't resolve up -> mft -> down, try up -> mft -> converter -> down */ + if (list_empty(out_topologies)) + { + IMFActivate **activate_convs; + UINT32 num_activate_convs; + + LIST_FOR_EACH_ENTRY(up_to_mft_topologies, &list_up_to_mft_topologies, struct list_topologies, entry) + { + IMFTopologyNode *current_up_to_mft_topology_upnode, *current_up_to_mft_topology_downnode; + struct list_topologies *mft_to_conv_topologies, *safety_mft_to_conv; + struct list list_mft_to_conv_topologies; + struct topology *current_up_to_mft_topology; + int count; + + current_up_to_mft_topology = up_to_mft_topologies->topology; + current_up_to_mft_topology_upnode = ¤t_up_to_mft_topology->nodes.nodes[0]->IMFTopologyNode_iface; + current_up_to_mft_topology_downnode = ¤t_up_to_mft_topology->nodes.nodes[1]->IMFTopologyNode_iface; + + list_init(&list_mft_to_conv_topologies); + + count = 0; + while (SUCCEEDED(topology_loader_get_next_output_mediatype(current_up_to_mft_topology_downnode, count++, &out_upstream))) + { + IMFTopologyNode *node_conv; + IMFTransform *conv; + int i; + + topology_loader_get_mfts(out_upstream, NULL, MF_CONNECT_ALLOW_CONVERTER, &activate_convs, &num_activate_convs); + MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node_conv); + for (i = 0; i < num_activate_convs; i++) + { + if (FAILED(hr = IMFActivate_ActivateObject(activate_convs[i], &IID_IMFTransform, (void **)&conv))) + continue; + + IMFTopologyNode_SetObject(node_conv, (IUnknown *)conv); + + /* set current media type so we don't iterate over its available media types in recursive call */ + topology_loader_test_set_output_mediatype(current_up_to_mft_topology_downnode, out_upstream, 1); + topology_loader_build_topologies_from_input_mediatype(current_up_to_mft_topology_downnode, NULL, node_conv, MF_CONNECT_DIRECT, &list_mft_to_conv_topologies); + } + IMFMediaType_Release(out_upstream); + } + LIST_FOR_EACH_ENTRY_SAFE(mft_to_conv_topologies, safety_mft_to_conv, &list_mft_to_conv_topologies, struct list_topologies, entry) + { + IMFTopologyNode *current_mft_to_conv_topology_downnode, *current_mft_to_conv_topology_upnode; + struct list_topologies *conv_to_down_topologies, *safety_conv_to_down; + struct topology *current_mft_to_conv_topology; + struct list list_conv_to_down_topologies; + IMFTopology *topology; + + current_mft_to_conv_topology = mft_to_conv_topologies->topology; + current_mft_to_conv_topology_upnode = ¤t_mft_to_conv_topology->nodes.nodes[0]->IMFTopologyNode_iface; + current_mft_to_conv_topology_downnode = ¤t_mft_to_conv_topology->nodes.nodes[1]->IMFTopologyNode_iface; + + list_init(&list_conv_to_down_topologies); + topology_loader_build_topologies_from_input_mediatype(current_mft_to_conv_topology_downnode, NULL, downstream_clone, MF_CONNECT_DIRECT, &list_conv_to_down_topologies); + LIST_FOR_EACH_ENTRY_SAFE(conv_to_down_topologies, safety_conv_to_down, &list_conv_to_down_topologies, struct list_topologies, entry) + { + IMFTopologyNode *current_up_to_mft_topology_upnode_clone; + IMFTopologyNode *current_mft_to_conv_topology_upnode_clone, *current_mft_to_conv_topology_downnode_clone; + IMFTopologyNode *current_conv_to_down_topology_upnode, *current_conv_to_down_topology_upnode_clone; + IMFTopologyNode *current_conv_to_down_topology_downnode, *current_conv_to_down_topology_downnode_clone; + struct topology *current_conv_to_down_topology; + struct list_topologies *out_entry; + + current_conv_to_down_topology = conv_to_down_topologies->topology; + current_conv_to_down_topology_upnode = ¤t_conv_to_down_topology->nodes.nodes[0]->IMFTopologyNode_iface; + current_conv_to_down_topology_downnode = ¤t_conv_to_down_topology->nodes.nodes[1]->IMFTopologyNode_iface; + + IMFTopologyNode_GetNodeType(current_up_to_mft_topology_upnode, &type); + MFCreateTopologyNode(type, ¤t_up_to_mft_topology_upnode_clone); + IMFTopologyNode_CloneFrom(current_up_to_mft_topology_upnode_clone, current_up_to_mft_topology_upnode); + + IMFTopologyNode_GetNodeType(current_mft_to_conv_topology_upnode, &type); + MFCreateTopologyNode(type, ¤t_mft_to_conv_topology_upnode_clone); + IMFTopologyNode_CloneFrom(current_mft_to_conv_topology_upnode_clone, current_mft_to_conv_topology_upnode); + + IMFTopologyNode_GetNodeType(current_mft_to_conv_topology_downnode, &type); + MFCreateTopologyNode(type, ¤t_mft_to_conv_topology_downnode_clone); + IMFTopologyNode_CloneFrom(current_mft_to_conv_topology_downnode_clone, current_mft_to_conv_topology_downnode); + + IMFTopologyNode_GetNodeType(current_conv_to_down_topology_upnode, &type); + MFCreateTopologyNode(type, ¤t_conv_to_down_topology_upnode_clone); + IMFTopologyNode_CloneFrom(current_conv_to_down_topology_upnode_clone, current_conv_to_down_topology_upnode); + + IMFTopologyNode_GetNodeType(current_conv_to_down_topology_downnode, &type); + MFCreateTopologyNode(type, ¤t_conv_to_down_topology_downnode_clone); + IMFTopologyNode_CloneFrom(current_conv_to_down_topology_downnode_clone, current_conv_to_down_topology_downnode); + + IMFTopologyNode_ConnectOutput(current_up_to_mft_topology_upnode_clone, 0, current_mft_to_conv_topology_upnode_clone, 0); + IMFTopologyNode_ConnectOutput(current_mft_to_conv_topology_upnode_clone, 0, current_mft_to_conv_topology_downnode_clone, 0); + IMFTopologyNode_ConnectOutput(current_mft_to_conv_topology_downnode_clone, 0, current_conv_to_down_topology_upnode_clone, 0); + IMFTopologyNode_ConnectOutput(current_conv_to_down_topology_upnode_clone, 0, current_conv_to_down_topology_downnode_clone, 0); + + MFCreateTopology(&topology); + topology_loader_add_branch(impl_from_IMFTopology(topology), current_up_to_mft_topology_upnode_clone); + out_entry = heap_alloc_zero(sizeof(struct list_topologies *)); + out_entry->topology = impl_from_IMFTopology(topology); + list_add_tail(out_topologies, &out_entry->entry); + + list_remove(&conv_to_down_topologies->entry); + IMFTopology_Release(&conv_to_down_topologies->topology->IMFTopology_iface); + heap_free(conv_to_down_topologies); + } + list_remove(&mft_to_conv_topologies->entry); + IMFTopology_Release(&mft_to_conv_topologies->topology->IMFTopology_iface); + heap_free(mft_to_conv_topologies); + } + } + } LIST_FOR_EACH_ENTRY(up_to_mft_topologies, &list_up_to_mft_topologies, struct list_topologies, entry) { IMFTopology_Release(&up_to_mft_topologies->topology->IMFTopology_iface);