From b474b9138c0297b9cd44dcd0675de4dbaf5d624a Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 25 Feb 2019 11:33:50 +0300 Subject: [PATCH] mf: Add support for source and output collections. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- 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 2b3fdcd798a..21d8be80c8e 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 d8012226f49..3b4a2e1a58c 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 =