Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/mfplat/mediatype.c | 108 +++++++++++++++++--------------------
dlls/mfplat/tests/mfplat.c | 53 +++++++++++++++++-
2 files changed, 101 insertions(+), 60 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c
index 5eaa4fdd08d..0c0d9620321 100644
--- a/dlls/mfplat/mediatype.c
+++ b/dlls/mfplat/mediatype.c
@@ -96,20 +96,32 @@ static struct presentation_desc *impl_from_IMFPresentationDescriptor(IMFPresenta
static HRESULT WINAPI mediatype_QueryInterface(IMFMediaType *iface, REFIID riid, void **out)
{
+ struct media_type *media_type = impl_from_IMFMediaType(iface);
+ GUID major = { 0 };
+
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
- if (IsEqualIID(riid, &IID_IMFMediaType) ||
+ attributes_GetGUID(&media_type->attributes, &MF_MT_MAJOR_TYPE, &major);
+
+ if (IsEqualGUID(&major, &MFMediaType_Video) && IsEqualIID(riid, &IID_IMFVideoMediaType))
+ {
+ *out = &media_type->IMFVideoMediaType_iface;
+ }
+ else if (IsEqualIID(riid, &IID_IMFMediaType) ||
IsEqualIID(riid, &IID_IMFAttributes) ||
IsEqualIID(riid, &IID_IUnknown))
{
- *out = iface;
- IMFMediaType_AddRef(iface);
- return S_OK;
+ *out = &media_type->IMFMediaType_iface;
+ }
+ else
+ {
+ WARN("Unsupported %s.\n", debugstr_guid(riid));
+ *out = NULL;
+ return E_NOINTERFACE;
}
- WARN("Unsupported %s.\n", debugstr_guid(riid));
- *out = NULL;
- return E_NOINTERFACE;
+ IUnknown_AddRef((IUnknown *)*out);
+ return S_OK;
}
static ULONG WINAPI mediatype_AddRef(IMFMediaType *iface)
@@ -613,48 +625,20 @@ static const IMFMediaTypeVtbl mediatypevtbl =
static HRESULT WINAPI video_mediatype_QueryInterface(IMFVideoMediaType *iface, REFIID riid, void **out)
{
- TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
-
- if (IsEqualIID(riid, &IID_IMFVideoMediaType) ||
- IsEqualIID(riid, &IID_IMFMediaType) ||
- IsEqualIID(riid, &IID_IMFAttributes) ||
- IsEqualIID(riid, &IID_IUnknown))
- {
- *out = iface;
- IMFVideoMediaType_AddRef(iface);
- return S_OK;
- }
-
- WARN("Unsupported %s.\n", debugstr_guid(riid));
- *out = NULL;
- return E_NOINTERFACE;
+ struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
+ return IMFMediaType_QueryInterface(&media_type->IMFMediaType_iface, riid, out);
}
static ULONG WINAPI video_mediatype_AddRef(IMFVideoMediaType *iface)
{
struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
- ULONG refcount = InterlockedIncrement(&media_type->attributes.ref);
-
- TRACE("%p, refcount %u.\n", iface, refcount);
-
- return refcount;
+ return IMFMediaType_AddRef(&media_type->IMFMediaType_iface);
}
static ULONG WINAPI video_mediatype_Release(IMFVideoMediaType *iface)
{
struct media_type *media_type = impl_from_IMFVideoMediaType(iface);
- ULONG refcount = InterlockedDecrement(&media_type->attributes.ref);
-
- TRACE("%p, refcount %u.\n", iface, refcount);
-
- if (!refcount)
- {
- clear_attributes_object(&media_type->attributes);
- CoTaskMemFree(media_type->video_format);
- heap_free(media_type);
- }
-
- return refcount;
+ return IMFMediaType_Release(&media_type->IMFMediaType_iface);
}
static HRESULT WINAPI video_mediatype_GetItem(IMFVideoMediaType *iface, REFGUID key, PROPVARIANT *value)
@@ -1039,6 +1023,28 @@ static const IMFVideoMediaTypeVtbl videomediatypevtbl =
video_mediatype_GetVideoRepresentation,
};
+static HRESULT create_media_type(struct media_type **ret)
+{
+ struct media_type *object;
+ HRESULT hr;
+
+ object = heap_alloc_zero(sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ if (FAILED(hr = init_attributes_object(&object->attributes, 0)))
+ {
+ heap_free(object);
+ return hr;
+ }
+ object->IMFMediaType_iface.lpVtbl = &mediatypevtbl;
+ object->IMFVideoMediaType_iface.lpVtbl = &videomediatypevtbl;
+
+ *ret = object;
+
+ return S_OK;
+}
+
/***********************************************************************
* MFCreateMediaType (mfplat.@)
*/
@@ -1052,16 +1058,8 @@ HRESULT WINAPI MFCreateMediaType(IMFMediaType **media_type)
if (!media_type)
return E_INVALIDARG;
- object = heap_alloc(sizeof(*object));
- if (!object)
- return E_OUTOFMEMORY;
-
- if (FAILED(hr = init_attributes_object(&object->attributes, 0)))
- {
- heap_free(object);
+ if (FAILED(hr = create_media_type(&object)))
return hr;
- }
- object->IMFMediaType_iface.lpVtbl = &mediatypevtbl;
*media_type = &object->IMFMediaType_iface;
@@ -2633,19 +2631,11 @@ HRESULT WINAPI MFCreateVideoMediaTypeFromSubtype(const GUID *subtype, IMFVideoMe
if (!media_type)
return E_INVALIDARG;
- object = heap_alloc(sizeof(*object));
- if (!object)
- return E_OUTOFMEMORY;
-
- if (FAILED(hr = init_attributes_object(&object->attributes, 0)))
- {
- heap_free(object);
+ if (FAILED(hr = create_media_type(&object)))
return hr;
- }
- object->IMFVideoMediaType_iface.lpVtbl = &videomediatypevtbl;
- IMFVideoMediaType_SetGUID(&object->IMFVideoMediaType_iface, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
- IMFVideoMediaType_SetGUID(&object->IMFVideoMediaType_iface, &MF_MT_SUBTYPE, subtype);
+ IMFMediaType_SetGUID(&object->IMFMediaType_iface, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
+ IMFMediaType_SetGUID(&object->IMFMediaType_iface, &MF_MT_SUBTYPE, subtype);
*media_type = &object->IMFVideoMediaType_iface;
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 309f7b669a4..c3558106548 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -763,8 +763,10 @@ static void init_functions(void)
static void test_media_type(void)
{
IMFMediaType *mediatype, *mediatype2;
+ IMFVideoMediaType *video_type;
+ IUnknown *unk, *unk2;
+ DWORD count, flags;
BOOL compressed;
- DWORD flags;
HRESULT hr;
GUID guid;
@@ -862,6 +864,55 @@ if(0)
IMFMediaType_Release(mediatype2);
IMFMediaType_Release(mediatype);
+
+ /* IMFVideoMediaType */
+ hr = MFCreateMediaType(&mediatype);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFVideoMediaType, (void **)&unk);
+ ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
+ hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
+ IUnknown_Release(unk);
+
+ hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
+ ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
+
+ hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFVideoMediaType, (void **)&unk);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
+ IUnknown_Release(unk2);
+ IUnknown_Release(unk);
+
+ hr = MFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB555, &video_type);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IMFVideoMediaType_QueryInterface(video_type, &IID_IMFMediaType, (void **)&unk);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ IUnknown_Release(unk);
+
+ hr = IMFVideoMediaType_QueryInterface(video_type, &IID_IMFVideoMediaType, (void **)&unk);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ IUnknown_Release(unk);
+
+ /* Major and subtype are set on creation. */
+ hr = IMFVideoMediaType_GetCount(video_type, &count);
+ ok(count == 2, "Unexpected attribute count %#x.\n", hr);
+
+ hr = IMFVideoMediaType_DeleteAllItems(video_type);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFVideoMediaType_GetCount(video_type, &count);
+ ok(!count, "Unexpected attribute count %#x.\n", hr);
+
+ hr = IMFVideoMediaType_QueryInterface(video_type, &IID_IMFVideoMediaType, (void **)&unk);
+ ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
+
+ IMFVideoMediaType_Release(video_type);
+
+ IMFMediaType_Release(mediatype);
}
static void test_MFCreateMediaEvent(void)
--
2.28.0