mf: Implement SetObject()/GetObject() for topology node.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2019-05-06 13:52:15 +03:00 committed by Alexandre Julliard
parent 9092f1f3da
commit c1d023565a
3 changed files with 158 additions and 5 deletions

View file

@ -1,5 +1,5 @@
TESTDLL = mf.dll
IMPORTS = mf mfplat
IMPORTS = mf mfplat mfuuid
C_SRCS = \
mf.c

View file

@ -27,6 +27,12 @@
#include "winbase.h"
#include "initguid.h"
#include "ole2.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
#undef INITGUID
#include <guiddef.h>
#include "mfapi.h"
#include "mferror.h"
#include "mfidl.h"
@ -35,11 +41,45 @@
DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
static HRESULT WINAPI test_unk_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IUnknown))
{
*obj = iface;
IUnknown_AddRef(iface);
return S_OK;
}
*obj = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI test_unk_AddRef(IUnknown *iface)
{
return 2;
}
static ULONG WINAPI test_unk_Release(IUnknown *iface)
{
return 1;
}
static const IUnknownVtbl test_unk_vtbl =
{
test_unk_QueryInterface,
test_unk_AddRef,
test_unk_Release,
};
static void test_topology(void)
{
IMFCollection *collection, *collection2;
IUnknown test_unk2 = { &test_unk_vtbl };
IUnknown test_unk = { &test_unk_vtbl };
IMFTopologyNode *node, *node2, *node3;
IMFTopology *topology, *topology2;
UINT32 attr_count;
IUnknown *object;
DWORD size;
WORD count;
HRESULT hr;
@ -302,6 +342,49 @@ static void test_topology(void)
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);
/* Associated object. */
hr = IMFTopologyNode_SetObject(node, NULL);
ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
hr = IMFTopologyNode_GetObject(node, NULL);
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
object = (void *)0xdeadbeef;
hr = IMFTopologyNode_GetObject(node, &object);
ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
ok(!object, "Unexpected object %p.\n", object);
hr = IMFTopologyNode_SetObject(node, &test_unk);
ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
hr = IMFTopologyNode_GetObject(node, &object);
ok(hr == S_OK, "Failed to get object, hr %#x.\n", hr);
ok(object == &test_unk, "Unexpected object %p.\n", object);
IUnknown_Release(object);
hr = IMFTopologyNode_SetObject(node, &test_unk2);
ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
hr = IMFTopologyNode_GetCount(node, &attr_count);
ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
ok(attr_count == 0, "Unexpected attribute count %u.\n", attr_count);
hr = IMFTopologyNode_SetGUID(node, &MF_TOPONODE_TRANSFORM_OBJECTID, &MF_TOPONODE_TRANSFORM_OBJECTID);
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
hr = IMFTopologyNode_SetObject(node, NULL);
ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
object = (void *)0xdeadbeef;
hr = IMFTopologyNode_GetObject(node, &object);
ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
ok(!object, "Unexpected object %p.\n", object);
hr = IMFTopologyNode_GetCount(node, &attr_count);
ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
ok(attr_count == 1, "Unexpected attribute count %u.\n", attr_count);
IMFTopologyNode_Release(node);
hr = IMFTopology_GetOutputNodeCollection(topology, &collection);

View file

@ -25,7 +25,13 @@
#include "windef.h"
#include "winbase.h"
#include "initguid.h"
#include "ole2.h"
#include "ocidl.h"
#undef INITGUID
#include <guiddef.h>
#include "mfapi.h"
#include "mferror.h"
#include "mfidl.h"
@ -54,6 +60,8 @@ struct topology_node
IMFAttributes *attributes;
MF_TOPOLOGY_TYPE node_type;
TOPOID id;
IUnknown *object;
CRITICAL_SECTION cs;
};
struct topology_loader
@ -755,7 +763,10 @@ static ULONG WINAPI topology_node_Release(IMFTopologyNode *iface)
if (!refcount)
{
if (node->object)
IUnknown_Release(node->object);
IMFAttributes_Release(node->attributes);
DeleteCriticalSection(&node->cs);
heap_free(node);
}
@ -1038,16 +1049,74 @@ static HRESULT WINAPI topology_node_CopyAllItems(IMFTopologyNode *iface, IMFAttr
static HRESULT WINAPI topology_node_SetObject(IMFTopologyNode *iface, IUnknown *object)
{
FIXME("(%p)->(%p)\n", iface, object);
static const GUID *iids[3] = { &IID_IPersist, &IID_IPersistStorage, &IID_IPersistPropertyBag };
struct topology_node *node = impl_from_IMFTopologyNode(iface);
IPersist *persist = NULL;
BOOL has_object_id;
GUID object_id;
unsigned int i;
HRESULT hr;
return E_NOTIMPL;
TRACE("%p, %p.\n", iface, object);
has_object_id = IMFAttributes_GetGUID(node->attributes, &MF_TOPONODE_TRANSFORM_OBJECTID, &object_id) == S_OK;
if (object && !has_object_id)
{
for (i = 0; i < ARRAY_SIZE(iids); ++i)
{
persist = NULL;
if (SUCCEEDED(hr = IUnknown_QueryInterface(object, iids[i], (void **)&persist)))
break;
}
if (persist)
{
if (FAILED(hr = IPersist_GetClassID(persist, &object_id)))
{
IPersist_Release(persist);
persist = NULL;
}
}
}
EnterCriticalSection(&node->cs);
if (node->object)
IUnknown_Release(node->object);
node->object = object;
if (node->object)
IUnknown_AddRef(node->object);
if (persist)
IMFAttributes_SetGUID(node->attributes, &MF_TOPONODE_TRANSFORM_OBJECTID, &object_id);
LeaveCriticalSection(&node->cs);
if (persist)
IPersist_Release(persist);
return S_OK;
}
static HRESULT WINAPI topology_node_GetObject(IMFTopologyNode *iface, IUnknown **object)
{
FIXME("(%p)->(%p)\n", iface, object);
struct topology_node *node = impl_from_IMFTopologyNode(iface);
return E_NOTIMPL;
TRACE("%p, %p.\n", iface, object);
if (!object)
return E_POINTER;
EnterCriticalSection(&node->cs);
*object = node->object;
if (*object)
IUnknown_AddRef(*object);
LeaveCriticalSection(&node->cs);
return *object ? S_OK : E_FAIL;
}
static HRESULT WINAPI topology_node_GetNodeType(IMFTopologyNode *iface, MF_TOPOLOGY_TYPE *node_type)
@ -1243,6 +1312,7 @@ HRESULT WINAPI MFCreateTopologyNode(MF_TOPOLOGY_TYPE node_type, IMFTopologyNode
return hr;
}
object->id = ((TOPOID)GetCurrentProcessId() << 32) | InterlockedIncrement(&next_node_id);
InitializeCriticalSection(&object->cs);
*node = &object->IMFTopologyNode_iface;