[PATCH 5/7] mf/topoloader: Make sure MF_TOPONODE_STREAMID is set for all outputs.

Nikolay Sivov nsivov at codeweavers.com
Tue Dec 1 06:16:27 CST 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mf/tests/mf.c | 131 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/mf/topology.c |  29 ++++++++++
 2 files changed, 158 insertions(+), 2 deletions(-)

diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 4d4c6283be8..c36a76d83bb 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -1622,8 +1622,11 @@ static void init_source_node(IMFMediaType *mediatype, IMFMediaSource *source, IM
     hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd);
     ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr);
 
-    hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_SOURCE, (IUnknown *)source);
-    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    if (source)
+    {
+        hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_SOURCE, (IUnknown *)source);
+        ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    }
 
     IMFStreamDescriptor_Release(sd);
 }
@@ -2121,6 +2124,129 @@ todo_wine {
     ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
 }
 
+static void test_topology_loader_evr(void)
+{
+    IMFTopologyNode *node, *source_node, *evr_node;
+    IMFTopology *topology, *full_topology;
+    IMFMediaTypeHandler *handler;
+    unsigned int i, count, value;
+    IMFStreamSink *stream_sink;
+    IMFMediaType *media_type;
+    IMFActivate *activate;
+    IMFTopoLoader *loader;
+    IMFMediaSink *sink;
+    WORD node_count;
+    HWND window;
+    HRESULT hr;
+
+    hr = CoInitialize(NULL);
+    ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
+
+    hr = MFCreateTopoLoader(&loader);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    /* Source node. */
+    hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &source_node);
+    ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
+
+    hr = MFCreateMediaType(&media_type);
+    ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
+
+    hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    hr = IMFMediaType_SetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    init_source_node(media_type, NULL, source_node);
+
+    /* EVR sink node. */
+    window = create_window();
+
+    hr = MFCreateVideoRendererActivate(window, &activate);
+    ok(hr == S_OK, "Failed to create activate object, hr %#x.\n", hr);
+
+    hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaSink_GetStreamSinkById(sink, 0, &stream_sink);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &evr_node);
+    ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
+
+    hr = IMFTopologyNode_SetObject(evr_node, (IUnknown *)stream_sink);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &handler);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    IMFMediaTypeHandler_Release(handler);
+
+    IMFStreamSink_Release(stream_sink);
+    IMFMediaSink_Release(sink);
+
+    hr = MFCreateTopology(&topology);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFTopology_AddNode(topology, source_node);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    hr = IMFTopology_AddNode(topology, evr_node);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    hr = IMFTopologyNode_ConnectOutput(source_node, 0, evr_node, 0);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFTopologyNode_SetUINT32(evr_node, &MF_TOPONODE_CONNECT_METHOD, MF_CONNECT_DIRECT);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFTopologyNode_GetCount(evr_node, &count);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(count == 1, "Unexpected attribute count %u.\n", count);
+
+    hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFTopology_GetNodeCount(full_topology, &node_count);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+todo_wine
+    ok(node_count == 3, "Unexpected node count %u.\n", node_count);
+
+    for (i = 0; i < node_count; ++i)
+    {
+        MF_TOPOLOGY_TYPE node_type;
+
+        hr = IMFTopology_GetNode(full_topology, i, &node);
+        ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+        hr = IMFTopologyNode_GetNodeType(node, &node_type);
+        ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+        if (node_type == MF_TOPOLOGY_OUTPUT_NODE)
+        {
+            value = 1;
+            hr = IMFTopologyNode_GetUINT32(node, &MF_TOPONODE_STREAMID, &value);
+            ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+            ok(!value, "Unexpected stream id %u.\n", value);
+        }
+    }
+
+    IMFTopology_Release(full_topology);
+
+    IMFTopoLoader_Release(loader);
+
+    IMFTopologyNode_Release(source_node);
+    IMFTopologyNode_Release(evr_node);
+    IMFTopology_Release(topology);
+    IMFMediaType_Release(media_type);
+    DestroyWindow(window);
+
+    CoUninitialize();
+}
+
 static HRESULT WINAPI testshutdown_QueryInterface(IMFShutdown *iface, REFIID riid, void **obj)
 {
     if (IsEqualIID(riid, &IID_IMFShutdown) ||
@@ -4859,6 +4985,7 @@ START_TEST(mf)
     test_topology();
     test_topology_tee_node();
     test_topology_loader();
+    test_topology_loader_evr();
     test_MFGetService();
     test_sequencer_source();
     test_media_session();
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
index 77baa1128c4..6f73bb859cd 100644
--- a/dlls/mf/topology.c
+++ b/dlls/mf/topology.c
@@ -2364,6 +2364,32 @@ static HRESULT topology_loader_resolve_nodes(struct topoloader_context *context,
     return hr;
 }
 
+static void topology_loader_resolve_complete(struct topoloader_context *context)
+{
+    MF_TOPOLOGY_TYPE node_type;
+    IMFTopologyNode *node;
+    WORD i, node_count;
+
+    IMFTopology_GetNodeCount(context->output_topology, &node_count);
+
+    for (i = 0; i < node_count; ++i)
+    {
+        if (SUCCEEDED(IMFTopology_GetNode(context->output_topology, i, &node)))
+        {
+            IMFTopologyNode_GetNodeType(node, &node_type);
+
+            if (node_type == MF_TOPOLOGY_OUTPUT_NODE)
+            {
+                /* Make sure MF_TOPONODE_STREAMID is set for all outputs. */
+                if (FAILED(IMFTopologyNode_GetItem(node, &MF_TOPONODE_STREAMID, NULL)))
+                    IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_STREAMID, 0);
+            }
+
+            IMFTopologyNode_Release(node);
+        }
+    }
+}
+
 static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *input_topology,
         IMFTopology **ret_topology, IMFTopology *current_topology)
 {
@@ -2451,6 +2477,9 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in
             break;
     }
 
+    if (SUCCEEDED(hr))
+        topology_loader_resolve_complete(&context);
+
     *ret_topology = output_topology;
 
     return hr;
-- 
2.29.2




More information about the wine-devel mailing list