Signed-off-by: Nikolay Sivov nsivov@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)