Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 3 +++ dlls/mf/tests/mf.c | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index dffd5113ff9..4821ed5c90a 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -1792,6 +1792,9 @@ static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface) IMFMediaEventQueue_Shutdown(session->event_queue); if (session->quality_manager) IMFQualityManager_Shutdown(session->quality_manager); + MFShutdownObject((IUnknown *)session->clock); + IMFPresentationClock_Release(session->clock); + session->clock = NULL; } LeaveCriticalSection(&session->cs);
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 2a671225a11..27e859fa82d 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1188,13 +1188,14 @@ static void test_media_session(void) IMFAttributes *attributes; IMFMediaSession *session; IMFTopology *topology; + IMFShutdown *shutdown; PROPVARIANT propvar; + DWORD status, caps; IMFGetService *gs; IMFClock *clock; IUnknown *unk; HRESULT hr; float rate; - DWORD caps; BOOL thin;
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); @@ -1275,9 +1276,24 @@ todo_wine hr = MFCreateMediaSession(NULL, &session); ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
+ hr = IMFMediaSession_GetClock(session, &clock); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFClock_QueryInterface(clock, &IID_IMFShutdown, (void **)&shutdown); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFShutdown_GetShutdownStatus(shutdown, &status); + ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr); + hr = IMFMediaSession_Shutdown(session); ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
+ hr = IMFShutdown_GetShutdownStatus(shutdown, &status); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(status == MFSHUTDOWN_COMPLETED, "Unexpected shutdown status %u.\n", status); + + IMFShutdown_Release(shutdown); + hr = IMFMediaSession_ClearTopologies(session); ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 4821ed5c90a..0381917826a 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -32,6 +32,10 @@
#include "mf_private.h"
+#include "initguid.h" + +DEFINE_GUID(_MF_TOPONODE_IMFActivate, 0x33706f4a, 0x309a, 0x49be, 0xa8, 0xdd, 0xe7, 0xc0, 0x87, 0x5e, 0xb6, 0x79); + WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
enum session_command @@ -683,6 +687,9 @@ static HRESULT session_bind_output_nodes(IMFTopology *topology) IMFMediaSink_Release(media_sink); }
+ if (SUCCEEDED(hr)) + IMFTopologyNode_SetUnknown(node, &_MF_TOPONODE_IMFActivate, (IUnknown *)activate); + IMFActivate_Release(activate); } }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 0381917826a..93e1eee915a 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -783,6 +783,61 @@ static void release_topo_node(struct topo_node *node) heap_free(node); }
+static void session_shutdown_current_topology(struct media_session *session) +{ + unsigned int shutdown, force_shutdown; + MF_TOPOLOGY_TYPE node_type; + IMFStreamSink *stream_sink; + IMFTopology *topology; + IMFTopologyNode *node; + IMFActivate *activate; + IMFMediaSink *sink; + IUnknown *object; + WORD idx = 0; + + topology = session->presentation.current_topology; + force_shutdown = session->state == SESSION_STATE_SHUT_DOWN; + + /* FIXME: should handle async MFTs, but these are not supported but the rest of the pipeline currently. */ + + while (SUCCEEDED(IMFTopology_GetNode(topology, idx++, &node))) + { + if (SUCCEEDED(IMFTopologyNode_GetNodeType(node, &node_type)) && + node_type == MF_TOPOLOGY_OUTPUT_NODE) + { + shutdown = 1; + IMFTopologyNode_GetUINT32(node, &MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, &shutdown); + + if (force_shutdown || shutdown) + { + if (SUCCEEDED(IMFTopologyNode_GetUnknown(node, &_MF_TOPONODE_IMFActivate, &IID_IMFActivate, + (void **)&activate))) + { + IMFActivate_ShutdownObject(activate); + IMFActivate_Release(activate); + } + else if (SUCCEEDED(IMFTopologyNode_GetObject(node, &object))) + { + if (SUCCEEDED(IUnknown_QueryInterface(object, &IID_IMFStreamSink, (void **)&stream_sink))) + { + if (SUCCEEDED(IMFStreamSink_GetMediaSink(stream_sink, &sink))) + { + IMFMediaSink_Shutdown(sink); + IMFMediaSink_Release(sink); + } + + IMFStreamSink_Release(stream_sink); + } + + IUnknown_Release(object); + } + } + } + + IMFTopologyNode_Release(node); + } +} + static void session_clear_presentation(struct media_session *session) { struct media_source *source, *source2; @@ -790,6 +845,8 @@ static void session_clear_presentation(struct media_session *session) struct topo_node *node, *node2; struct session_op *op, *op2;
+ session_shutdown_current_topology(session); + IMFTopology_Clear(session->presentation.current_topology); session->presentation.topo_status = MF_TOPOSTATUS_INVALID;
@@ -1790,7 +1847,7 @@ static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface) struct media_session *session = impl_from_IMFMediaSession(iface); HRESULT hr = S_OK;
- FIXME("%p.\n", iface); + TRACE("%p.\n", iface);
EnterCriticalSection(&session->cs); if (SUCCEEDED(hr = session_is_shut_down(session))) @@ -1802,6 +1859,7 @@ static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface) MFShutdownObject((IUnknown *)session->clock); IMFPresentationClock_Release(session->clock); session->clock = NULL; + session_clear_presentation(session); } LeaveCriticalSection(&session->cs);