[PATCH 9/9] mfplat: Implement media type handler functionality for stream descriptor.

Nikolay Sivov nsivov at codeweavers.com
Mon Mar 4 03:27:26 CST 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfplat/main.c           |  1 -
 dlls/mfplat/mediatype.c      | 90 ++++++++++++++++++++++++++++++++----
 dlls/mfplat/mfplat_private.h |  1 +
 dlls/mfplat/queue.c          |  2 -
 dlls/mfplat/tests/mfplat.c   | 62 +++++++++++++++++++------
 5 files changed, 130 insertions(+), 26 deletions(-)

diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 743d5bdacd..2217f3fb94 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -28,7 +28,6 @@
 #include "winreg.h"
 
 #include "initguid.h"
-#include "mferror.h"
 
 #include "wine/heap.h"
 #include "wine/debug.h"
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c
index 1bd32cd8b0..a473c755d9 100644
--- a/dlls/mfplat/mediatype.c
+++ b/dlls/mfplat/mediatype.c
@@ -37,6 +37,10 @@ struct stream_desc
     IMFStreamDescriptor IMFStreamDescriptor_iface;
     IMFMediaTypeHandler IMFMediaTypeHandler_iface;
     DWORD identifier;
+    IMFMediaType **media_types;
+    unsigned int media_types_count;
+    IMFMediaType *current_type;
+    CRITICAL_SECTION cs;
 };
 
 static inline struct media_type *impl_from_IMFMediaType(IMFMediaType *iface)
@@ -416,11 +420,21 @@ static ULONG WINAPI stream_descriptor_Release(IMFStreamDescriptor *iface)
 {
     struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
     ULONG refcount = InterlockedDecrement(&stream_desc->attributes.ref);
+    unsigned int i;
 
     TRACE("%p, refcount %u.\n", iface, refcount);
 
     if (!refcount)
     {
+        for (i = 0; i < stream_desc->media_types_count; ++i)
+        {
+            if (stream_desc->media_types[i])
+                IMFMediaType_Release(stream_desc->media_types[i]);
+        }
+        heap_free(stream_desc->media_types);
+        if (stream_desc->current_type)
+            IMFMediaType_Release(stream_desc->current_type);
+        DeleteCriticalSection(&stream_desc->cs);
         heap_free(stream_desc);
     }
 
@@ -715,31 +729,71 @@ static HRESULT WINAPI mediatype_handler_IsMediaTypeSupported(IMFMediaTypeHandler
 
 static HRESULT WINAPI mediatype_handler_GetMediaTypeCount(IMFMediaTypeHandler *iface, DWORD *count)
 {
-    FIXME("%p, %p.\n", iface, count);
+    struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
 
-    return E_NOTIMPL;
+    TRACE("%p, %p.\n", iface, count);
+
+    *count = stream_desc->media_types_count;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI mediatype_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *iface, DWORD index,
         IMFMediaType **type)
 {
-    FIXME("%p, %u, %p.\n", iface, index, type);
+    struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
 
-    return E_NOTIMPL;
+    TRACE("%p, %u, %p.\n", iface, index, type);
+
+    if (index >= stream_desc->media_types_count)
+        return MF_E_NO_MORE_TYPES;
+
+    if (stream_desc->media_types[index])
+    {
+        *type = stream_desc->media_types[index];
+        IMFMediaType_AddRef(*type);
+    }
+
+    return stream_desc->media_types[index] ? S_OK : E_FAIL;
 }
 
 static HRESULT WINAPI mediatype_handler_SetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType *type)
 {
-    FIXME("%p, %p.\n", iface, type);
+    struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
 
-    return E_NOTIMPL;
+    TRACE("%p, %p.\n", iface, type);
+
+    if (!type)
+        return E_POINTER;
+
+    EnterCriticalSection(&stream_desc->cs);
+    if (stream_desc->current_type)
+        IMFMediaType_Release(stream_desc->current_type);
+    stream_desc->current_type = type;
+    IMFMediaType_AddRef(stream_desc->current_type);
+    LeaveCriticalSection(&stream_desc->cs);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI mediatype_handler_GetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType **type)
 {
-    FIXME("%p, %p.\n", iface, type);
+    struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
+    HRESULT hr = S_OK;
 
-    return E_NOTIMPL;
+    TRACE("%p, %p.\n", iface, type);
+
+    EnterCriticalSection(&stream_desc->cs);
+    if (stream_desc->current_type)
+    {
+        *type = stream_desc->current_type;
+        IMFMediaType_AddRef(*type);
+    }
+    else
+        hr = MF_E_NOT_INITIALIZED;
+    LeaveCriticalSection(&stream_desc->cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI mediatype_handler_GetMajorType(IMFMediaTypeHandler *iface, GUID *type)
@@ -769,10 +823,14 @@ HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD count,
         IMFMediaType **types, IMFStreamDescriptor **descriptor)
 {
     struct stream_desc *object;
+    unsigned int i;
 
     TRACE("%d, %d, %p, %p.\n", identifier, count, types, descriptor);
 
-    object = heap_alloc(sizeof(*object));
+    if (!count)
+        return E_INVALIDARG;
+
+    object = heap_alloc_zero(sizeof(*object));
     if (!object)
         return E_OUTOFMEMORY;
 
@@ -780,6 +838,20 @@ HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD count,
     object->IMFStreamDescriptor_iface.lpVtbl = &streamdescriptorvtbl;
     object->IMFMediaTypeHandler_iface.lpVtbl = &mediatypehandlervtbl;
     object->identifier = identifier;
+    object->media_types = heap_alloc(count * sizeof(*object->media_types));
+    if (!object->media_types)
+    {
+        heap_free(object);
+        return E_OUTOFMEMORY;
+    }
+    for (i = 0; i < count; ++i)
+    {
+        object->media_types[i] = types[i];
+        if (object->media_types[i])
+            IMFMediaType_AddRef(object->media_types[i]);
+    }
+    object->media_types_count = count;
+    InitializeCriticalSection(&object->cs);
 
     *descriptor = &object->IMFStreamDescriptor_iface;
 
diff --git a/dlls/mfplat/mfplat_private.h b/dlls/mfplat/mfplat_private.h
index 46320bbb50..e5b0647e63 100644
--- a/dlls/mfplat/mfplat_private.h
+++ b/dlls/mfplat/mfplat_private.h
@@ -18,6 +18,7 @@
 
 #include "mfapi.h"
 #include "mfidl.h"
+#include "mferror.h"
 
 typedef struct attributes
 {
diff --git a/dlls/mfplat/queue.c b/dlls/mfplat/queue.c
index 0382b02a27..4d3322840c 100644
--- a/dlls/mfplat/queue.c
+++ b/dlls/mfplat/queue.c
@@ -20,8 +20,6 @@
 
 #define COBJMACROS
 
-#include "mferror.h"
-
 #include "wine/debug.h"
 #include "wine/heap.h"
 #include "wine/list.h"
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 7d297d6179..d65eb7649d 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -1431,7 +1431,7 @@ static void test_event_queue(void)
 
 static void test_stream_descriptor(void)
 {
-    IMFMediaType *media_types[2], *media_type;
+    IMFMediaType *media_types[2], *media_type, *media_type2;
     IMFMediaTypeHandler *type_handler;
     IMFStreamDescriptor *stream_desc;
     GUID major_type;
@@ -1446,7 +1446,6 @@ static void test_stream_descriptor(void)
     }
 
     hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
-todo_wine
     ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
 
     hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
@@ -1460,12 +1459,10 @@ todo_wine
     ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
 
     hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
-todo_wine {
     ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
     ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
-}
+
     hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
-todo_wine
     ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
 
     hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
@@ -1475,35 +1472,72 @@ todo_wine
     for (i = 0; i < ARRAY_SIZE(media_types); ++i)
     {
         hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
-todo_wine {
         ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
         ok(media_type == media_types[i], "Unexpected object.\n");
-}
-        if (SUCCEEDED(hr))
-            IMFMediaType_Release(media_type);
+        IMFMediaType_Release(media_type);
     }
 
     hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
-todo_wine
     ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
 
     hr = MFCreateMediaType(&media_type);
     ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
 
     hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
-todo_wine
     ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
 
+    hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 0, &media_type2);
+    ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
+    ok(media_types[0] == media_type2, "Unexpected object.\n");
+    IMFMediaType_Release(media_type2);
+
+    hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type2);
+    ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
+    ok(media_type2 == media_type, "Unexpected object.\n");
+    IMFMediaType_Release(media_type);
+    IMFMediaType_Release(media_type2);
+
     hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
-todo_wine {
     ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
     ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
-}
-    IMFMediaType_Release(media_type);
+
+    hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    for (i = 0; i < ARRAY_SIZE(media_types); ++i)
+    {
+        IMFMediaType_Release(media_types[i]);
+    }
 
     IMFMediaTypeHandler_Release(type_handler);
+    IMFStreamDescriptor_Release(stream_desc);
+
+    /* Not every type element is initialized. */
+    media_types[0] = NULL;
+    hr = MFCreateMediaType(&media_types[1]);
+    ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
+
+    hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
+    ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
+
+    hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
+    ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
+    ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
+
+    hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 0, &media_type);
+    ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 1, &media_type);
+    ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
+    ok(media_type == media_types[1], "Unexpected object.\n");
+    IMFMediaType_Release(media_type);
 
     IMFStreamDescriptor_Release(stream_desc);
+    IMFMediaTypeHandler_Release(type_handler);
+    IMFMediaType_Release(media_types[1]);
 }
 
 START_TEST(mfplat)
-- 
2.20.1




More information about the wine-devel mailing list