[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 = ¤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);
--
2.17.1
More information about the wine-devel
mailing list