From 37a7b65140c928de8e029d5bea3d27ba1c346573 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 8 May 2019 14:46:42 +0300 Subject: [PATCH] mf: Disconnect removed nodes. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/mf/tests/mf.c | 10 ++-- dlls/mf/topology.c | 123 ++++++++++++++++++++++++++------------------- 2 files changed, 74 insertions(+), 59 deletions(-) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 8b3b8b43738..ff3290a158b 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -589,10 +589,9 @@ static void test_topology(void) hr = IMFTopology_Clear(topology); ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr); -todo_wine { EXPECT_REF(node, 1); EXPECT_REF(node2, 1); -} + /* Removing connected node breaks connection. */ hr = IMFTopology_AddNode(topology, node); ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr); @@ -606,12 +605,10 @@ todo_wine { hr = IMFTopology_RemoveNode(topology, node); ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr); -todo_wine { EXPECT_REF(node, 1); EXPECT_REF(node2, 2); -} + hr = IMFTopologyNode_GetOutput(node, 0, &node3, &index); -todo_wine ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr); hr = IMFTopology_AddNode(topology, node); @@ -623,10 +620,9 @@ todo_wine hr = IMFTopology_RemoveNode(topology, node2); ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr); -todo_wine { EXPECT_REF(node, 2); EXPECT_REF(node2, 1); -} + IMFTopologyNode_Release(node); IMFTopologyNode_Release(node2); diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index c10bc6ad02d..e10bc8b07d0 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -174,12 +174,81 @@ static ULONG WINAPI topology_AddRef(IMFTopology *iface) return refcount; } +static HRESULT topology_node_disconnect_output(struct topology_node *node, DWORD output_index) +{ + struct topology_node *connection = NULL; + struct node_stream *stream; + DWORD connection_stream; + HRESULT hr = S_OK; + + EnterCriticalSection(&node->cs); + + if (output_index < node->outputs.count) + { + stream = &node->outputs.streams[output_index]; + + if (stream->connection) + { + connection = stream->connection; + connection_stream = stream->connection_stream; + stream->connection = NULL; + stream->connection_stream = 0; + } + else + hr = MF_E_NOT_FOUND; + } + else + hr = E_INVALIDARG; + + LeaveCriticalSection(&node->cs); + + if (connection) + { + EnterCriticalSection(&connection->cs); + + if (connection_stream < connection->inputs.count) + { + stream = &connection->inputs.streams[connection_stream]; + + if (stream->connection) + { + stream->connection = NULL; + stream->connection_stream = 0; + } + } + + LeaveCriticalSection(&connection->cs); + + IMFTopologyNode_Release(&connection->IMFTopologyNode_iface); + IMFTopologyNode_Release(&node->IMFTopologyNode_iface); + } + + return hr; +} + +static void topology_node_disconnect(struct topology_node *node) +{ + struct node_stream *stream; + size_t i; + + for (i = 0; i < node->outputs.count; ++i) + topology_node_disconnect_output(node, i); + + for (i = 0; i < node->inputs.count; ++i) + { + stream = &node->inputs.streams[i]; + if (stream->connection) + topology_node_disconnect_output(stream->connection, stream->connection_stream); + } +} + static void topology_clear(struct topology *topology) { size_t i; for (i = 0; i < topology->nodes.count; ++i) { + topology_node_disconnect(topology->nodes.nodes[i]); IMFTopologyNode_Release(&topology->nodes.nodes[i]->IMFTopologyNode_iface); } heap_free(topology->nodes.nodes); @@ -551,6 +620,8 @@ static HRESULT WINAPI topology_RemoveNode(IMFTopology *iface, IMFTopologyNode *n { if (&topology->nodes.nodes[i]->IMFTopologyNode_iface == node) { + topology_node_disconnect(topology->nodes.nodes[i]); + IMFTopologyNode_Release(&topology->nodes.nodes[i]->IMFTopologyNode_iface); count = topology->nodes.count - i - 1; if (count) { @@ -1248,58 +1319,6 @@ static HRESULT WINAPI topology_node_GetOutputCount(IMFTopologyNode *iface, DWORD return S_OK; } -static HRESULT topology_node_disconnect_output(struct topology_node *node, DWORD output_index) -{ - struct topology_node *connection = NULL; - struct node_stream *stream; - DWORD connection_stream; - HRESULT hr = S_OK; - - EnterCriticalSection(&node->cs); - - if (output_index < node->outputs.count) - { - stream = &node->outputs.streams[output_index]; - - if (stream->connection) - { - connection = stream->connection; - connection_stream = stream->connection_stream; - stream->connection = NULL; - stream->connection_stream = 0; - } - else - hr = MF_E_NOT_FOUND; - } - else - hr = E_INVALIDARG; - - LeaveCriticalSection(&node->cs); - - if (connection) - { - EnterCriticalSection(&connection->cs); - - if (connection_stream < connection->inputs.count) - { - stream = &connection->inputs.streams[connection_stream]; - - if (stream->connection) - { - stream->connection = NULL; - stream->connection_stream = 0; - } - } - - LeaveCriticalSection(&connection->cs); - - IMFTopologyNode_Release(&connection->IMFTopologyNode_iface); - IMFTopologyNode_Release(&node->IMFTopologyNode_iface); - } - - return hr; -} - static HRESULT WINAPI topology_node_ConnectOutput(IMFTopologyNode *iface, DWORD output_index, IMFTopologyNode *peer, DWORD input_index) {