mf/session: Handle shutdown state on GetService().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
aaf520cf5e
commit
a2728cdece
|
@ -2020,15 +2020,66 @@ static ULONG WINAPI session_get_service_Release(IMFGetService *iface)
|
||||||
return IMFMediaSession_Release(&session->IMFMediaSession_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)
|
static HRESULT WINAPI session_get_service_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj)
|
||||||
{
|
{
|
||||||
struct media_session *session = impl_from_IMFGetService(iface);
|
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);
|
TRACE("%p, %s, %s, %p.\n", iface, debugstr_guid(service), debugstr_guid(riid), obj);
|
||||||
|
|
||||||
*obj = NULL;
|
*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))
|
if (IsEqualIID(riid, &IID_IMFRateSupport))
|
||||||
{
|
{
|
||||||
|
@ -2038,68 +2089,31 @@ static HRESULT WINAPI session_get_service_GetService(IMFGetService *iface, REFGU
|
||||||
{
|
{
|
||||||
*obj = &session->IMFRateControl_iface;
|
*obj = &session->IMFRateControl_iface;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
hr = E_NOINTERFACE;
|
||||||
|
|
||||||
|
if (*obj)
|
||||||
|
IUnknown_AddRef((IUnknown *)*obj);
|
||||||
}
|
}
|
||||||
else if (IsEqualGUID(service, &MF_LOCAL_MFT_REGISTRATION_SERVICE))
|
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))
|
else if (IsEqualGUID(service, &MF_TOPONODE_ATTRIBUTE_EDITOR_SERVICE))
|
||||||
{
|
{
|
||||||
*obj = &session->IMFTopologyNodeAttributeEditor_iface;
|
*obj = &session->IMFTopologyNodeAttributeEditor_iface;
|
||||||
|
IUnknown_AddRef((IUnknown *)*obj);
|
||||||
}
|
}
|
||||||
else if (IsEqualGUID(service, &MR_VIDEO_RENDER_SERVICE))
|
else if (IsEqualGUID(service, &MR_VIDEO_RENDER_SERVICE))
|
||||||
{
|
{
|
||||||
IMFStreamSink *stream_sink;
|
hr = session_get_video_render_service(session, service, riid, obj);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
FIXME("Unsupported service %s.\n", debugstr_guid(service));
|
FIXME("Unsupported service %s.\n", debugstr_guid(service));
|
||||||
|
|
||||||
if (*obj)
|
LeaveCriticalSection(&session->cs);
|
||||||
IUnknown_AddRef((IUnknown *)*obj);
|
|
||||||
|
|
||||||
return *obj ? S_OK : E_NOINTERFACE;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const IMFGetServiceVtbl session_get_service_vtbl =
|
static const IMFGetServiceVtbl session_get_service_vtbl =
|
||||||
|
|
|
@ -1170,6 +1170,7 @@ static void test_media_session(void)
|
||||||
IMFShutdown *shutdown;
|
IMFShutdown *shutdown;
|
||||||
PROPVARIANT propvar;
|
PROPVARIANT propvar;
|
||||||
DWORD status, caps;
|
DWORD status, caps;
|
||||||
|
IMFGetService *gs;
|
||||||
IMFClock *clock;
|
IMFClock *clock;
|
||||||
IUnknown *unk;
|
IUnknown *unk;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -1271,6 +1272,16 @@ todo_wine
|
||||||
hr = IMFMediaSession_Shutdown(session);
|
hr = IMFMediaSession_Shutdown(session);
|
||||||
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
|
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);
|
hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
|
||||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||||
ok(status == MFSHUTDOWN_COMPLETED, "Unexpected shutdown status %u.\n", status);
|
ok(status == MFSHUTDOWN_COMPLETED, "Unexpected shutdown status %u.\n", status);
|
||||||
|
|
Loading…
Reference in New Issue