mfplat: Implement IMFAttributes::{SetItem,GetItem}.

Signed-off-by: Jactry Zeng <jzeng@codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jactry Zeng 2019-03-14 11:03:08 +03:00 committed by Alexandre Julliard
parent fc4ebe1590
commit 7edec69cd7
3 changed files with 165 additions and 7 deletions

View File

@ -642,11 +642,41 @@ static ULONG WINAPI mfattributes_Release(IMFAttributes *iface)
return refcount;
}
static struct attribute *attributes_find_item(struct attributes *attributes, REFGUID key, size_t *index)
{
size_t i;
for (i = 0; i < attributes->count; ++i)
{
if (IsEqualGUID(key, &attributes->attributes[i].key))
{
if (index)
*index = i;
return &attributes->attributes[i];
}
}
return NULL;
}
static HRESULT WINAPI mfattributes_GetItem(IMFAttributes *iface, REFGUID key, PROPVARIANT *value)
{
FIXME("%p, %s, %p.\n", iface, debugstr_attr(key), value);
struct attributes *attributes = impl_from_IMFAttributes(iface);
struct attribute *attribute;
HRESULT hr;
return E_NOTIMPL;
TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
EnterCriticalSection(&attributes->cs);
if ((attribute = attributes_find_item(attributes, key, NULL)))
hr = PropVariantCopy(value, &attribute->value);
else
hr = MF_E_ATTRIBUTENOTFOUND;
LeaveCriticalSection(&attributes->cs);
return hr;
}
static HRESULT WINAPI mfattributes_GetItemType(IMFAttributes *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
@ -753,11 +783,56 @@ static HRESULT WINAPI mfattributes_GetUnknown(IMFAttributes *iface, REFGUID key,
return E_NOTIMPL;
}
static HRESULT WINAPI mfattributes_SetItem(IMFAttributes *iface, REFGUID key, REFPROPVARIANT Value)
static HRESULT attributes_set_item(struct attributes *attributes, REFGUID key, REFPROPVARIANT value)
{
FIXME("%p, %s, %p.\n", iface, debugstr_attr(key), Value);
struct attribute *attribute;
return E_NOTIMPL;
EnterCriticalSection(&attributes->cs);
attribute = attributes_find_item(attributes, key, NULL);
if (!attribute)
{
if (!mf_array_reserve((void **)&attributes->attributes, &attributes->capacity, attributes->count + 1,
sizeof(*attributes->attributes)))
{
LeaveCriticalSection(&attributes->cs);
return E_OUTOFMEMORY;
}
attributes->attributes[attributes->count].key = *key;
attribute = &attributes->attributes[attributes->count++];
}
else
PropVariantClear(&attribute->value);
PropVariantCopy(&attribute->value, value);
LeaveCriticalSection(&attributes->cs);
return S_OK;
}
static HRESULT WINAPI mfattributes_SetItem(IMFAttributes *iface, REFGUID key, REFPROPVARIANT value)
{
struct attributes *attributes = impl_from_IMFAttributes(iface);
PROPVARIANT empty;
TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
switch (value->vt)
{
case MF_ATTRIBUTE_UINT32:
case MF_ATTRIBUTE_UINT64:
case MF_ATTRIBUTE_DOUBLE:
case MF_ATTRIBUTE_GUID:
case MF_ATTRIBUTE_STRING:
case MF_ATTRIBUTE_BLOB:
case MF_ATTRIBUTE_IUNKNOWN:
return attributes_set_item(attributes, key, value);
default:
PropVariantInit(&empty);
attributes_set_item(attributes, key, &empty);
return MF_E_INVALIDTYPE;
}
}
static HRESULT WINAPI mfattributes_DeleteItem(IMFAttributes *iface, REFGUID key)

View File

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

View File

@ -35,6 +35,7 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19);
DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21);
DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22);
DEFINE_GUID(DUMMY_GUID3, 0x12345678,0x1234,0x1234,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23);
#undef INITGUID
#include <guiddef.h>
@ -42,6 +43,7 @@ DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,
#include "mfidl.h"
#include "mferror.h"
#include "mfreadwrite.h"
#include "propvarutil.h"
#include "wine/test.h"
@ -498,9 +500,10 @@ static void test_MFCreateMediaEvent(void)
static void test_MFCreateAttributes(void)
{
PROPVARIANT propvar, ret_propvar;
IMFAttributes *attributes;
HRESULT hr;
UINT32 count;
HRESULT hr;
hr = MFCreateAttributes( &attributes, 3 );
ok(hr == S_OK, "got 0x%08x\n", hr);
@ -518,6 +521,86 @@ static void test_MFCreateAttributes(void)
todo_wine ok(count == 1, "got %d\n", count);
IMFAttributes_Release(attributes);
hr = MFCreateAttributes(&attributes, 0);
ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
PropVariantInit(&propvar);
propvar.vt = MF_ATTRIBUTE_UINT32;
U(propvar).ulVal = 123;
hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
PropVariantInit(&ret_propvar);
ret_propvar.vt = MF_ATTRIBUTE_UINT32;
U(ret_propvar).ulVal = 0xdeadbeef;
hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
PropVariantClear(&ret_propvar);
PropVariantInit(&ret_propvar);
ret_propvar.vt = MF_ATTRIBUTE_STRING;
U(ret_propvar).pwszVal = NULL;
hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
PropVariantClear(&ret_propvar);
PropVariantClear(&propvar);
PropVariantInit(&propvar);
propvar.vt = MF_ATTRIBUTE_UINT64;
U(propvar).uhVal.QuadPart = 65536;
hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
PropVariantInit(&ret_propvar);
ret_propvar.vt = MF_ATTRIBUTE_UINT32;
U(ret_propvar).ulVal = 0xdeadbeef;
hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
PropVariantClear(&ret_propvar);
PropVariantClear(&propvar);
PropVariantInit(&propvar);
propvar.vt = VT_I4;
U(propvar).lVal = 123;
hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#x.\n", hr);
PropVariantInit(&ret_propvar);
ret_propvar.vt = MF_ATTRIBUTE_UINT32;
U(ret_propvar).lVal = 0xdeadbeef;
hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
PropVariantClear(&propvar);
ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
PropVariantClear(&ret_propvar);
PropVariantInit(&propvar);
propvar.vt = MF_ATTRIBUTE_UINT32;
U(propvar).ulVal = 123;
hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
todo_wine ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
PropVariantClear(&ret_propvar);
PropVariantClear(&propvar);
propvar.vt = MF_ATTRIBUTE_UINT64;
U(propvar).uhVal.QuadPart = 65536;
hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
PropVariantClear(&ret_propvar);
PropVariantClear(&propvar);
IMFAttributes_Release(attributes);
}
static void test_MFCreateMFByteStreamOnStream(void)