Signed-off-by: Nikolay Sivov nsivov@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();