[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 = &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_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 = &current_mft_to_down_topology->nodes.nodes[0]->IMFTopologyNode_iface;
+                current_mft_to_down_topology_downnode = &current_mft_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_down_topology_upnode, &type);
+                MFCreateTopologyNode(type, &current_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, &current_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(&current_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