Nikolay Sivov : mf: Disconnect removed nodes.
Alexandre Julliard
julliard at winehq.org
Wed May 8 18:22:47 CDT 2019
Module: wine
Branch: master
Commit: 37a7b65140c928de8e029d5bea3d27ba1c346573
URL: https://source.winehq.org/git/wine.git/?a=commit;h=37a7b65140c928de8e029d5bea3d27ba1c346573
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed May 8 14:46:42 2019 +0300
mf: Disconnect removed nodes.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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 8b3b8b4..ff3290a 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 c10bc6a..e10bc8b 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)
{
More information about the wine-cvs
mailing list