Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/tests/mf.c | 57 +++++++--------------- dlls/mf/topology.c | 117 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 121 insertions(+), 53 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index e8051eb3ba..2b3fdcd798 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -63,117 +63,101 @@ static void test_topology(void) hr = IMFTopologyNode_SetTopoNodeID(node2, id); ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
+ hr = IMFTopology_GetNodeCount(topology, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IMFTopology_AddNode(topology, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + count = 1; hr = IMFTopology_GetNodeCount(topology, &count); -todo_wine { ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); ok(count == 0, "Unexpected node count %u.\n", count); -} + /* Same id, different nodes. */ hr = IMFTopology_AddNode(topology, node); -todo_wine ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
count = 0; hr = IMFTopology_GetNodeCount(topology, &count); -todo_wine { ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); ok(count == 1, "Unexpected node count %u.\n", count); -} + hr = IMFTopology_AddNode(topology, node2); -todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); IMFTopologyNode_Release(node2);
hr = IMFTopology_GetNodeByID(topology, id, &node2); -todo_wine { ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr); ok(node2 == node, "Unexpected node.\n"); -} - if (SUCCEEDED(hr)) - IMFTopologyNode_Release(node2); + IMFTopologyNode_Release(node2);
/* Change node id, add it again. */ hr = IMFTopologyNode_SetTopoNodeID(node, ++id); ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
hr = IMFTopology_GetNodeByID(topology, id, &node2); -todo_wine { ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr); ok(node2 == node, "Unexpected node.\n"); -} - if (SUCCEEDED(hr)) - IMFTopologyNode_Release(node2); + IMFTopologyNode_Release(node2);
hr = IMFTopology_GetNodeByID(topology, id + 1, &node2); -todo_wine ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr);
hr = IMFTopology_AddNode(topology, node); -todo_wine ok(hr == E_INVALIDARG, "Failed to add a node, hr %#x.\n", hr);
hr = IMFTopology_GetNode(topology, 0, &node2); -todo_wine { ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr); ok(node2 == node, "Unexpected node.\n"); -} - if (SUCCEEDED(hr)) - IMFTopologyNode_Release(node2); + IMFTopologyNode_Release(node2); + + hr = IMFTopology_GetNode(topology, 1, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
hr = IMFTopology_GetNode(topology, 1, &node2); -todo_wine ok(hr == MF_E_INVALIDINDEX, "Failed to get a node, hr %#x.\n", hr);
hr = IMFTopology_GetNode(topology, -2, &node2); -todo_wine ok(hr == MF_E_INVALIDINDEX, "Failed to get a node, hr %#x.\n", hr);
hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2); ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr); hr = IMFTopology_AddNode(topology, node2); -todo_wine ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr); IMFTopologyNode_Release(node2);
count = 0; hr = IMFTopology_GetNodeCount(topology, &count); -todo_wine { ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); ok(count == 2, "Unexpected node count %u.\n", count); -} + /* Remove with detached node, existing id. */ hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2); ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr); hr = IMFTopologyNode_SetTopoNodeID(node2, id); ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr); hr = IMFTopology_RemoveNode(topology, node2); -todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); IMFTopologyNode_Release(node2);
hr = IMFTopology_RemoveNode(topology, node); -todo_wine ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr);
count = 0; hr = IMFTopology_GetNodeCount(topology, &count); -todo_wine { ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); ok(count == 1, "Unexpected node count %u.\n", count); -} + hr = IMFTopology_Clear(topology); -todo_wine ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
count = 1; hr = IMFTopology_GetNodeCount(topology, &count); -todo_wine { ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); ok(count == 0, "Unexpected node count %u.\n", count); -} + hr = IMFTopology_Clear(topology); -todo_wine ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
hr = IMFTopologyNode_SetTopoNodeID(node, 123); @@ -189,11 +173,9 @@ todo_wine ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
hr = IMFTopology_AddNode(topology, node); -todo_wine ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
hr = IMFTopology_AddNode(topology, node2); -todo_wine ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
hr = IMFTopologyNode_GetTopoNodeID(node, &id); @@ -203,12 +185,9 @@ todo_wine ok(hr == S_OK, "Failed to get node id, hr %#x.\n", hr);
hr = IMFTopology_GetNodeByID(topology, id, &node3); -todo_wine { ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr); ok(node3 == node, "Unexpected node.\n"); -} - if (SUCCEEDED(hr)) - IMFTopologyNode_Release(node3); + IMFTopologyNode_Release(node3);
IMFTopologyNode_Release(node); IMFTopologyNode_Release(node2); diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index 54e9faf94a..d8012226f4 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -25,6 +25,7 @@ #include "winbase.h" #include "initguid.h" #include "mfapi.h" +#include "mferror.h" #include "mfidl.h"
#include "wine/debug.h" @@ -39,6 +40,7 @@ struct topology IMFTopology IMFTopology_iface; LONG refcount; IMFAttributes *attributes; + IMFCollection *nodes; };
struct topology_node @@ -113,7 +115,10 @@ static ULONG WINAPI topology_Release(IMFTopology *iface)
if (!refcount) { - IMFAttributes_Release(topology->attributes); + if (topology->attributes) + IMFAttributes_Release(topology->attributes); + if (topology->nodes) + IMFCollection_Release(topology->nodes); heap_free(topology); }
@@ -401,39 +406,117 @@ static HRESULT WINAPI topology_GetTopologyID(IMFTopology *iface, TOPOID *id) return E_NOTIMPL; }
+static HRESULT topology_get_node_by_id(const struct topology *topology, TOPOID id, IMFTopologyNode **node) +{ + IMFTopologyNode *iter; + unsigned int i = 0; + + while (IMFCollection_GetElement(topology->nodes, i, (IUnknown **)&iter) == S_OK) + { + TOPOID node_id; + HRESULT hr; + + hr = IMFTopologyNode_GetTopoNodeID(iter, &node_id); + if (FAILED(hr)) + return hr; + + if (node_id == id) + { + *node = iter; + return S_OK; + } + + ++i; + } + + return MF_E_NOT_FOUND; +} + static HRESULT WINAPI topology_AddNode(IMFTopology *iface, IMFTopologyNode *node) { - FIXME("(%p)->(%p)\n", iface, node); + struct topology *topology = impl_from_IMFTopology(iface); + IMFTopologyNode *match; + HRESULT hr; + TOPOID id;
- return E_NOTIMPL; + TRACE("(%p)->(%p)\n", iface, node); + + if (!node) + return E_POINTER; + + if (FAILED(hr = IMFTopologyNode_GetTopoNodeID(node, &id))) + return hr; + + if (FAILED(topology_get_node_by_id(topology, id, &match))) + return IMFCollection_AddElement(topology->nodes, (IUnknown *)node); + + IMFTopologyNode_Release(match); + + return E_INVALIDARG; }
static HRESULT WINAPI topology_RemoveNode(IMFTopology *iface, IMFTopologyNode *node) { - FIXME("(%p)->(%p)\n", iface, node); + struct topology *topology = impl_from_IMFTopology(iface); + unsigned int i = 0; + IUnknown *element;
- return E_NOTIMPL; + TRACE("(%p)->(%p)\n", iface, node); + + while (IMFCollection_GetElement(topology->nodes, i, &element) == S_OK) + { + BOOL match = element == (IUnknown *)node; + + IUnknown_Release(element); + + if (match) + { + IMFCollection_RemoveElement(topology->nodes, i, &element); + IUnknown_Release(element); + return S_OK; + } + + ++i; + } + + return E_INVALIDARG; }
static HRESULT WINAPI topology_GetNodeCount(IMFTopology *iface, WORD *count) { - FIXME("(%p)->(%p)\n", iface, count); + struct topology *topology = impl_from_IMFTopology(iface); + DWORD nodecount; + HRESULT hr;
- return E_NOTIMPL; + TRACE("(%p)->(%p)\n", iface, count); + + hr = IMFCollection_GetElementCount(topology->nodes, count ? &nodecount : NULL); + if (count) + *count = nodecount; + + return hr; }
static HRESULT WINAPI topology_GetNode(IMFTopology *iface, WORD index, IMFTopologyNode **node) { - FIXME("(%p)->(%u, %p)\n", iface, index, node); + struct topology *topology = impl_from_IMFTopology(iface);
- return E_NOTIMPL; + TRACE("(%p)->(%u, %p)\n", iface, index, node); + + if (!node) + return E_POINTER; + + return SUCCEEDED(IMFCollection_GetElement(topology->nodes, index, (IUnknown **)node)) ? + S_OK : MF_E_INVALIDINDEX; }
static HRESULT WINAPI topology_Clear(IMFTopology *iface) { - FIXME("(%p)\n", iface); + struct topology *topology = impl_from_IMFTopology(iface);
- return E_NOTIMPL; + TRACE("(%p)\n", iface); + + return IMFCollection_RemoveAllElements(topology->nodes); }
static HRESULT WINAPI topology_CloneFrom(IMFTopology *iface, IMFTopology *src_topology) @@ -445,9 +528,11 @@ static HRESULT WINAPI topology_CloneFrom(IMFTopology *iface, IMFTopology *src_to
static HRESULT WINAPI topology_GetNodeByID(IMFTopology *iface, TOPOID id, IMFTopologyNode **node) { - FIXME("(%p)->(%p)\n", iface, node); + struct topology *topology = impl_from_IMFTopology(iface);
- return E_NOTIMPL; + TRACE("(%p)->(%p)\n", iface, node); + + return topology_get_node_by_id(topology, id, node); }
static HRESULT WINAPI topology_GetSourceNodeCollection(IMFTopology *iface, IMFCollection **collection) @@ -530,10 +615,14 @@ HRESULT WINAPI MFCreateTopology(IMFTopology **topology)
object->IMFTopology_iface.lpVtbl = &topologyvtbl; object->refcount = 1; + hr = MFCreateAttributes(&object->attributes, 0); + if (SUCCEEDED(hr)) + hr = MFCreateCollection(&object->nodes); + if (FAILED(hr)) { - heap_free(object); + IMFTopology_Release(&object->IMFTopology_iface); return hr; }