Nikolay Sivov : mf/session: Handle shutdown state on GetService().
Alexandre Julliard
julliard at winehq.org
Mon Apr 12 16:11:26 CDT 2021
Module: wine
Branch: master
Commit: a2728cdeced4d1ae28f56eb73b822b8e9779a7fa
URL: https://source.winehq.org/git/wine.git/?a=commit;h=a2728cdeced4d1ae28f56eb73b822b8e9779a7fa
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon Apr 12 12:19:53 2021 +0300
mf/session: Handle shutdown state on GetService().
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mf/session.c | 110 ++++++++++++++++++++++++++++++-----------------------
dlls/mf/tests/mf.c | 11 ++++++
2 files changed, 73 insertions(+), 48 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c
index 20ccdd0535e..7a8c7e9f598 100644
--- a/dlls/mf/session.c
+++ b/dlls/mf/session.c
@@ -2020,15 +2020,66 @@ static ULONG WINAPI session_get_service_Release(IMFGetService *iface)
return IMFMediaSession_Release(&session->IMFMediaSession_iface);
}
+static HRESULT session_get_video_render_service(struct media_session *session, REFGUID service,
+ REFIID riid, void **obj)
+{
+ IMFStreamSink *stream_sink;
+ IMFTopologyNode *node;
+ IMFCollection *nodes;
+ IMFMediaSink *sink;
+ unsigned int i = 0;
+ IUnknown *vr;
+ HRESULT hr = E_FAIL;
+
+ /* Use first sink to support IMFVideoRenderer. */
+ if (session->presentation.current_topology)
+ {
+ if (SUCCEEDED(IMFTopology_GetOutputNodeCollection(session->presentation.current_topology,
+ &nodes)))
+ {
+ while (IMFCollection_GetElement(nodes, i++, (IUnknown **)&node) == S_OK)
+ {
+ if (SUCCEEDED(topology_node_get_object(node, &IID_IMFStreamSink, (void **)&stream_sink)))
+ {
+ if (SUCCEEDED(IMFStreamSink_GetMediaSink(stream_sink, &sink)))
+ {
+ if (SUCCEEDED(IMFMediaSink_QueryInterface(sink, &IID_IMFVideoRenderer, (void **)&vr)))
+ {
+ if (FAILED(hr = MFGetService(vr, service, riid, obj)))
+ WARN("Failed to get service from video renderer %#x.\n", hr);
+ IUnknown_Release(vr);
+ }
+ }
+ IMFStreamSink_Release(stream_sink);
+ }
+
+ IMFTopologyNode_Release(node);
+
+ if (*obj)
+ break;
+ }
+
+ IMFCollection_Release(nodes);
+ }
+ }
+
+ return hr;
+}
+
static HRESULT WINAPI session_get_service_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj)
{
struct media_session *session = impl_from_IMFGetService(iface);
+ HRESULT hr = S_OK;
TRACE("%p, %s, %s, %p.\n", iface, debugstr_guid(service), debugstr_guid(riid), obj);
*obj = NULL;
- if (IsEqualGUID(service, &MF_RATE_CONTROL_SERVICE))
+ EnterCriticalSection(&session->cs);
+ if (FAILED(hr = session_is_shut_down(session)))
+ {
+ }
+ else if (IsEqualGUID(service, &MF_RATE_CONTROL_SERVICE))
{
if (IsEqualIID(riid, &IID_IMFRateSupport))
{
@@ -2038,68 +2089,31 @@ static HRESULT WINAPI session_get_service_GetService(IMFGetService *iface, REFGU
{
*obj = &session->IMFRateControl_iface;
}
+ else
+ hr = E_NOINTERFACE;
+
+ if (*obj)
+ IUnknown_AddRef((IUnknown *)*obj);
}
else if (IsEqualGUID(service, &MF_LOCAL_MFT_REGISTRATION_SERVICE))
{
- return IMFLocalMFTRegistration_QueryInterface(&local_mft_registration, riid, obj);
+ hr = IMFLocalMFTRegistration_QueryInterface(&local_mft_registration, riid, obj);
}
else if (IsEqualGUID(service, &MF_TOPONODE_ATTRIBUTE_EDITOR_SERVICE))
{
*obj = &session->IMFTopologyNodeAttributeEditor_iface;
+ IUnknown_AddRef((IUnknown *)*obj);
}
else if (IsEqualGUID(service, &MR_VIDEO_RENDER_SERVICE))
{
- IMFStreamSink *stream_sink;
- IMFTopologyNode *node;
- IMFCollection *nodes;
- IMFMediaSink *sink;
- unsigned int i = 0;
- IUnknown *vr;
- HRESULT hr;
-
- EnterCriticalSection(&session->cs);
-
- /* Use first sink to support IMFVideoRenderer. */
- if (session->presentation.current_topology)
- {
- if (SUCCEEDED(IMFTopology_GetOutputNodeCollection(session->presentation.current_topology,
- &nodes)))
- {
- while (IMFCollection_GetElement(nodes, i++, (IUnknown **)&node) == S_OK)
- {
- if (SUCCEEDED(topology_node_get_object(node, &IID_IMFStreamSink, (void **)&stream_sink)))
- {
- if (SUCCEEDED(IMFStreamSink_GetMediaSink(stream_sink, &sink)))
- {
- if (SUCCEEDED(IMFMediaSink_QueryInterface(sink, &IID_IMFVideoRenderer, (void **)&vr)))
- {
- if (FAILED(hr = MFGetService(vr, service, riid, obj)))
- WARN("Failed to get service from video renderer %#x.\n", hr);
- IUnknown_Release(vr);
- }
- }
- IMFStreamSink_Release(stream_sink);
- }
-
- IMFTopologyNode_Release(node);
-
- if (*obj)
- break;
- }
-
- IMFCollection_Release(nodes);
- }
- }
-
- LeaveCriticalSection(&session->cs);
+ hr = session_get_video_render_service(session, service, riid, obj);
}
else
FIXME("Unsupported service %s.\n", debugstr_guid(service));
- if (*obj)
- IUnknown_AddRef((IUnknown *)*obj);
+ LeaveCriticalSection(&session->cs);
- return *obj ? S_OK : E_NOINTERFACE;
+ return hr;
}
static const IMFGetServiceVtbl session_get_service_vtbl =
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 20440499227..308c1fae529 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -1170,6 +1170,7 @@ static void test_media_session(void)
IMFShutdown *shutdown;
PROPVARIANT propvar;
DWORD status, caps;
+ IMFGetService *gs;
IMFClock *clock;
IUnknown *unk;
HRESULT hr;
@@ -1271,6 +1272,16 @@ todo_wine
hr = IMFMediaSession_Shutdown(session);
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
+ check_interface(session, &IID_IMFGetService, TRUE);
+
+ hr = IMFMediaSession_QueryInterface(session, &IID_IMFGetService, (void **)&gs);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFGetService_GetService(gs, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void **)&rate_support);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+ IMFGetService_Release(gs);
+
hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(status == MFSHUTDOWN_COMPLETED, "Unexpected shutdown status %u.\n", status);
More information about the wine-cvs
mailing list