Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/mfplat/main.c | 101 +++++++++++++++--
dlls/mfplat/tests/mfplat.c | 223 ++++++++++++++++++++++++++++++++++++-
2 files changed, 315 insertions(+), 9 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 88945f6724..4589840c21 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -724,9 +724,24 @@ static HRESULT WINAPI mfattributes_GetItem(IMFAttributes *iface, REFGUID key, PR
static HRESULT WINAPI mfattributes_GetItemType(IMFAttributes *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
{
- FIXME("%p, %s, %p.\n", iface, debugstr_attr(key), type);
+ struct attributes *attributes = impl_from_IMFAttributes(iface);
+ struct attribute *attribute;
+ HRESULT hr = S_OK;
- return E_NOTIMPL;
+ TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), type);
+
+ EnterCriticalSection(&attributes->cs);
+
+ if ((attribute = attributes_find_item(attributes, key, NULL)))
+ {
+ *type = attribute->value.vt;
+ }
+ else
+ hr = MF_E_ATTRIBUTENOTFOUND;
+
+ LeaveCriticalSection(&attributes->cs);
+
+ return hr;
}
static HRESULT WINAPI mfattributes_CompareItem(IMFAttributes *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
@@ -748,14 +763,86 @@ static HRESULT WINAPI mfattributes_CompareItem(IMFAttributes *iface, REFGUID key
return S_OK;
}
-static HRESULT WINAPI mfattributes_Compare(IMFAttributes *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
- BOOL *result)
+static HRESULT WINAPI mfattributes_Compare(IMFAttributes *iface, IMFAttributes *theirs,
+ MF_ATTRIBUTES_MATCH_TYPE match_type, BOOL *ret)
{
- mfattributes *This = impl_from_IMFAttributes(iface);
+ struct attributes *attributes = impl_from_IMFAttributes(iface);
+ IMFAttributes *smaller, *other;
+ MF_ATTRIBUTE_TYPE type;
+ HRESULT hr = S_OK;
+ UINT32 count;
+ BOOL result;
+ size_t i;
- FIXME("%p, %p, %d, %p\n", This, theirs, type, result);
+ TRACE("%p, %p, %d, %p.\n", iface, theirs, match_type, ret);
- return E_NOTIMPL;
+ if (FAILED(hr = IMFAttributes_GetCount(theirs, &count)))
+ return hr;
+
+ EnterCriticalSection(&attributes->cs);
+
+ result = TRUE;
+
+ switch (match_type)
+ {
+ case MF_ATTRIBUTES_MATCH_OUR_ITEMS:
+ for (i = 0; i < attributes->count; ++i)
+ {
+ if (FAILED(hr = IMFAttributes_CompareItem(theirs, &attributes->attributes[i].key,
+ &attributes->attributes[i].value, &result)))
+ break;
+ if (!result)
+ break;
+ }
+ break;
+ case MF_ATTRIBUTES_MATCH_THEIR_ITEMS:
+ hr = IMFAttributes_Compare(theirs, iface, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+ break;
+ case MF_ATTRIBUTES_MATCH_ALL_ITEMS:
+ if (count != attributes->count)
+ {
+ result = FALSE;
+ break;
+ }
+ for (i = 0; i < count; ++i)
+ {
+ if (FAILED(hr = IMFAttributes_CompareItem(theirs, &attributes->attributes[i].key,
+ &attributes->attributes[i].value, &result)))
+ break;
+ if (!result)
+ break;
+ }
+ break;
+ case MF_ATTRIBUTES_MATCH_INTERSECTION:
+ for (i = 0; i < attributes->count; ++i)
+ {
+ if (FAILED(IMFAttributes_GetItemType(theirs, &attributes->attributes[i].key, &type)))
+ continue;
+
+ if (FAILED(hr = IMFAttributes_CompareItem(theirs, &attributes->attributes[i].key,
+ &attributes->attributes[i].value, &result)))
+ break;
+
+ if (!result)
+ break;
+ }
+ break;
+ case MF_ATTRIBUTES_MATCH_SMALLER:
+ smaller = attributes->count > count ? theirs : iface;
+ other = attributes->count > count ? iface : theirs;
+ hr = IMFAttributes_Compare(smaller, other, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+ break;
+ default:
+ WARN("Unknown match type %d.\n", match_type);
+ hr = E_INVALIDARG;
+ }
+
+ LeaveCriticalSection(&attributes->cs);
+
+ if (SUCCEEDED(hr))
+ *ret = result;
+
+ return hr;
}
static HRESULT WINAPI mfattributes_GetUINT32(IMFAttributes *iface, REFGUID key, UINT32 *value)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 38151d9020..d012acc524 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -496,14 +496,27 @@ static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
}
-static void test_MFCreateAttributes(void)
+#define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
+static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
+{
+ MF_ATTRIBUTE_TYPE type;
+ HRESULT hr;
+
+ hr = IMFAttributes_GetItemType(obj, key, &type);
+ ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
+ ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
+}
+
+static void test_attributes(void)
{
static const WCHAR stringW[] = {'W','i','n','e',0};
static const UINT8 blob[] = {0,1,2,3,4,5};
IMFAttributes *attributes, *attributes1;
UINT8 blob_value[256], *blob_buf = NULL;
+ MF_ATTRIBUTES_MATCH_TYPE match_type;
UINT32 value, string_length, size;
PROPVARIANT propvar, ret_propvar;
+ MF_ATTRIBUTE_TYPE type;
double double_value;
IUnknown *unk_value;
WCHAR bufferW[256];
@@ -516,10 +529,14 @@ static void test_MFCreateAttributes(void)
hr = MFCreateAttributes( &attributes, 3 );
ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
+ ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
+
CHECK_ATTR_COUNT(attributes, 0);
hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
ok(hr == S_OK, "Failed to set UINT32 value, hr %#x.\n", hr);
CHECK_ATTR_COUNT(attributes, 1);
+ CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
value = 0xdeadbeef;
hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
@@ -534,6 +551,7 @@ static void test_MFCreateAttributes(void)
hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
ok(hr == S_OK, "Failed to set UINT64 value, hr %#x.\n", hr);
CHECK_ATTR_COUNT(attributes, 1);
+ CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
ok(hr == S_OK, "Failed to get UINT64 value, hr %#x.\n", hr);
@@ -643,6 +661,7 @@ static void test_MFCreateAttributes(void)
hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
ok(hr == S_OK, "Failed to set double value, hr %#x.\n", hr);
CHECK_ATTR_COUNT(attributes, 3);
+ CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
double_value = 0xdeadbeef;
hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
@@ -664,6 +683,7 @@ static void test_MFCreateAttributes(void)
hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
ok(hr == S_OK, "Failed to set string attribute, hr %#x.\n", hr);
CHECK_ATTR_COUNT(attributes, 3);
+ CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
ok(hr == S_OK, "Failed to get string length, hr %#x.\n", hr);
@@ -701,6 +721,7 @@ static void test_MFCreateAttributes(void)
hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
CHECK_ATTR_COUNT(attributes, 4);
+ CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
@@ -747,6 +768,7 @@ static void test_MFCreateAttributes(void)
hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
ok(hr == S_OK, "Failed to set blob attribute, hr %#x.\n", hr);
CHECK_ATTR_COUNT(attributes, 1);
+ CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
@@ -779,6 +801,203 @@ static void test_MFCreateAttributes(void)
IMFAttributes_Release(attributes);
IMFAttributes_Release(attributes1);
+
+ /* Compare() */
+ hr = MFCreateAttributes(&attributes, 0);
+ ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
+ hr = MFCreateAttributes(&attributes1, 0);
+ ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
+
+ hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
+ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+ for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
+ {
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+ }
+
+ hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
+ ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
+ ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
+ ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
+ ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = TRUE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(!result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ result = FALSE;
+ hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+ ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+ ok(result, "Unexpected result %d.\n", result);
+
+ IMFAttributes_Release(attributes);
+ IMFAttributes_Release(attributes1);
}
static void test_MFCreateMFByteStreamOnStream(void)
@@ -2112,7 +2331,7 @@ START_TEST(mfplat)
test_register();
test_media_type();
test_MFCreateMediaEvent();
- test_MFCreateAttributes();
+ test_attributes();
test_sample();
test_MFCreateFile();
test_MFCreateMFByteStreamOnStream();
--
2.20.1