[PATCH v5 8/8] mf: Add support for second-level resolution (mft+converter) if mft-only fails.

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


Signed-off-by: Sergio Gómez Del Real <sdelreal at 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 = &current_up_to_mft_topology->nodes.nodes[0]->IMFTopologyNode_iface;
+                current_up_to_mft_topology_downnode = &current_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 = &current_mft_to_conv_topology->nodes.nodes[0]->IMFTopologyNode_iface;
+                    current_mft_to_conv_topology_downnode = &current_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 = &current_conv_to_down_topology->nodes.nodes[0]->IMFTopologyNode_iface;
+                        current_conv_to_down_topology_downnode = &current_conv_to_down_topology->nodes.nodes[1]->IMFTopologyNode_iface;
+
+                        IMFTopologyNode_GetNodeType(current_up_to_mft_topology_upnode, &type);
+                        MFCreateTopologyNode(type, &current_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, &current_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, &current_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, &current_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, &current_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);
-- 
2.17.1




More information about the wine-devel mailing list