[PATCH] mf: Add MFCreateSimpleTypeHandler().
Nikolay Sivov
nsivov at codeweavers.com
Mon Feb 24 07:37:11 CST 2020
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/mf/main.c | 180 +++++++++++++++++++++++++++++++++++++++++++++
dlls/mf/mf.spec | 2 +-
dlls/mf/tests/mf.c | 66 +++++++++++++++++
include/mfidl.idl | 1 +
4 files changed, 248 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/main.c b/dlls/mf/main.c
index 251d59e1c0..5d645db200 100644
--- a/dlls/mf/main.c
+++ b/dlls/mf/main.c
@@ -1168,3 +1168,183 @@ HRESULT WINAPI MFCreateVideoRendererActivate(HWND hwnd, IMFActivate **activate)
return create_activation_object(hwnd, &evr_activate_funcs, activate);
}
+
+struct simple_type_handler
+{
+ IMFMediaTypeHandler IMFMediaTypeHandler_iface;
+ LONG refcount;
+ IMFMediaType *media_type;
+ CRITICAL_SECTION cs;
+};
+
+static struct simple_type_handler *impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler *iface)
+{
+ return CONTAINING_RECORD(iface, struct simple_type_handler, IMFMediaTypeHandler_iface);
+}
+
+static HRESULT WINAPI simple_type_handler_QueryInterface(IMFMediaTypeHandler *iface, REFIID riid, void **obj)
+{
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+ if (IsEqualIID(riid, &IID_IMFMediaTypeHandler) ||
+ IsEqualIID(riid, &IID_IUnknown))
+ {
+ *obj = iface;
+ IMFMediaTypeHandler_AddRef(iface);
+ return S_OK;
+ }
+
+ *obj = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI simple_type_handler_AddRef(IMFMediaTypeHandler *iface)
+{
+ struct simple_type_handler *handler = impl_from_IMFMediaTypeHandler(iface);
+ ULONG refcount = InterlockedIncrement(&handler->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI simple_type_handler_Release(IMFMediaTypeHandler *iface)
+{
+ struct simple_type_handler *handler = impl_from_IMFMediaTypeHandler(iface);
+ ULONG refcount = InterlockedDecrement(&handler->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ if (handler->media_type)
+ IMFMediaType_Release(handler->media_type);
+ DeleteCriticalSection(&handler->cs);
+ heap_free(handler);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI simple_type_handler_IsMediaTypeSupported(IMFMediaTypeHandler *iface, IMFMediaType *in_type,
+ IMFMediaType **out_type)
+{
+ FIXME("%p, %p, %p.\n", iface, in_type, out_type);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI simple_type_handler_GetMediaTypeCount(IMFMediaTypeHandler *iface, DWORD *count)
+{
+ TRACE("%p, %p.\n", iface, count);
+
+ if (!count)
+ return E_POINTER;
+
+ *count = 1;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI simple_type_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *iface, DWORD index,
+ IMFMediaType **type)
+{
+ struct simple_type_handler *handler = impl_from_IMFMediaTypeHandler(iface);
+
+ TRACE("%p, %u, %p.\n", iface, index, type);
+
+ if (index > 0)
+ return MF_E_NO_MORE_TYPES;
+
+ EnterCriticalSection(&handler->cs);
+ *type = handler->media_type;
+ if (*type)
+ IMFMediaType_AddRef(*type);
+ LeaveCriticalSection(&handler->cs);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI simple_type_handler_SetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType *media_type)
+{
+ struct simple_type_handler *handler = impl_from_IMFMediaTypeHandler(iface);
+
+ TRACE("%p, %p.\n", iface, media_type);
+
+ EnterCriticalSection(&handler->cs);
+ if (handler->media_type)
+ IMFMediaType_Release(handler->media_type);
+ handler->media_type = media_type;
+ if (handler->media_type)
+ IMFMediaType_AddRef(handler->media_type);
+ LeaveCriticalSection(&handler->cs);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI simple_type_handler_GetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType **media_type)
+{
+ struct simple_type_handler *handler = impl_from_IMFMediaTypeHandler(iface);
+
+ TRACE("%p, %p.\n", iface, media_type);
+
+ if (!media_type)
+ return E_POINTER;
+
+ EnterCriticalSection(&handler->cs);
+ *media_type = handler->media_type;
+ if (*media_type)
+ IMFMediaType_AddRef(*media_type);
+ LeaveCriticalSection(&handler->cs);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI simple_type_handler_GetMajorType(IMFMediaTypeHandler *iface, GUID *type)
+{
+ struct simple_type_handler *handler = impl_from_IMFMediaTypeHandler(iface);
+ HRESULT hr;
+
+ TRACE("%p, %p.\n", iface, type);
+
+ EnterCriticalSection(&handler->cs);
+ if (handler->media_type)
+ hr = IMFMediaType_GetGUID(handler->media_type, &MF_MT_MAJOR_TYPE, type);
+ else
+ hr = MF_E_NOT_INITIALIZED;
+ LeaveCriticalSection(&handler->cs);
+
+ return hr;
+}
+
+static const IMFMediaTypeHandlerVtbl simple_type_handler_vtbl =
+{
+ simple_type_handler_QueryInterface,
+ simple_type_handler_AddRef,
+ simple_type_handler_Release,
+ simple_type_handler_IsMediaTypeSupported,
+ simple_type_handler_GetMediaTypeCount,
+ simple_type_handler_GetMediaTypeByIndex,
+ simple_type_handler_SetCurrentMediaType,
+ simple_type_handler_GetCurrentMediaType,
+ simple_type_handler_GetMajorType,
+};
+
+HRESULT WINAPI MFCreateSimpleTypeHandler(IMFMediaTypeHandler **handler)
+{
+ struct simple_type_handler *object;
+
+ TRACE("%p.\n", handler);
+
+ object = heap_alloc_zero(sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ object->IMFMediaTypeHandler_iface.lpVtbl = &simple_type_handler_vtbl;
+ object->refcount = 1;
+ InitializeCriticalSection(&object->cs);
+
+ *handler = &object->IMFMediaTypeHandler_iface;
+
+ return S_OK;
+}
diff --git a/dlls/mf/mf.spec b/dlls/mf/mf.spec
index a8dd314aa3..e396d01519 100644
--- a/dlls/mf/mf.spec
+++ b/dlls/mf/mf.spec
@@ -56,7 +56,7 @@
@ stub MFCreateSequencerSegmentOffset
@ stdcall MFCreateSequencerSource(ptr ptr)
@ stub MFCreateSequencerSourceRemoteStream
-@ stub MFCreateSimpleTypeHandler
+@ stdcall MFCreateSimpleTypeHandler(ptr)
@ stdcall MFCreateSourceResolver(ptr) mfplat.MFCreateSourceResolver
@ stdcall MFCreateStandardQualityManager(ptr)
@ stdcall MFCreateTopoLoader(ptr)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index b353df780b..a1a7d2b05a 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -2595,6 +2595,71 @@ static void test_evr(void)
IMFActivate_Release(activate);
}
+static void test_MFCreateSimpleTypeHandler(void)
+{
+ IMFMediaType *media_type, *media_type2;
+ IMFMediaTypeHandler *handler;
+ DWORD count;
+ HRESULT hr;
+ GUID guid;
+
+ hr = MFCreateSimpleTypeHandler(&handler);
+ ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
+
+ hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, NULL);
+ ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+ count = 0;
+ hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
+ ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
+ ok(count == 1, "Unexpected count %u.\n", count);
+
+ hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, NULL);
+ ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+ media_type = (void *)0xdeadbeef;
+ hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(!media_type, "Unexpected pointer.\n");
+
+ hr = MFCreateMediaType(&media_type);
+ ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
+
+ hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type);
+ ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
+
+ hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type2);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(media_type2 == media_type, "Unexpected type.\n");
+ IMFMediaType_Release(media_type2);
+
+ hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 1, &media_type2);
+ ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type2);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(media_type == media_type2, "Unexpected pointer.\n");
+ IMFMediaType_Release(media_type2);
+
+ IMFMediaType_Release(media_type);
+
+ hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
+ ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
+ ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
+
+ media_type = (void *)0xdeadbeef;
+ hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(!media_type, "Unexpected pointer.\n");
+
+ hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
+ ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
+
+ IMFMediaTypeHandler_Release(handler);
+}
+
START_TEST(mf)
{
test_topology();
@@ -2609,4 +2674,5 @@ START_TEST(mf)
test_quality_manager();
test_sar();
test_evr();
+ test_MFCreateSimpleTypeHandler();
}
diff --git a/include/mfidl.idl b/include/mfidl.idl
index b301edbbdd..b1568b9b56 100644
--- a/include/mfidl.idl
+++ b/include/mfidl.idl
@@ -580,6 +580,7 @@ cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStreamEx(IUnknown *stream, IMFBy
cpp_quote("HRESULT WINAPI MFCreatePresentationClock(IMFPresentationClock **clock);")
cpp_quote("HRESULT WINAPI MFCreatePresentationDescriptor(DWORD count, IMFStreamDescriptor **descriptors,")
cpp_quote(" IMFPresentationDescriptor **presentation_desc);")
+cpp_quote("HRESULT WINAPI MFCreateSimpleTypeHandler(IMFMediaTypeHandler **handler);")
cpp_quote("HRESULT WINAPI MFCreateSampleGrabberSinkActivate(IMFMediaType *media_type,")
cpp_quote(" IMFSampleGrabberSinkCallback *callback, IMFActivate **activate);")
cpp_quote("HRESULT WINAPI MFCreateSequencerSource(IUnknown *reserved, IMFSequencerSource **seq_source);" )
--
2.25.0
More information about the wine-devel
mailing list