Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/mediatype.c | 101 ++++++++++++++++++++++++++++++++++++- dlls/mfplat/tests/mfplat.c | 89 ++++++++++++++++++++++++++++++-- include/mfapi.h | 3 ++ 3 files changed, 188 insertions(+), 5 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 974ab3aba3..27ca405175 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -332,9 +332,106 @@ static HRESULT WINAPI mediatype_IsCompressedFormat(IMFMediaType *iface, BOOL *co
static HRESULT WINAPI mediatype_IsEqual(IMFMediaType *iface, IMFMediaType *type, DWORD *flags) { - FIXME("%p, %p, %p.\n", iface, type, flags); + const DWORD full_equality_flags = MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | + MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA; + struct media_type *media_type = impl_from_IMFMediaType(iface); + struct comparand + { + IMFAttributes *type; + PROPVARIANT value; + UINT32 count; + GUID guid; + HRESULT hr; + } left, right, swp; + unsigned int i; + BOOL result;
- return E_NOTIMPL; + TRACE("%p, %p, %p.\n", iface, type, flags); + + *flags = 0; + + left.type = &media_type->attributes.IMFAttributes_iface; + right.type = (IMFAttributes *)type; + + if (FAILED(IMFAttributes_GetGUID(left.type, &MF_MT_MAJOR_TYPE, &left.guid))) + return E_INVALIDARG; + + if (FAILED(IMFAttributes_GetGUID(right.type, &MF_MT_MAJOR_TYPE, &right.guid))) + return E_INVALIDARG; + + if (IsEqualGUID(&left.guid, &right.guid)) + *flags |= MF_MEDIATYPE_EQUAL_MAJOR_TYPES; + + /* Subtypes equal or both missing. */ + left.hr = IMFAttributes_GetGUID(left.type, &MF_MT_SUBTYPE, &left.guid); + right.hr = IMFAttributes_GetGUID(right.type, &MF_MT_SUBTYPE, &right.guid); + + if ((SUCCEEDED(left.hr) && SUCCEEDED(right.hr) && IsEqualGUID(&left.guid, &right.guid)) || + (FAILED(left.hr) && FAILED(right.hr))) + { + *flags |= MF_MEDIATYPE_EQUAL_FORMAT_TYPES; + } + + /* Format data */ + IMFAttributes_GetCount(left.type, &left.count); + IMFAttributes_GetCount(right.type, &right.count); + + if (right.count < left.count) + { + swp = left; + left = right; + right = swp; + } + + *flags |= MF_MEDIATYPE_EQUAL_FORMAT_DATA; + + for (i = 0; i < left.count; ++i) + { + PROPVARIANT value; + GUID key; + + if (SUCCEEDED(IMFAttributes_GetItemByIndex(left.type, i, &key, &value))) + { + if (IsEqualGUID(&key, &MF_MT_USER_DATA) || + IsEqualGUID(&key, &MF_MT_FRAME_RATE_RANGE_MIN) || + IsEqualGUID(&key, &MF_MT_FRAME_RATE_RANGE_MAX)) + { + PropVariantClear(&value); + continue; + } + + result = FALSE; + IMFAttributes_CompareItem(right.type, &key, &value, &result); + PropVariantClear(&value); + if (!result) + { + *flags &= ~MF_MEDIATYPE_EQUAL_FORMAT_DATA; + break; + } + } + } + + /* User data */ + PropVariantInit(&left.value); + left.hr = IMFAttributes_GetItem(left.type, &MF_MT_USER_DATA, &left.value); + PropVariantInit(&right.value); + right.hr = IMFAttributes_GetItem(right.type, &MF_MT_USER_DATA, &right.value); + + if (SUCCEEDED(left.hr) && SUCCEEDED(left.hr)) + { + result = FALSE; + IMFAttributes_CompareItem(left.type, &MF_MT_USER_DATA, &left.value, &result); + } + else if (FAILED(left.hr) && FAILED(left.hr)) + result = TRUE; + + PropVariantClear(&left.value); + PropVariantClear(&right.value); + + if (result) + *flags |= MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA; + + return *flags == full_equality_flags ? S_OK : S_FALSE; }
static HRESULT WINAPI mediatype_GetRepresentation(IMFMediaType *iface, GUID guid, void **representation) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 3fa729b50e..ca00ac17d9 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -328,10 +328,13 @@ static void init_functions(void) is_win8_plus = pMFPutWaitingWorkItem != NULL; }
-static void test_MFCreateMediaType(void) +static void test_media_type(void) { + IMFMediaType *mediatype, *mediatype2; + BOOL compressed; + DWORD flags; HRESULT hr; - IMFMediaType *mediatype; + GUID guid;
if(0) { @@ -343,9 +346,89 @@ if(0) hr = MFCreateMediaType(&mediatype); ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = IMFMediaType_GetMajorType(mediatype, &guid); +todo_wine + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr); + + compressed = FALSE; + hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed); +todo_wine + ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr); + ok(compressed, "Unexpected value %d.\n", compressed); + + hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 0); +todo_wine + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + compressed = FALSE; + hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed); +todo_wine + ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr); + ok(compressed, "Unexpected value %d.\n", compressed); + + hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1); +todo_wine + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + compressed = TRUE; + hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed); +todo_wine { + ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr); + ok(!compressed, "Unexpected value %d.\n", compressed); +} hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = IMFMediaType_GetMajorType(mediatype, &guid); +todo_wine { + ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr); + ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n"); +} + /* IsEqual() */ + hr = MFCreateMediaType(&mediatype2); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr); + + flags = 0xdeadbeef; + hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(flags == 0, "Unexpected flags %#x.\n", flags); + + /* Different major types. */ + hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); +todo_wine + ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr); + + flags = 0; + hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags); +todo_wine { + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + ok(flags == (MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), + "Unexpected flags %#x.\n", flags); +} + /* Same major types, different subtypes. */ + hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); +todo_wine + ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr); + + flags = 0; + hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA + | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), "Unexpected flags %#x.\n", flags); +} + hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32); +todo_wine + ok(hr == S_OK, "Failed to set subtype, hr %#x.\n", hr); + + flags = 0; + hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags); +todo_wine { + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), + "Unexpected flags %#x.\n", flags); +} + IMFMediaType_Release(mediatype2); IMFMediaType_Release(mediatype); }
@@ -1766,7 +1849,7 @@ START_TEST(mfplat)
test_startup(); test_register(); - test_MFCreateMediaType(); + test_media_type(); test_MFCreateMediaEvent(); test_MFCreateAttributes(); test_sample(); diff --git a/include/mfapi.h b/include/mfapi.h index 2ad9f25062..fd5fbebc58 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -88,6 +88,9 @@ DEFINE_GUID(MF_MT_MAJOR_TYPE, 0x48eba18e, 0xf8c9, 0x4687, 0xbf, 0x1 DEFINE_GUID(MF_MT_PIXEL_ASPECT_RATIO, 0xc6376a1e, 0x8d0a, 0x4027, 0xbe, 0x45, 0x6d, 0x9a, 0x0a, 0xd3, 0x9b, 0xb6); DEFINE_GUID(MF_MT_SUBTYPE, 0xf7e34c9a, 0x42e8, 0x4714, 0xb7, 0x4b, 0xcb, 0x29, 0xd7, 0x2c, 0x35, 0xe5); DEFINE_GUID(MF_MT_ALL_SAMPLES_INDEPENDENT, 0xc9173739, 0x5e56, 0x461c, 0xb7, 0x13, 0x46, 0xfb, 0x99, 0x5c, 0xb9, 0x5f); +DEFINE_GUID(MF_MT_USER_DATA, 0xb6bc765f, 0x4c3b, 0x40a4, 0xbd, 0x51, 0x25, 0x35, 0xb6, 0x6f, 0xe0, 0x9d); +DEFINE_GUID(MF_MT_FRAME_RATE_RANGE_MIN, 0xd2e7558c, 0xdc1f, 0x403f, 0x9a, 0x72, 0xd2, 0x8b, 0xb1, 0xeb, 0x3b, 0x5e); +DEFINE_GUID(MF_MT_FRAME_RATE_RANGE_MAX, 0xe3371d41, 0xb4cf, 0x4a05, 0xbd, 0x4e, 0x20, 0xb8, 0x8b, 0xb2, 0xc4, 0xd6);
DEFINE_GUID(MFT_CATEGORY_VIDEO_DECODER, 0xd6c02d4b, 0x6833, 0x45b4, 0x97, 0x1a, 0x05, 0xa4, 0xb0, 0x4b, 0xab, 0x91); DEFINE_GUID(MFT_CATEGORY_VIDEO_ENCODER, 0xf79eac7d, 0xe545, 0x4387, 0xbd, 0xee, 0xd6, 0x47, 0xd7, 0xbd, 0xe4, 0x2a);