[PATCH v5 7/8] mf: Introduce mediatype negotiator topology_loader_build_topologies_from_input_mediatype() for use by topology loader.
Sergio Gómez Del Real
sdelreal at codeweavers.com
Wed Apr 22 22:28:34 CDT 2020
Signed-off-by: Sergio Gómez Del Real <sdelreal at codeweavers.com>
---
dlls/mf/tests/mf.c | 2 -
dlls/mf/topology.c | 540 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 538 insertions(+), 4 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 33c33f9a7c..63dbdecd22 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -1851,7 +1851,6 @@ todo_wine {
ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
hr = IMFTopology_GetNodeCount(full_topology, &node_count);
ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
-todo_wine
ok(node_count == 3, "Unexpected node count %d.\n", node_count);
IMFTopology_Release(full_topology);
@@ -1868,7 +1867,6 @@ todo_wine
hr = IMFTopology_GetNodeCount(full_topology, &node_count);
ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
-todo_wine
ok(node_count == 3, "Unexpected node count %d.\n", node_count);
/* now test without MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES on source */
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
index f1b3c3c9e4..3ca781e12f 100644
--- a/dlls/mf/topology.c
+++ b/dlls/mf/topology.c
@@ -1949,6 +1949,514 @@ out:
return hr == MF_E_NOT_FOUND ? S_OK : hr;
}
+static inline HRESULT topology_node_get_mediatypehandler(IMFTopologyNode *node, IMFMediaTypeHandler **mth)
+{
+ MF_TOPOLOGY_TYPE type;
+ HRESULT hr;
+
+ if (!node || !mth)
+ {
+ hr = MF_E_INVALIDREQUEST;
+ goto out;
+ }
+
+ if (FAILED(hr = IMFTopologyNode_GetNodeType(node, &type)))
+ goto out;
+
+ if (type == MF_TOPOLOGY_SOURCESTREAM_NODE)
+ {
+ IMFStreamDescriptor *streamdesc;
+
+ if (SUCCEEDED(hr = IMFTopologyNode_GetUnknown(node, &MF_TOPONODE_STREAM_DESCRIPTOR, &IID_IMFStreamDescriptor, (void **)&streamdesc)))
+ {
+ hr = IMFStreamDescriptor_GetMediaTypeHandler(streamdesc, mth);
+ IMFStreamDescriptor_Release(streamdesc);
+ }
+ }
+ else if (type == MF_TOPOLOGY_OUTPUT_NODE)
+ {
+ IMFStreamSink *streamsink;
+
+ if (SUCCEEDED(hr = IMFTopologyNode_GetObject(node, (IUnknown **)&streamsink)))
+ {
+ hr = IMFStreamSink_GetMediaTypeHandler(streamsink, mth);
+ IMFStreamSink_Release(streamsink);
+ }
+ }
+
+out:
+ return hr;
+}
+
+static inline HRESULT topology_loader_test_set_output_mediatype(IMFTopologyNode *node, IMFMediaType *mediatype, int set)
+{
+ MF_TOPOLOGY_TYPE nodetype;
+ HRESULT hr;
+
+ if (!node || !mediatype)
+ {
+ hr = MF_E_INVALIDREQUEST;
+ goto out;
+ }
+
+ IMFTopologyNode_GetNodeType(node, &nodetype);
+
+ if (nodetype == MF_TOPOLOGY_SOURCESTREAM_NODE)
+ {
+ IMFMediaTypeHandler *mth;
+
+ if (SUCCEEDED(hr = topology_node_get_mediatypehandler(node, &mth)))
+ {
+ if (set)
+ hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, mediatype);
+ else
+ hr = IMFMediaTypeHandler_IsMediaTypeSupported(mth, mediatype, NULL);
+ }
+ }
+ else if (nodetype == MF_TOPOLOGY_TRANSFORM_NODE)
+ {
+ IMFTransform *transform;
+
+ if (SUCCEEDED(hr = IMFTopologyNode_GetObject(node, (IUnknown **)&transform)))
+ hr = IMFTransform_SetOutputType(transform, 0, mediatype, set);
+ }
+
+out:
+ return hr;
+}
+
+static inline HRESULT topology_loader_test_set_input_mediatype(IMFTopologyNode *node, IMFMediaType *mediatype, int set)
+{
+ MF_TOPOLOGY_TYPE nodetype;
+ HRESULT hr;
+
+ if (!node || !mediatype)
+ {
+ hr = MF_E_INVALIDREQUEST;
+ goto out;
+ }
+
+ if (FAILED(hr = IMFTopologyNode_GetNodeType(node, &nodetype)))
+ goto out;
+
+ if (nodetype == MF_TOPOLOGY_OUTPUT_NODE)
+ {
+ IMFMediaTypeHandler *mth;
+
+ if (SUCCEEDED(hr = topology_node_get_mediatypehandler(node, &mth)))
+ {
+ if (set)
+ hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, mediatype);
+ else
+ {
+ DWORD flags;
+ IMFMediaType *curr_type;
+
+ IMFMediaTypeHandler_GetCurrentMediaType(mth, &curr_type);
+ hr = IMFMediaType_IsEqual(curr_type, mediatype, &flags);
+ if (!(flags & MF_MEDIATYPE_EQUAL_FORMAT_DATA))
+ hr = MF_E_INVALIDMEDIATYPE;
+ }
+ }
+ }
+ else if (nodetype == MF_TOPOLOGY_TRANSFORM_NODE)
+ {
+ IMFTransform *transform;
+
+ if (SUCCEEDED(hr = IMFTopologyNode_GetObject(node, (IUnknown **)&transform)))
+ hr = IMFTransform_SetInputType(transform, 0, mediatype, set);
+ }
+
+out:
+ return hr;
+}
+
+static inline HRESULT topology_loader_get_current_input_mediatype(IMFTopologyNode *node, IMFMediaType **in)
+{
+ MF_TOPOLOGY_TYPE type;
+ HRESULT hr;
+
+ if (!node || !in)
+ {
+ hr = MF_E_INVALIDREQUEST;
+ goto out;
+ }
+
+ if (FAILED(hr = IMFTopologyNode_GetNodeType(node, &type)))
+ goto out;
+
+ if (type == MF_TOPOLOGY_OUTPUT_NODE)
+ {
+ IMFMediaTypeHandler *mth;
+
+ if (SUCCEEDED(hr = topology_node_get_mediatypehandler(node, &mth)))
+ hr = IMFMediaTypeHandler_GetCurrentMediaType(mth, in);
+ }
+ else if (type == MF_TOPOLOGY_TRANSFORM_NODE)
+ {
+ IMFTransform *transform;
+
+ if (SUCCEEDED(hr = IMFTopologyNode_GetObject(node, (IUnknown **)&transform)))
+ hr = IMFTransform_GetInputCurrentType(transform, 0, in);
+ }
+
+out:
+ return hr;
+}
+
+static inline HRESULT topology_loader_get_current_output_mediatype(IMFTopologyNode *node, IMFMediaType **out)
+{
+ MF_TOPOLOGY_TYPE type;
+ HRESULT hr;
+
+ if (!node || !out)
+ {
+ hr = MF_E_INVALIDREQUEST;
+ goto out;
+ }
+
+ if (FAILED(hr = IMFTopologyNode_GetNodeType(node, &type)))
+ goto out;
+
+ if (type == MF_TOPOLOGY_SOURCESTREAM_NODE)
+ {
+ IMFMediaTypeHandler *mth;
+
+ if (SUCCEEDED(hr = topology_node_get_mediatypehandler(node, &mth)))
+ hr = IMFMediaTypeHandler_GetCurrentMediaType(mth, out);
+ }
+ else if (type == MF_TOPOLOGY_TRANSFORM_NODE)
+ {
+ IMFTransform *transform;
+
+ if (SUCCEEDED(hr = IMFTopologyNode_GetObject(node, (IUnknown **)&transform)))
+ hr = IMFTransform_GetOutputCurrentType(transform, 0, out);
+ }
+
+out:
+ return hr;
+}
+
+static inline HRESULT topology_loader_get_next_output_mediatype(IMFTopologyNode *node, UINT32 index, IMFMediaType **output)
+{
+ MF_TOPOLOGY_TYPE type;
+ HRESULT hr;
+
+ if (!node || !output)
+ {
+ hr = MF_E_INVALIDREQUEST;
+ goto out;
+ }
+
+ if (FAILED(hr = IMFTopologyNode_GetNodeType(node, &type)))
+ goto out;
+
+ if (type == MF_TOPOLOGY_SOURCESTREAM_NODE)
+ {
+ IMFMediaTypeHandler *mth;
+
+ if (!index)
+ {
+ if (SUCCEEDED(hr = topology_node_get_mediatypehandler(node, &mth)))
+ {
+ hr = IMFMediaTypeHandler_GetCurrentMediaType(mth, output);
+ IMFMediaTypeHandler_Release(mth);
+ }
+ }
+ else
+ hr = MF_E_INVALIDREQUEST;
+ }
+ else if (type == MF_TOPOLOGY_TRANSFORM_NODE)
+ {
+ IMFTransform *transform;
+
+ if (SUCCEEDED(hr = IMFTopologyNode_GetObject(node, (IUnknown **)&transform)))
+ {
+ hr = IMFTransform_GetOutputAvailableType(transform, 0, index, output);
+ IMFTransform_Release(transform);
+ }
+ }
+
+out:
+ return hr;
+}
+
+static inline HRESULT topology_loader_get_mft_category(IMFMediaType *mediatype, MF_CONNECT_METHOD method, GUID *category)
+{
+ GUID major_type;
+
+ if (!mediatype || !category)
+ return MF_E_INVALIDREQUEST;
+
+ if (FAILED(IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &major_type)))
+ return MF_E_INVALIDREQUEST;
+
+ if (method == MF_CONNECT_ALLOW_DECODER || method == MF_CONNECT_ALLOW_CONVERTER)
+ {
+ if (IsEqualGUID(&major_type, &MFMediaType_Audio))
+ *category = MFT_CATEGORY_AUDIO_DECODER;
+ else if (IsEqualGUID(&major_type, &MFMediaType_Video))
+ *category = MFT_CATEGORY_VIDEO_DECODER;
+ else
+ return MF_E_TOPO_CODEC_NOT_FOUND;
+ }
+ else
+ return MF_E_TOPO_CODEC_NOT_FOUND;
+
+ return S_OK;
+}
+
+static inline HRESULT topology_loader_get_mft_reg_typeinfo(IMFMediaType *type, MFT_REGISTER_TYPE_INFO *typeinfo)
+{
+ GUID major_type, subtype;
+
+ if (!type || !typeinfo)
+ return MF_E_INVALIDREQUEST;
+
+ IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type);
+ IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype);
+
+ typeinfo->guidMajorType = major_type;
+ typeinfo->guidSubtype = subtype;
+
+ return S_OK;
+}
+
+static HRESULT topology_loader_get_mfts(IMFMediaType *in, IMFMediaType *out, MF_CONNECT_METHOD method, IMFActivate ***activates, UINT32 *num_activates)
+{
+ MFT_REGISTER_TYPE_INFO *info_in = NULL, *info_out = NULL;
+ MFT_REGISTER_TYPE_INFO mftinfo_in, mftinfo_out;
+ GUID mft_category;
+
+ if (in == NULL && out == NULL)
+ return MF_E_INVALIDREQUEST;
+
+ if (in != NULL)
+ {
+ topology_loader_get_mft_reg_typeinfo(in, &mftinfo_in);
+ topology_loader_get_mft_category(in, method, &mft_category);
+ info_in = &mftinfo_in;
+ }
+ if (out != NULL)
+ {
+ topology_loader_get_mft_reg_typeinfo(out, &mftinfo_out);
+ topology_loader_get_mft_category(out, method, &mft_category);
+ info_out = &mftinfo_out;
+ }
+
+ return MFTEnumEx(mft_category, MFT_ENUM_FLAG_ALL, info_in, info_out, activates, num_activates);
+}
+
+/*
+ * Receives upstream and downstream nodes, and input mediatype for upstream.
+ * Build a list of compatible topologies. Try, in order, direct connection, mft only and mft + converter.
+ * Always operate on cloned nodes and topologies, since resolution might fail, and nodes and/or branches might be optional,
+ * so the need arises to recover previous states.
+ */
+static HRESULT topology_loader_build_topologies_from_input_mediatype(IMFTopologyNode *upstream, IMFMediaType *input, IMFTopologyNode *downstream, MF_CONNECT_METHOD method, struct list *out_topologies)
+{
+ IMFMediaType *out = NULL;
+ MF_TOPOLOGY_TYPE type;
+ HRESULT hr;
+
+ IMFTopologyNode_GetNodeType(upstream, &type);
+
+ if (type != MF_TOPOLOGY_SOURCESTREAM_NODE)
+ {
+ if (input == NULL)
+ {
+ HRESULT hr = topology_loader_get_current_input_mediatype(upstream, &out);
+
+ if (FAILED(hr) && hr != E_NOTIMPL)
+ return MF_E_INVALIDMEDIATYPE;
+ }
+ else
+ {
+ if (FAILED(topology_loader_test_set_input_mediatype(upstream, input, 0)))
+ return MF_E_INVALIDMEDIATYPE;
+
+ topology_loader_test_set_input_mediatype(upstream, input, 1);
+ }
+ }
+
+ if (out)
+ IMFMediaType_Release(out);
+
+ if (method == MF_CONNECT_DIRECT)
+ {
+ struct list_topologies *topology_entry;
+ IMFMediaType *up_output_mtype;
+ IMFTopology *topology;
+
+ if (SUCCEEDED(topology_loader_get_current_output_mediatype(upstream, &up_output_mtype)))
+ {
+ if (SUCCEEDED(topology_loader_test_set_input_mediatype(downstream, up_output_mtype, 0)))
+ {
+ IMFTopologyNode *upstream_clone, *downstream_clone;
+
+ IMFTopologyNode_GetNodeType(upstream, &type);
+ MFCreateTopologyNode(type, &upstream_clone);
+ IMFTopologyNode_CloneFrom(upstream_clone, upstream);
+
+ IMFTopologyNode_GetNodeType(downstream, &type);
+ MFCreateTopologyNode(type, &downstream_clone);
+ IMFTopologyNode_CloneFrom(downstream_clone, downstream);
+ topology_loader_test_set_input_mediatype(downstream_clone, up_output_mtype, 1);
+
+ IMFTopologyNode_ConnectOutput(upstream_clone, 0, downstream_clone, 0);
+
+ MFCreateTopology(&topology);
+ topology_loader_add_branch(impl_from_IMFTopology(topology), upstream_clone);
+
+ topology_entry = heap_alloc_zero(sizeof(struct list_topologies *));
+ topology_entry->topology = impl_from_IMFTopology(topology);
+ list_add_tail(out_topologies, &topology_entry->entry);
+
+ hr = S_OK;
+ }
+ IMFMediaType_Release(up_output_mtype);
+ }
+ else
+ {
+ int count = 0;
+ while (SUCCEEDED(topology_loader_get_next_output_mediatype(upstream, count++, &up_output_mtype)))
+ {
+ if (SUCCEEDED(topology_loader_test_set_input_mediatype(downstream, up_output_mtype, 0)))
+ {
+ IMFTopologyNode *upstream_clone, *downstream_clone;
+
+ IMFTopologyNode_GetNodeType(upstream, &type);
+ MFCreateTopologyNode(type, &upstream_clone);
+ IMFTopologyNode_CloneFrom(upstream_clone, upstream);
+
+ IMFTopologyNode_GetNodeType(downstream, &type);
+ MFCreateTopologyNode(type, &downstream_clone);
+ IMFTopologyNode_CloneFrom(downstream_clone, downstream);
+ topology_loader_test_set_input_mediatype(downstream_clone, up_output_mtype, 1);
+
+ IMFTopologyNode_ConnectOutput(upstream_clone, 0, downstream_clone, 0);
+
+ MFCreateTopology(&topology);
+ topology_loader_add_branch(impl_from_IMFTopology(topology), upstream_clone);
+ topology_entry = heap_alloc_zero(sizeof(struct list_topologies *));
+ topology_entry->topology = impl_from_IMFTopology(topology);
+ list_add_tail(out_topologies, &topology_entry->entry);
+
+ hr = S_OK;
+ }
+ IMFMediaType_Release(up_output_mtype);
+ }
+ }
+ }
+
+ else
+ {
+ IMFTopologyNode *upstream_clone, *downstream_clone;
+ struct list_topologies *up_to_mft_topologies;
+ struct list list_up_to_mft_topologies;
+ IMFMediaType *out_upstream;
+ int count;
+
+ IMFTopologyNode_GetNodeType(upstream, &type);
+ MFCreateTopologyNode(type, &upstream_clone);
+ IMFTopologyNode_CloneFrom(upstream_clone, upstream);
+
+ IMFTopologyNode_GetNodeType(downstream, &type);
+ MFCreateTopologyNode(type, &downstream_clone);
+ IMFTopologyNode_CloneFrom(downstream_clone, downstream);
+
+ list_init(&list_up_to_mft_topologies);
+
+ count = 0;
+ while (SUCCEEDED(topology_loader_get_next_output_mediatype(upstream_clone, count++, &out_upstream)))
+ {
+ IMFActivate **activate_mfts;
+ IMFTopologyNode *node_mft;
+ UINT32 num_activate_mfts;
+ IMFTransform *mft;
+ int i;
+
+ /* set current media type so we don't iterate over all available media types in recursive call */
+ topology_loader_test_set_output_mediatype(upstream_clone, out_upstream, 1);
+
+ MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node_mft);
+
+ topology_loader_get_mfts(out_upstream, NULL, method, &activate_mfts, &num_activate_mfts);
+ for (i = 0; i < num_activate_mfts; i++)
+ {
+ if (FAILED(hr = IMFActivate_ActivateObject(activate_mfts[i], &IID_IMFTransform, (void **)&mft)))
+ continue;
+ IMFTopologyNode_SetObject(node_mft, (IUnknown *)mft);
+ hr = topology_loader_build_topologies_from_input_mediatype(upstream_clone, NULL, node_mft, MF_CONNECT_DIRECT, &list_up_to_mft_topologies);
+ }
+ IMFTopologyNode_Release(node_mft);
+ IMFMediaType_Release(out_upstream);
+ }
+
+ /* first try direct connections: up -> mft -> down */
+ 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_down_topologies, *safety_mft_to_down;
+ struct topology *current_up_to_mft_topology;
+ struct list list_mft_to_down_topologies;
+
+ 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_down_topologies);
+ hr = topology_loader_build_topologies_from_input_mediatype(current_up_to_mft_topology_downnode, NULL, downstream_clone, MF_CONNECT_DIRECT, &list_mft_to_down_topologies);
+
+ LIST_FOR_EACH_ENTRY_SAFE(mft_to_down_topologies, safety_mft_to_down, &list_mft_to_down_topologies, struct list_topologies, entry)
+ {
+ IMFTopologyNode *current_mft_to_down_topology_upnode, *current_mft_to_down_topology_upnode_clone;
+ IMFTopologyNode *current_mft_to_down_topology_downnode, *current_mft_to_down_topology_downnode_clone;
+ IMFTopologyNode *current_up_to_mft_topology_upnode_clone;
+ struct topology *current_mft_to_down_topology;
+ struct list_topologies *out_entry;
+ IMFTopology *topology;
+
+ current_mft_to_down_topology = mft_to_down_topologies->topology;
+ current_mft_to_down_topology_upnode = ¤t_mft_to_down_topology->nodes.nodes[0]->IMFTopologyNode_iface;
+ current_mft_to_down_topology_downnode = ¤t_mft_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_down_topology_upnode, &type);
+ MFCreateTopologyNode(type, ¤t_mft_to_down_topology_upnode_clone);
+ IMFTopologyNode_CloneFrom(current_mft_to_down_topology_upnode_clone, current_mft_to_down_topology_upnode);
+
+ IMFTopologyNode_GetNodeType(current_mft_to_down_topology_downnode, &type);
+ MFCreateTopologyNode(type, ¤t_mft_to_down_topology_downnode_clone);
+ IMFTopologyNode_CloneFrom(current_mft_to_down_topology_downnode_clone, current_mft_to_down_topology_downnode);
+ IMFTopologyNode_ConnectOutput(current_up_to_mft_topology_upnode_clone, 0, current_mft_to_down_topology_upnode_clone, 0);
+ IMFTopologyNode_ConnectOutput(current_mft_to_down_topology_upnode_clone, 0, current_mft_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(&mft_to_down_topologies->entry);
+ heap_free(mft_to_down_topologies);
+ IMFTopology_Release(¤t_mft_to_down_topology->IMFTopology_iface);
+ }
+ }
+
+ 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);
+ heap_free(up_to_mft_topologies);
+ }
+ }
+
+ return hr;
+}
+
/* iterate through the branch that starts at source node with id srcid, and try to resolve it */
static HRESULT topology_loader_resolve_branch_connect_nodes(struct topology *topology, TOPOID srcid, MF_CONNECT_METHOD method)
{
@@ -1991,7 +2499,7 @@ static HRESULT topology_loader_resolve_branch_connect_nodes(struct topology *top
/* 'method' argument passed to function only applies to source media types */
if (method == MF_CONNECT_DIRECT)
{
- hr = S_OK;
+ hr = topology_loader_build_topologies_from_input_mediatype(up_clone, NULL, down_clone, MF_CONNECT_DIRECT, &list_topologies[i]);
if (list_empty(&list_topologies[i]))
{
IMFTopologyNode_Release(up_clone);
@@ -2004,7 +2512,11 @@ static HRESULT topology_loader_resolve_branch_connect_nodes(struct topology *top
}
else
{
- hr = S_OK;
+ hr = topology_loader_build_topologies_from_input_mediatype(up_clone, NULL, down_clone, MF_CONNECT_DIRECT, &list_topologies[0]);
+ if (list_empty(&list_topologies[0]))
+ hr = topology_loader_build_topologies_from_input_mediatype(up_clone, NULL, down_clone, MF_CONNECT_ALLOW_DECODER, &list_topologies[0]);
+ if (list_empty(&list_topologies[0]))
+ hr = topology_loader_build_topologies_from_input_mediatype(up_clone, NULL, down_clone, MF_CONNECT_ALLOW_CONVERTER, &list_topologies[0]);
if (list_empty(&list_topologies[i]))
{
IMFTopologyNode_Release(up_clone);
@@ -2036,6 +2548,12 @@ static HRESULT topology_loader_resolve_branch_connect_nodes(struct topology *top
prev_topology = prev_topologies->topology;
IMFTopologyNode_CloneFrom(up_clone, &prev_topology->nodes.nodes[prev_topology->nodes.count-1]->IMFTopologyNode_iface);
+ hr = topology_loader_build_topologies_from_input_mediatype(up_clone, NULL, down_clone, MF_CONNECT_DIRECT, &list_topologies[i]);
+ if (list_empty(&list_topologies[i]))
+ hr = topology_loader_build_topologies_from_input_mediatype(up_clone, NULL, down_clone, MF_CONNECT_ALLOW_DECODER, &list_topologies[i]);
+ if (list_empty(&list_topologies[i]))
+ hr = topology_loader_build_topologies_from_input_mediatype(up_clone, NULL, down_clone, MF_CONNECT_ALLOW_CONVERTER, &list_topologies[i]);
+
if (list_empty(&list_topologies[i]))
{
IMFTopologyNode_Release(up_clone);
@@ -2072,6 +2590,24 @@ static HRESULT topology_loader_resolve_branch_connect_nodes(struct topology *top
}
out:
+ if (SUCCEEDED(hr))
+ {
+ int set = 0;
+ struct list_topologies *curr_topologies;
+ LIST_FOR_EACH_ENTRY(curr_topologies, &list_topologies[num_lists-1], struct list_topologies, entry)
+ {
+ struct topology *curr_topology = curr_topologies->topology;
+
+ if (!set)
+ {
+ IMFTopology_CloneFrom(&topology->IMFTopology_iface, &curr_topology->IMFTopology_iface);
+ set = 1;
+ }
+ IMFTopology_Release(&curr_topology->IMFTopology_iface);
+ break;
+ }
+ }
+
heap_free(list_topologies);
return hr;
}
--
2.17.1
More information about the wine-devel
mailing list