[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