From: R��mi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/mf.c | 477 +++++++++++++++++++++++---------------------- 1 file changed, 245 insertions(+), 232 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index af611fac814..612d5a7db05 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -300,6 +300,230 @@ static BOOL create_transform(GUID category, MFT_REGISTER_TYPE_INFO *input_type, return TRUE; }
+static void init_media_type(IMFMediaType *mediatype, const struct attribute_desc *desc, ULONG limit) +{ + HRESULT hr; + ULONG i; + + hr = IMFMediaType_DeleteAllItems(mediatype); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + for (i = 0; i < limit && desc[i].key; ++i) + { + hr = IMFMediaType_SetItem(mediatype, desc[i].key, &desc[i].value); + ok(hr == S_OK, "SetItem %s returned %#lx\n", debugstr_a(desc[i].name), hr); + } +} + +static void create_descriptors(UINT enum_types_count, IMFMediaType **enum_types, const media_type_desc *current_desc, + IMFPresentationDescriptor **pd, IMFStreamDescriptor **sd) +{ + HRESULT hr; + + hr = MFCreateStreamDescriptor(0, enum_types_count, enum_types, sd); + ok(hr == S_OK, "Failed to create stream descriptor, hr %#lx.\n", hr); + + hr = MFCreatePresentationDescriptor(1, sd, pd); + ok(hr == S_OK, "Failed to create presentation descriptor, hr %#lx.\n", hr); + + if (current_desc) + { + IMFMediaTypeHandler *handler; + IMFMediaType *type; + + hr = MFCreateMediaType(&type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(type, *current_desc, -1); + + hr = IMFStreamDescriptor_GetMediaTypeHandler(*sd, &handler); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFMediaTypeHandler_Release(handler); + IMFMediaType_Release(type); + } +} + +static void init_source_node(IMFMediaSource *source, MF_CONNECT_METHOD method, IMFTopologyNode *node, + IMFPresentationDescriptor *pd, IMFStreamDescriptor *sd) +{ + HRESULT hr; + + hr = IMFTopologyNode_DeleteAllItems(node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd); + ok(hr == S_OK, "Failed to set node pd, hr %#lx.\n", hr); + hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); + ok(hr == S_OK, "Failed to set node sd, hr %#lx.\n", hr); + + if (method != -1) + { + hr = IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_CONNECT_METHOD, method); + ok(hr == S_OK, "Failed to set connect method, hr %#lx.\n", hr); + } + + if (source) + { + hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_SOURCE, (IUnknown *)source); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } +} + +static void init_sink_node(IMFStreamSink *stream_sink, MF_CONNECT_METHOD method, IMFTopologyNode *node) +{ + HRESULT hr; + + hr = IMFTopologyNode_DeleteAllItems(node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFTopologyNode_SetObject(node, (IUnknown *)stream_sink); + ok(hr == S_OK, "Failed to set object, hr %#lx.\n", hr); + + if (method != -1) + { + hr = IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_CONNECT_METHOD, method); + ok(hr == S_OK, "Failed to set connect method, hr %#lx.\n", hr); + } +} + +struct test_source +{ + IMFMediaSource IMFMediaSource_iface; + LONG refcount; +}; + +static struct test_source *impl_from_IMFMediaSource(IMFMediaSource *iface) +{ + return CONTAINING_RECORD(iface, struct test_source, IMFMediaSource_iface); +} + +static HRESULT WINAPI test_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) +{ + if (IsEqualIID(riid, &IID_IMFMediaSource) + || IsEqualIID(riid, &IID_IMFMediaEventGenerator) + || IsEqualIID(riid, &IID_IUnknown)) + { + *out = iface; + } + else + { + *out = NULL; + return E_NOINTERFACE; + } + + IMFMediaSource_AddRef(iface); + return S_OK; +} + +static ULONG WINAPI test_source_AddRef(IMFMediaSource *iface) +{ + struct test_source *source = impl_from_IMFMediaSource(iface); + return InterlockedIncrement(&source->refcount); +} + +static ULONG WINAPI test_source_Release(IMFMediaSource *iface) +{ + struct test_source *source = impl_from_IMFMediaSource(iface); + ULONG refcount = InterlockedDecrement(&source->refcount); + + if (!refcount) + free(source); + + return refcount; +} + +static HRESULT WINAPI test_source_GetEvent(IMFMediaSource *iface, DWORD flags, IMFMediaEvent **event) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_BeginGetEvent(IMFMediaSource *iface, IMFAsyncCallback *callback, IUnknown *state) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_EndGetEvent(IMFMediaSource *iface, IMFAsyncResult *result, IMFMediaEvent **event) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_QueueEvent(IMFMediaSource *iface, MediaEventType event_type, REFGUID ext_type, + HRESULT hr, const PROPVARIANT *value) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_GetCharacteristics(IMFMediaSource *iface, DWORD *flags) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **pd) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *pd, const GUID *time_format, + const PROPVARIANT *start_position) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_Stop(IMFMediaSource *iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_Pause(IMFMediaSource *iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_Shutdown(IMFMediaSource *iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static const IMFMediaSourceVtbl test_source_vtbl = +{ + test_source_QueryInterface, + test_source_AddRef, + test_source_Release, + test_source_GetEvent, + test_source_BeginGetEvent, + test_source_EndGetEvent, + test_source_QueueEvent, + test_source_GetCharacteristics, + test_source_CreatePresentationDescriptor, + test_source_Start, + test_source_Stop, + test_source_Pause, + test_source_Shutdown, +}; + +static IMFMediaSource *create_test_source(void) +{ + struct test_source *source; + + source = calloc(1, sizeof(*source)); + source->IMFMediaSource_iface.lpVtbl = &test_source_vtbl; + source->refcount = 1; + + return &source->IMFMediaSource_iface; +} + static HRESULT WINAPI test_unk_QueryInterface(IUnknown *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IUnknown)) @@ -1970,231 +2194,6 @@ static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl = test_grabber_callback_OnShutdown, };
-struct test_source -{ - IMFMediaSource IMFMediaSource_iface; - LONG refcount; -}; - -static struct test_source *impl_from_IMFMediaSource(IMFMediaSource *iface) -{ - return CONTAINING_RECORD(iface, struct test_source, IMFMediaSource_iface); -} - -static HRESULT WINAPI test_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) -{ - if (IsEqualIID(riid, &IID_IMFMediaSource) - || IsEqualIID(riid, &IID_IMFMediaEventGenerator) - || IsEqualIID(riid, &IID_IUnknown)) - { - *out = iface; - } - else - { - *out = NULL; - return E_NOINTERFACE; - } - - IMFMediaSource_AddRef(iface); - return S_OK; -} - -static ULONG WINAPI test_source_AddRef(IMFMediaSource *iface) -{ - struct test_source *source = impl_from_IMFMediaSource(iface); - return InterlockedIncrement(&source->refcount); -} - -static ULONG WINAPI test_source_Release(IMFMediaSource *iface) -{ - struct test_source *source = impl_from_IMFMediaSource(iface); - ULONG refcount = InterlockedDecrement(&source->refcount); - - if (!refcount) - free(source); - - return refcount; -} - -static HRESULT WINAPI test_source_GetEvent(IMFMediaSource *iface, DWORD flags, IMFMediaEvent **event) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI test_source_BeginGetEvent(IMFMediaSource *iface, IMFAsyncCallback *callback, IUnknown *state) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI test_source_EndGetEvent(IMFMediaSource *iface, IMFAsyncResult *result, IMFMediaEvent **event) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI test_source_QueueEvent(IMFMediaSource *iface, MediaEventType event_type, REFGUID ext_type, - HRESULT hr, const PROPVARIANT *value) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI test_source_GetCharacteristics(IMFMediaSource *iface, DWORD *flags) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI test_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **pd) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI test_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *pd, const GUID *time_format, - const PROPVARIANT *start_position) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI test_source_Stop(IMFMediaSource *iface) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI test_source_Pause(IMFMediaSource *iface) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI test_source_Shutdown(IMFMediaSource *iface) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} - -static const IMFMediaSourceVtbl test_source_vtbl = -{ - test_source_QueryInterface, - test_source_AddRef, - test_source_Release, - test_source_GetEvent, - test_source_BeginGetEvent, - test_source_EndGetEvent, - test_source_QueueEvent, - test_source_GetCharacteristics, - test_source_CreatePresentationDescriptor, - test_source_Start, - test_source_Stop, - test_source_Pause, - test_source_Shutdown, -}; - -static IMFMediaSource *create_test_source(void) -{ - struct test_source *source; - - source = calloc(1, sizeof(*source)); - source->IMFMediaSource_iface.lpVtbl = &test_source_vtbl; - source->refcount = 1; - - return &source->IMFMediaSource_iface; -} - -static void init_media_type(IMFMediaType *mediatype, const struct attribute_desc *desc, ULONG limit) -{ - HRESULT hr; - ULONG i; - - hr = IMFMediaType_DeleteAllItems(mediatype); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - - for (i = 0; i < limit && desc[i].key; ++i) - { - hr = IMFMediaType_SetItem(mediatype, desc[i].key, &desc[i].value); - ok(hr == S_OK, "SetItem %s returned %#lx\n", debugstr_a(desc[i].name), hr); - } -} - -static void init_source_node(IMFMediaSource *source, MF_CONNECT_METHOD method, IMFTopologyNode *node, - UINT enum_types_count, IMFMediaType **enum_types, const media_type_desc *current_desc) -{ - IMFPresentationDescriptor *pd; - IMFStreamDescriptor *sd; - HRESULT hr; - - hr = IMFTopologyNode_DeleteAllItems(node); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - - hr = MFCreateStreamDescriptor(0, enum_types_count, enum_types, &sd); - ok(hr == S_OK, "Failed to create stream descriptor, hr %#lx.\n", hr); - - hr = MFCreatePresentationDescriptor(1, &sd, &pd); - ok(hr == S_OK, "Failed to create presentation descriptor, hr %#lx.\n", hr); - - hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd); - ok(hr == S_OK, "Failed to set node pd, hr %#lx.\n", hr); - - IMFPresentationDescriptor_Release(pd); - - hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); - ok(hr == S_OK, "Failed to set node sd, hr %#lx.\n", hr); - - if (method != -1) - { - hr = IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_CONNECT_METHOD, method); - ok(hr == S_OK, "Failed to set connect method, hr %#lx.\n", hr); - } - - if (source) - { - hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_SOURCE, (IUnknown *)source); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - } - - if (current_desc) - { - IMFMediaTypeHandler *handler; - IMFMediaType *type; - - hr = MFCreateMediaType(&type); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - init_media_type(type, *current_desc, -1); - - hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, type); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - - IMFMediaTypeHandler_Release(handler); - IMFMediaType_Release(type); - } - - IMFStreamDescriptor_Release(sd); -} - -static void init_sink_node(IMFStreamSink *stream_sink, MF_CONNECT_METHOD method, IMFTopologyNode *node) -{ - HRESULT hr; - - hr = IMFTopologyNode_DeleteAllItems(node); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - - hr = IMFTopologyNode_SetObject(node, (IUnknown *)stream_sink); - ok(hr == S_OK, "Failed to set object, hr %#lx.\n", hr); - - if (method != -1) - { - hr = IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_CONNECT_METHOD, method); - ok(hr == S_OK, "Failed to set connect method, hr %#lx.\n", hr); - } -} - enum loader_test_flags { LOADER_EXPECTED_DECODER = 0x1, @@ -2581,6 +2580,15 @@ static void test_topology_loader(void) ref = IMFActivate_Release(sink_activate); ok(ref == 0, "Release returned %ld\n", ref);
+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFPresentationDescriptor_Release(pd); + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFStreamDescriptor_Release(sd); + ok(ref == 0, "Release returned %ld\n", ref); +
hr = MFCreateMediaType(&input_type); ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); @@ -2619,7 +2627,11 @@ static void test_topology_loader(void) handler.media_types = NULL; }
- init_source_node(source, test->source_method, src_node, 1, &input_type, test->current_input); + create_descriptors(1, &input_type, test->current_input, &pd, &sd); + init_source_node(source, test->source_method, src_node, pd, sd); + IMFPresentationDescriptor_Release(pd); + IMFStreamDescriptor_Release(sd); + init_sink_node(&stream_sink.IMFStreamSink_iface, test->sink_method, sink_node);
hr = IMFTopology_GetCount(topology, &count); @@ -2794,11 +2806,6 @@ todo_wine { ref = IMFMediaSource_Release(source); ok(ref == 0, "Release returned %ld\n", ref);
- ref = IMFPresentationDescriptor_Release(pd); - ok(ref == 0, "Release returned %ld\n", ref); - ref = IMFStreamDescriptor_Release(sd); - ok(ref == 0, "Release returned %ld\n", ref); - ref = IMFMediaType_Release(input_type); ok(ref == 0, "Release returned %ld\n", ref); ref = IMFMediaType_Release(output_type); @@ -2820,10 +2827,12 @@ static void test_topology_loader_evr(void) }; IMFTopologyNode *node, *source_node, *evr_node; IMFTopology *topology, *full_topology; + IMFPresentationDescriptor *pd; IMFMediaTypeHandler *handler; unsigned int i, count, value; IMFStreamSink *stream_sink; IMFMediaType *media_type; + IMFStreamDescriptor *sd; IMFActivate *activate; IMFTopoLoader *loader; IMFMediaSink *sink; @@ -2846,7 +2855,11 @@ static void test_topology_loader_evr(void) hr = MFCreateMediaType(&media_type); ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); init_media_type(media_type, media_type_desc, -1); - init_source_node(NULL, -1, source_node, 1, &media_type, &media_type_desc); + + create_descriptors(1, &media_type, &media_type_desc, &pd, &sd); + init_source_node(NULL, -1, source_node, pd, sd); + IMFPresentationDescriptor_Release(pd); + IMFStreamDescriptor_Release(sd);
/* EVR sink node. */ window = create_window();
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/mf.c | 63 ++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 25 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 612d5a7db05..5dba4ecdb88 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -392,6 +392,7 @@ struct test_source { IMFMediaSource IMFMediaSource_iface; LONG refcount; + IMFPresentationDescriptor *pd; };
static struct test_source *impl_from_IMFMediaSource(IMFMediaSource *iface) @@ -429,7 +430,10 @@ static ULONG WINAPI test_source_Release(IMFMediaSource *iface) ULONG refcount = InterlockedDecrement(&source->refcount);
if (!refcount) + { + IMFPresentationDescriptor_Release(source->pd); free(source); + }
return refcount; } @@ -461,14 +465,14 @@ static HRESULT WINAPI test_source_QueueEvent(IMFMediaSource *iface, MediaEventTy
static HRESULT WINAPI test_source_GetCharacteristics(IMFMediaSource *iface, DWORD *flags) { - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; + *flags = 0; + return S_OK; }
static HRESULT WINAPI test_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **pd) { - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; + struct test_source *source = impl_from_IMFMediaSource(iface); + return IMFPresentationDescriptor_Clone(source->pd, pd); }
static HRESULT WINAPI test_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *pd, const GUID *time_format, @@ -513,13 +517,14 @@ static const IMFMediaSourceVtbl test_source_vtbl = test_source_Shutdown, };
-static IMFMediaSource *create_test_source(void) +static IMFMediaSource *create_test_source(IMFPresentationDescriptor *pd) { struct test_source *source;
source = calloc(1, sizeof(*source)); source->IMFMediaSource_iface.lpVtbl = &test_source_vtbl; source->refcount = 1; + IMFPresentationDescriptor_AddRef((source->pd = pd));
return &source->IMFMediaSource_iface; } @@ -2504,34 +2509,28 @@ static void test_topology_loader(void) hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node); ok(hr == S_OK, "Failed to create topology node, hr %#lx.\n", hr);
- /* When a decoder is involved, windows requires this attribute to be present */ - source = create_test_source(); - - hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)source); - ok(hr == S_OK, "Failed to set node source, hr %#lx.\n", hr); - hr = MFCreateMediaType(&media_type); ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); - hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr); hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
- hr = MFCreateStreamDescriptor(0, 1, &media_type, &sd); - ok(hr == S_OK, "Failed to create stream descriptor, hr %#lx.\n", hr); + /* When a decoder is involved, windows requires this attribute to be present */ + create_descriptors(1, &media_type, NULL, &pd, &sd); + IMFMediaType_Release(media_type); + + source = create_test_source(pd); + + hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)source); + ok(hr == S_OK, "Failed to set node source, hr %#lx.\n", hr);
hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); ok(hr == S_OK, "Failed to set node sd, hr %#lx.\n", hr);
- hr = MFCreatePresentationDescriptor(1, &sd, &pd); - ok(hr == S_OK, "Failed to create presentation descriptor, hr %#lx.\n", hr); - hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd); ok(hr == S_OK, "Failed to set node pd, hr %#lx.\n", hr);
- IMFMediaType_Release(media_type); - hr = IMFTopology_AddNode(topology, src_node); ok(hr == S_OK, "Failed to add a node, hr %#lx.\n", hr);
@@ -2580,10 +2579,14 @@ static void test_topology_loader(void) ref = IMFActivate_Release(sink_activate); ok(ref == 0, "Release returned %ld\n", ref);
+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, NULL); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, NULL); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFMediaSource_Release(source); + ok(ref == 0, "Release returned %ld\n", ref); ref = IMFPresentationDescriptor_Release(pd); ok(ref == 0, "Release returned %ld\n", ref); ref = IMFStreamDescriptor_Release(sd); @@ -2628,10 +2631,10 @@ static void test_topology_loader(void) }
create_descriptors(1, &input_type, test->current_input, &pd, &sd); - init_source_node(source, test->source_method, src_node, pd, sd); - IMFPresentationDescriptor_Release(pd); - IMFStreamDescriptor_Release(sd);
+ source = create_test_source(pd); + + init_source_node(source, test->source_method, src_node, pd, sd); init_sink_node(&stream_sink.IMFStreamSink_iface, test->sink_method, sink_node);
hr = IMFTopology_GetCount(topology, &count); @@ -2791,6 +2794,19 @@ todo_wine { else ok(!handler.enum_count, "got %lu GetMediaTypeByIndex\n", handler.enum_count);
+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFMediaSource_Release(source); + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFPresentationDescriptor_Release(pd); + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFStreamDescriptor_Release(sd); + ok(ref == 0, "Release returned %ld\n", ref); + winetest_pop_context(); }
@@ -2803,9 +2819,6 @@ todo_wine { ref = IMFTopologyNode_Release(sink_node); ok(ref == 0, "Release returned %ld\n", ref);
- ref = IMFMediaSource_Release(source); - ok(ref == 0, "Release returned %ld\n", ref); - ref = IMFMediaType_Release(input_type); ok(ref == 0, "Release returned %ld\n", ref); ref = IMFMediaType_Release(output_type);
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/mf.c | 86 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 25 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 5dba4ecdb88..454694cac8b 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1792,8 +1792,14 @@ static const struct test_stream_sink test_stream_sink = {.IMFStreamSink_iface.lp struct test_callback { IMFAsyncCallback IMFAsyncCallback_iface; + LONG refcount; };
+static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface) +{ + return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface); +} + static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IMFAsyncCallback) || @@ -1810,12 +1816,21 @@ static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFII
static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface) { - return 2; + struct test_callback *callback = impl_from_IMFAsyncCallback(iface); + return InterlockedIncrement(&callback->refcount); }
static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface) { - return 1; + struct test_callback *callback = impl_from_IMFAsyncCallback(iface); + ULONG refcount = InterlockedDecrement(&callback->refcount); + + if (!refcount) + { + free(callback); + } + + return refcount; }
static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) @@ -1840,20 +1855,35 @@ static const IMFAsyncCallbackVtbl testcallbackvtbl = testcallback_Invoke, };
-static void init_test_callback(struct test_callback *callback) +static IMFAsyncCallback *create_test_callback(void) { + struct test_callback *callback; + + if (!(callback = calloc(1, sizeof(*callback)))) + return NULL; + + callback->refcount = 1; callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl; + + return &callback->IMFAsyncCallback_iface; }
-static void test_session_events(IMFMediaSession *session) +static void test_media_session_events(void) { - struct test_callback callback, callback2; + IMFAsyncCallback *callback, *callback2; + IMFMediaSession *session; IMFAsyncResult *result; IMFMediaEvent *event; HRESULT hr;
- init_test_callback(&callback); - init_test_callback(&callback2); + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Startup failure, hr %#lx.\n", hr); + + callback = create_test_callback(); + callback2 = create_test_callback(); + + hr = MFCreateMediaSession(NULL, &session); + ok(hr == S_OK, "Failed to create media session, hr %#lx.\n", hr);
hr = IMFMediaSession_GetEvent(session, MF_EVENT_FLAG_NO_WAIT, &event); ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr); @@ -1862,26 +1892,31 @@ static void test_session_events(IMFMediaSession *session) hr = IMFMediaSession_BeginGetEvent(session, NULL, NULL); ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
- hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session); + hr = IMFMediaSession_BeginGetEvent(session, callback, (IUnknown *)session); ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr); + EXPECT_REF(callback, 2);
/* Same callback, same state. */ - hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session); + hr = IMFMediaSession_BeginGetEvent(session, callback, (IUnknown *)session); ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr); + EXPECT_REF(callback, 2);
/* Same callback, different state. */ - hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface); + hr = IMFMediaSession_BeginGetEvent(session, callback, (IUnknown *)callback); ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr); + EXPECT_REF(callback, 2);
/* Different callback, same state. */ - hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)session); + hr = IMFMediaSession_BeginGetEvent(session, callback2, (IUnknown *)session); ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr); + EXPECT_REF(callback2, 1);
/* Different callback, different state. */ - hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface); + hr = IMFMediaSession_BeginGetEvent(session, callback2, (IUnknown *)callback); ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr); + EXPECT_REF(callback, 2);
- hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result); + hr = MFCreateAsyncResult(NULL, callback, NULL, &result); ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
hr = IMFMediaSession_EndGetEvent(session, result, &event); @@ -1890,6 +1925,17 @@ static void test_session_events(IMFMediaSession *session) /* Shutdown behavior. */ hr = IMFMediaSession_Shutdown(session); ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr); + IMFMediaSession_Release(session); + + /* Shutdown leaks callback */ + EXPECT_REF(callback, 2); + EXPECT_REF(callback2, 1); + + IMFAsyncCallback_Release(callback); + IMFAsyncCallback_Release(callback2); + + hr = MFShutdown(); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); }
static void test_media_session(void) @@ -1903,8 +1949,8 @@ static void test_media_session(void) PROPVARIANT propvar; IMFGetService *gs; IMFClock *clock; - DWORD caps; HRESULT hr; + DWORD caps;
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); ok(hr == S_OK, "Startup failure, hr %#lx.\n", hr); @@ -2007,17 +2053,6 @@ static void test_media_session(void) IMFMediaSession_Release(session);
IMFAttributes_Release(attributes); - - /* Basic events behavior. */ - hr = MFCreateMediaSession(NULL, &session); - ok(hr == S_OK, "Failed to create media session, hr %#lx.\n", hr); - - test_session_events(session); - - IMFMediaSession_Release(session); - - hr = MFShutdown(); - ok(hr == S_OK, "Shutdown failure, hr %#lx.\n", hr); }
static void test_media_session_rate_control(void) @@ -9795,6 +9830,7 @@ START_TEST(mf) test_MFGetService(); test_sequencer_source(); test_media_session(); + test_media_session_events(); test_media_session_rate_control(); test_MFShutdownObject(); test_presentation_clock();
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/mf.c | 123 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 454694cac8b..bcb766a231d 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1793,6 +1793,9 @@ struct test_callback { IMFAsyncCallback IMFAsyncCallback_iface; LONG refcount; + + HANDLE event; + IMFMediaEvent *media_event; };
static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface) @@ -1827,6 +1830,9 @@ static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
if (!refcount) { + if (callback->media_event) + IMFMediaEvent_Release(callback->media_event); + CloseHandle(callback->event); free(callback); }
@@ -1841,9 +1847,28 @@ static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD
static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { + struct test_callback *callback = CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface); + IUnknown *object; + HRESULT hr; + ok(result != NULL, "Unexpected result object.\n");
- return E_NOTIMPL; + if (callback->media_event) + IMFMediaEvent_Release(callback->media_event); + + hr = IMFAsyncResult_GetObject(result, &object); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = IMFAsyncResult_GetState(result, &object); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaEventGenerator_EndGetEvent((IMFMediaEventGenerator *)object, + result, &callback->media_event); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IUnknown_Release(object); + + SetEvent(callback->event); + + return S_OK; }
static const IMFAsyncCallbackVtbl testcallbackvtbl = @@ -1864,16 +1889,54 @@ static IMFAsyncCallback *create_test_callback(void)
callback->refcount = 1; callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl; + callback->event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!callback->event, "CreateEventW failed, error %lu\n", GetLastError());
return &callback->IMFAsyncCallback_iface; }
+#define wait_media_event(a, b, c, d, e) wait_media_event_(__LINE__, a, b, c, d, e) +static HRESULT wait_media_event_(int line, IMFMediaSession *session, IMFAsyncCallback *callback, + MediaEventType expect_type, DWORD timeout, PROPVARIANT *value) +{ + struct test_callback *impl = impl_from_IMFAsyncCallback(callback); + MediaEventType type; + HRESULT hr, status; + DWORD ret; + GUID guid; + + do + { + hr = IMFMediaSession_BeginGetEvent(session, &impl->IMFAsyncCallback_iface, (IUnknown *)session); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ret = WaitForSingleObject(impl->event, timeout); + ok_(__FILE__, line)(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", ret); + hr = IMFMediaEvent_GetType(impl->media_event, &type); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } while (type != expect_type); + + ok_(__FILE__, line)(type == expect_type, "got type %lu\n", type); + + hr = IMFMediaEvent_GetExtendedType(impl->media_event, &guid); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)(IsEqualGUID(&guid, &GUID_NULL), "got extended type %s\n", debugstr_guid(&guid)); + + hr = IMFMediaEvent_GetValue(impl->media_event, value); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaEvent_GetStatus(impl->media_event, &status); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + return status; +} + static void test_media_session_events(void) { IMFAsyncCallback *callback, *callback2; IMFMediaSession *session; IMFAsyncResult *result; IMFMediaEvent *event; + PROPVARIANT propvar; HRESULT hr;
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); @@ -1934,6 +1997,64 @@ static void test_media_session_events(void) IMFAsyncCallback_Release(callback); IMFAsyncCallback_Release(callback2);
+ + callback = create_test_callback(); + + hr = MFCreateMediaSession(NULL, &session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionStarted, 1000, &propvar); + ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + + hr = IMFMediaSession_Stop(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionStopped, 1000, &propvar); + todo_wine + ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + + hr = IMFMediaSession_Pause(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionPaused, 1000, &propvar); + todo_wine + ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + + hr = IMFMediaSession_ClearTopologies(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionTopologiesCleared, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + + hr = IMFMediaSession_ClearTopologies(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionTopologiesCleared, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + + hr = IMFMediaSession_Close(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionClosed, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + + hr = IMFMediaSession_ClearTopologies(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionTopologiesCleared, 1000, &propvar); + ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + + hr = IMFMediaSession_Shutdown(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* sometimes briefly leaking */ + IMFMediaSession_Release(session); + IMFAsyncCallback_Release(callback); + + hr = MFShutdown(); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=121934
Your paranoid android.
=== debian11 (64 bit WoW report) ===
mf: mf.c:2007: Test failed: Unexpected hr 0x80020008. mf.c:2008: Test failed: WaitForSingleObject returned 258 Unhandled exception: page fault on read access to 0x0000000000000000 in 64-bit code (0x0000000040d393).
Report validation errors: mf:mf prints too much data (51673 bytes)
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/mf.c | 127 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index bcb766a231d..6234996c408 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1932,12 +1932,32 @@ static HRESULT wait_media_event_(int line, IMFMediaSession *session, IMFAsyncCal
static void test_media_session_events(void) { + static const media_type_desc audio_pcm_44100 = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 1), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), + }; + IMFAsyncCallback *callback, *callback2; + IMFTopologyNode *src_node, *sink_node; + IMFTopology *topology, *full_topology; + IMFPresentationDescriptor *pd; + IMFStreamSink *stream_sink; IMFMediaSession *session; + IMFMediaType *input_type; + IMFMediaSink *media_sink; + IMFStreamDescriptor *sd; IMFAsyncResult *result; + IMFMediaSource *source; IMFMediaEvent *event; PROPVARIANT propvar; HRESULT hr; + ULONG ref;
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); ok(hr == S_OK, "Startup failure, hr %#lx.\n", hr); @@ -2050,10 +2070,117 @@ static void test_media_session_events(void) hr = IMFMediaSession_Shutdown(session); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ /* sometimes briefly leaking */ + IMFMediaSession_Release(session); + + + hr = MFCreateMediaSession(NULL, &session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateAudioRenderer(NULL, &media_sink); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaSink_GetStreamSinkByIndex(media_sink, 0, &stream_sink); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_sink_node(stream_sink, -1, sink_node); + + hr = MFCreateMediaType(&input_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(input_type, audio_pcm_44100, -1); + create_descriptors(1, &input_type, NULL, &pd, &sd); + + hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_source_node(NULL, -1, src_node, pd, sd); + + hr = MFCreateTopology(&topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopology_AddNode(topology, sink_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopology_AddNode(topology, src_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSession_SetTopology(session, 0, topology); + todo_wine + ok(hr == MF_E_TOPO_MISSING_SOURCE, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + hr = wait_media_event(session, callback, MESessionTopologySet, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&propvar); + } + + source = create_test_source(pd); + init_source_node(source, -1, src_node, pd, sd); + + hr = IMFMediaSession_SetTopology(session, 0, topology); + todo_wine + ok(hr == MF_E_TOPO_STREAM_DESCRIPTOR_NOT_SELECTED, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + hr = wait_media_event(session, callback, MESessionTopologySet, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&propvar); + } + + IMFPresentationDescriptor_SelectStream(pd, 0); + + hr = IMFMediaSession_SetTopology(session, 0, topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionTopologySet, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_UNKNOWN, "got vt %u\n", propvar.vt); + ok(propvar.punkVal != (IUnknown *)topology, "got punkVal %p\n", propvar.punkVal); + hr = IUnknown_QueryInterface(propvar.punkVal, &IID_IMFTopology, (void **)&full_topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&propvar); + + hr = IMFMediaSession_ClearTopologies(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionTopologiesCleared, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + + hr = IMFMediaSession_Shutdown(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + /* sometimes briefly leaking */ IMFMediaSession_Release(session); IMFAsyncCallback_Release(callback);
+ /* Windows requires this to avoid leaking source */ + hr = IMFTopology_Clear(full_topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFTopology_Release(full_topology); + ok(ref == 0, "Release returned %ld\n", ref); + + hr = IMFTopology_Clear(topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFTopologyNode_Release(src_node); + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFTopologyNode_Release(sink_node); + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFTopology_Release(topology); + ok(ref == 0, "Release returned %ld\n", ref); + + ref = IMFMediaSink_Release(media_sink); + todo_wine + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFStreamSink_Release(stream_sink); + ok(ref == 0, "Release returned %ld\n", ref); + + ref = IMFMediaSource_Release(source); + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFPresentationDescriptor_Release(pd); + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFStreamDescriptor_Release(sd); + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFMediaType_Release(input_type); + ok(ref == 0, "Release returned %ld\n", ref); +
hr = MFShutdown(); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/mf.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 6234996c408..e0a295c5be7 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1944,12 +1944,13 @@ static void test_media_session_events(void) };
IMFAsyncCallback *callback, *callback2; + IMFMediaType *input_type, *media_type; IMFTopologyNode *src_node, *sink_node; IMFTopology *topology, *full_topology; IMFPresentationDescriptor *pd; + IMFMediaTypeHandler *handler; IMFStreamSink *stream_sink; IMFMediaSession *session; - IMFMediaType *input_type; IMFMediaSink *media_sink; IMFStreamDescriptor *sd; IMFAsyncResult *result; @@ -2128,6 +2129,11 @@ static void test_media_session_events(void)
IMFPresentationDescriptor_SelectStream(pd, 0);
+ hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &handler); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type); + ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaSession_SetTopology(session, 0, topology); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = wait_media_event(session, callback, MESessionTopologySet, 1000, &propvar); @@ -2138,6 +2144,12 @@ static void test_media_session_events(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); PropVariantClear(&propvar);
+ hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaTypeHandler_Release(handler); + if (hr == S_OK) IMFMediaType_Release(media_type); + hr = IMFMediaSession_ClearTopologies(session); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = wait_media_event(session, callback, MESessionTopologiesCleared, 1000, &propvar);
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/mf/session.c | 21 +++++++++++++++++++++ dlls/mf/tests/mf.c | 5 +++-- 2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 87fe77a730f..18952fb1f6e 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -592,7 +592,28 @@ static HRESULT session_bind_output_nodes(IMFTopology *topology) }
if (stream_sink) + { + IMFMediaTypeHandler *handler; + + if (SUCCEEDED(hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &handler))) + { + IMFMediaType *type; + + if (SUCCEEDED(hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &type))) + IMFMediaType_Release(type); + else if (hr == MF_E_NOT_INITIALIZED) + { + for (i = 0; FAILED(hr) && SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, i, &type)); ++i) + { + hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, type); + IMFMediaType_Release(type); + } + } + + IMFMediaTypeHandler_Release(handler); + } IMFStreamSink_Release(stream_sink); + } IUnknown_Release(object); }
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index e0a295c5be7..bc85a2f7a70 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2132,6 +2132,7 @@ static void test_media_session_events(void) hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &handler); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type); + todo_wine ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaSession_SetTopology(session, 0, topology); @@ -2145,10 +2146,9 @@ static void test_media_session_events(void) PropVariantClear(&propvar);
hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); IMFMediaTypeHandler_Release(handler); - if (hr == S_OK) IMFMediaType_Release(media_type); + IMFMediaType_Release(media_type);
hr = IMFMediaSession_ClearTopologies(session); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -2182,6 +2182,7 @@ static void test_media_session_events(void) todo_wine ok(ref == 0, "Release returned %ld\n", ref); ref = IMFStreamSink_Release(stream_sink); + todo_wine ok(ref == 0, "Release returned %ld\n", ref);
ref = IMFMediaSource_Release(source);
This is also in preparation to add more tests for https://gitlab.winehq.org/wine/wine/-/merge_requests/607.