Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
v2: fixes test crashes on older versions
dlls/mf/tests/mf.c | 110 +++++++++++++++++++++++++++++++++++++++++++++
dlls/mf/topology.c | 55 +++++++++++++++++++++--
2 files changed, 161 insertions(+), 4 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 2b3fdcd798..21d8be80c8 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -35,8 +35,10 @@
static void test_topology(void)
{
+ IMFCollection *collection, *collection2;
IMFTopologyNode *node, *node2, *node3;
IMFTopology *topology;
+ DWORD size;
WORD count;
HRESULT hr;
TOPOID id;
@@ -192,6 +194,114 @@ static void test_topology(void)
IMFTopologyNode_Release(node);
IMFTopologyNode_Release(node2);
+ /* Source/output collections. */
+ hr = IMFTopology_Clear(topology);
+ ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
+
+ hr = IMFTopology_GetSourceNodeCollection(topology, NULL);
+ ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
+ ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
+ ok(!!collection, "Unexpected object pointer.\n");
+
+ hr = IMFTopology_GetSourceNodeCollection(topology, &collection2);
+ ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
+ ok(!!collection2, "Unexpected object pointer.\n");
+ ok(collection2 != collection, "Expected cloned collection.\n");
+
+ hr = IMFCollection_GetElementCount(collection, &size);
+ ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
+ ok(!size, "Unexpected item count.\n");
+
+ hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
+ ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
+
+ hr = IMFCollection_GetElementCount(collection, &size);
+ ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
+ ok(size == 1, "Unexpected item count.\n");
+
+ hr = IMFCollection_GetElementCount(collection2, &size);
+ ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
+ ok(!size, "Unexpected item count.\n");
+
+ IMFCollection_Release(collection2);
+ IMFCollection_Release(collection);
+
+ /* Add some nodes. */
+ hr = IMFTopology_GetSourceNodeCollection(topology, NULL);
+ ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTopology_GetOutputNodeCollection(topology, NULL);
+ ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+ hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
+ ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
+ hr = IMFTopology_AddNode(topology, node);
+ ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
+ IMFTopologyNode_Release(node);
+
+ hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
+ ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
+ ok(!!collection, "Unexpected object pointer.\n");
+ hr = IMFCollection_GetElementCount(collection, &size);
+ ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
+ ok(size == 1, "Unexpected item count.\n");
+ IMFCollection_Release(collection);
+
+ hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node);
+ ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
+ hr = IMFTopology_AddNode(topology, node);
+ ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
+ IMFTopologyNode_Release(node);
+
+ hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
+ ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
+ ok(!!collection, "Unexpected object pointer.\n");
+ hr = IMFCollection_GetElementCount(collection, &size);
+ ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
+ ok(size == 1, "Unexpected item count.\n");
+ IMFCollection_Release(collection);
+
+ hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node);
+ ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
+ hr = IMFTopology_AddNode(topology, node);
+ ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
+ IMFTopologyNode_Release(node);
+
+ hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
+ ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
+ ok(!!collection, "Unexpected object pointer.\n");
+ hr = IMFCollection_GetElementCount(collection, &size);
+ ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
+ ok(size == 1, "Unexpected item count.\n");
+ IMFCollection_Release(collection);
+
+ hr = IMFTopology_GetOutputNodeCollection(topology, &collection);
+ ok(hr == S_OK || broken(hr == E_FAIL) /* before Win8 */, "Failed to get source node collection, hr %#x.\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ ok(!!collection, "Unexpected object pointer.\n");
+ hr = IMFCollection_GetElementCount(collection, &size);
+ ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
+ ok(!size, "Unexpected item count.\n");
+ IMFCollection_Release(collection);
+
+ hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node);
+ ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
+ hr = IMFTopology_AddNode(topology, node);
+ ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
+ IMFTopologyNode_Release(node);
+
+ hr = IMFTopology_GetOutputNodeCollection(topology, &collection);
+ ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
+ ok(!!collection, "Unexpected object pointer.\n");
+ hr = IMFCollection_GetElementCount(collection, &size);
+ ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
+ ok(size == 1, "Unexpected item count.\n");
+ IMFCollection_Release(collection);
+ }
+
IMFTopology_Release(topology);
}
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
index d8012226f4..3b4a2e1a58 100644
--- a/dlls/mf/topology.c
+++ b/dlls/mf/topology.c
@@ -535,18 +535,65 @@ static HRESULT WINAPI topology_GetNodeByID(IMFTopology *iface, TOPOID id, IMFTop
return topology_get_node_by_id(topology, id, node);
}
+static HRESULT topology_add_node_of_type(const struct topology *topology, IMFTopologyNode *node,
+ MF_TOPOLOGY_TYPE filter, IMFCollection *collection)
+{
+ MF_TOPOLOGY_TYPE node_type;
+ HRESULT hr;
+
+ if (FAILED(hr = IMFTopologyNode_GetNodeType(node, &node_type)))
+ return hr;
+
+ if (node_type != filter)
+ return S_OK;
+
+ return IMFCollection_AddElement(collection, (IUnknown *)node);
+}
+
+static HRESULT topology_get_node_collection(const struct topology *topology, MF_TOPOLOGY_TYPE node_type,
+ IMFCollection **collection)
+{
+ IMFTopologyNode *node;
+ unsigned int i = 0;
+ HRESULT hr;
+
+ if (!collection)
+ return E_POINTER;
+
+ if (FAILED(hr = MFCreateCollection(collection)))
+ return hr;
+
+ while (IMFCollection_GetElement(topology->nodes, i++, (IUnknown **)&node) == S_OK)
+ {
+ hr = topology_add_node_of_type(topology, node, node_type, *collection);
+ IMFTopologyNode_Release(node);
+ if (FAILED(hr))
+ {
+ IMFCollection_Release(*collection);
+ *collection = NULL;
+ break;
+ }
+ }
+
+ return hr;
+}
+
static HRESULT WINAPI topology_GetSourceNodeCollection(IMFTopology *iface, IMFCollection **collection)
{
- FIXME("(%p)->(%p)\n", iface, collection);
+ struct topology *topology = impl_from_IMFTopology(iface);
- return E_NOTIMPL;
+ TRACE("(%p)->(%p)\n", iface, collection);
+
+ return topology_get_node_collection(topology, MF_TOPOLOGY_SOURCESTREAM_NODE, collection);
}
static HRESULT WINAPI topology_GetOutputNodeCollection(IMFTopology *iface, IMFCollection **collection)
{
- FIXME("(%p)->(%p)\n", iface, collection);
+ struct topology *topology = impl_from_IMFTopology(iface);
- return E_NOTIMPL;
+ TRACE("(%p)->(%p)\n", iface, collection);
+
+ return topology_get_node_collection(topology, MF_TOPOLOGY_OUTPUT_NODE, collection);
}
static const IMFTopologyVtbl topologyvtbl =
--
2.20.1