[PATCH v5 5/8] mf: Introduce topology_loader_resolve_branch() wrapper for use by topology loader.

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


Signed-off-by: Sergio Gómez Del Real <sdelreal at codeweavers.com>
---
 dlls/mf/topology.c | 109 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 108 insertions(+), 1 deletion(-)

diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
index ce107d05f2..4298ab1bc5 100644
--- a/dlls/mf/topology.c
+++ b/dlls/mf/topology.c
@@ -1913,6 +1913,97 @@ static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface)
     return refcount;
 }
 
+
+/* Resolves a branch with the supplied source and sink */
+static HRESULT topology_loader_resolve_branch(struct topology_node *src, struct topology_node *sink, struct topology *full_topology)
+{
+    IMFStreamDescriptor *strm_desc;
+    IMFMediaType **src_mediatypes;
+    UINT32 method, enum_src_types;
+    IMFMediaTypeHandler *mth_src;
+    IMFAttributes *attrs_src;
+    IMFMediaType *mtype_src;
+    DWORD num_media_types;
+    HRESULT hr;
+    int i;
+
+    attrs_src = src->attributes;
+    if (FAILED(hr = IMFAttributes_GetUnknown(attrs_src, &MF_TOPONODE_STREAM_DESCRIPTOR, &IID_IMFStreamDescriptor, (void **)&strm_desc)))
+        return hr;
+
+    if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(strm_desc, &mth_src)))
+    {
+        IMFStreamDescriptor_Release(strm_desc);
+        return hr;
+    }
+    IMFStreamDescriptor_Release(strm_desc);
+
+    if (FAILED(IMFTopology_GetUINT32(&full_topology->IMFTopology_iface, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, &enum_src_types)))
+        enum_src_types = 0;
+
+    if (!enum_src_types)
+    {
+        num_media_types = 1;
+        if (FAILED(hr = IMFMediaTypeHandler_GetCurrentMediaType(mth_src, &mtype_src)))
+            if (FAILED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth_src, 0, &mtype_src)))
+            {
+                IMFMediaTypeHandler_Release(mth_src);
+                return hr;
+            }
+    }
+    else
+        IMFMediaTypeHandler_GetMediaTypeCount(mth_src, &num_media_types);
+
+    src_mediatypes = heap_alloc(sizeof(IMFMediaType *) * num_media_types);
+    if (!src_mediatypes)
+    {
+        if (!enum_src_types)
+            IMFMediaType_Release(mtype_src);
+        IMFMediaTypeHandler_Release(mth_src);
+        return E_OUTOFMEMORY;
+    }
+
+    if (enum_src_types)
+        for (i = 0; i < num_media_types; i++)
+            IMFMediaTypeHandler_GetMediaTypeByIndex(mth_src, i, &src_mediatypes[i]);
+    else
+        src_mediatypes[0] = mtype_src;
+
+    hr = IMFAttributes_GetUINT32(attrs_src, &MF_TOPONODE_CONNECT_METHOD, &method);
+    if (!enum_src_types || (hr == S_OK && !(method & MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES)))
+    {
+        for (method = MF_CONNECT_DIRECT; method < MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES; method++)
+        {
+            for (i = 0; i < num_media_types; i++)
+            {
+                IMFMediaTypeHandler_SetCurrentMediaType(mth_src, src_mediatypes[i]);
+                hr = S_OK;
+                goto out;
+            }
+        }
+    }
+    else
+    {
+        for (i = 0; i < num_media_types; i++)
+        {
+            for (method = MF_CONNECT_DIRECT; method < MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES; method++)
+            {
+                IMFMediaTypeHandler_SetCurrentMediaType(mth_src, src_mediatypes[i]);
+                hr = S_OK;
+                goto out;
+            }
+        }
+    }
+
+out:
+    while (num_media_types--)
+        IMFMediaType_Release(src_mediatypes[num_media_types]);
+    IMFMediaTypeHandler_Release(mth_src);
+    heap_free(src_mediatypes);
+
+    return hr;
+}
+
 static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *input_topology,
         IMFTopology **output_topology, IMFTopology *current_topology)
 {
@@ -2005,10 +2096,26 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
         IMFStreamSink_Release(sink);
     }
 
+    /* resolve each branch */
+    for (i = 0; i < num_connections; i++)
+    {
+        struct topology_node *sink = node_pairs[i][1];
+        struct topology_node *src = node_pairs[i][0];
+
+        if (FAILED(hr = topology_loader_resolve_branch(src, sink, full_topology)))
+        {
+            FIXME("Check for MF_CONNECT_AS_OPTIONAL and MF_CONNECT_AS_OPTIONAL_BRANCH flags.\n");
+            goto out;
+        }
+    }
+
     *output_topology = &full_topology->IMFTopology_iface;
-    hr = S_OK;
+
 out:
+    if (FAILED(hr))
+        IMFTopology_Release(&full_topology->IMFTopology_iface);
     heap_free(node_pairs);
+
     return hr;
 }
 
-- 
2.17.1




More information about the wine-devel mailing list