Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/mf_private.h | 1 + dlls/mf/sar.c | 5 +++++ dlls/mf/session.c | 51 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/dlls/mf/mf_private.h b/dlls/mf/mf_private.h index 2f81eaa13b0..db6f101cd6d 100644 --- a/dlls/mf/mf_private.h +++ b/dlls/mf/mf_private.h @@ -80,4 +80,5 @@ static inline const char *debugstr_time(LONGLONG time) }
extern BOOL mf_is_sample_copier_transform(IMFTransform *transform) DECLSPEC_HIDDEN; +extern BOOL mf_is_sar_sink(IMFMediaSink *sink) DECLSPEC_HIDDEN; extern HRESULT topology_node_get_object(IMFTopologyNode *node, REFIID riid, void **obj) DECLSPEC_HIDDEN; diff --git a/dlls/mf/sar.c b/dlls/mf/sar.c index e35531acb71..f6f2b32dd2d 100644 --- a/dlls/mf/sar.c +++ b/dlls/mf/sar.c @@ -1915,6 +1915,11 @@ failed: return hr; }
+BOOL mf_is_sar_sink(IMFMediaSink *sink) +{ + return sink->lpVtbl == &audio_renderer_sink_vtbl; +} + static void sar_shutdown_object(void *user_context, IUnknown *obj) { IMFMediaSink *sink; diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 9e8429fa8ac..df7a987bc55 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -1952,18 +1952,36 @@ 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) +typedef BOOL (*p_renderer_node_test_func)(IMFMediaSink *sink); + +static BOOL session_video_renderer_test_func(IMFMediaSink *sink) +{ + IUnknown *obj; + HRESULT hr; + + /* Use first sink to support IMFVideoRenderer. */ + hr = IMFMediaSink_QueryInterface(sink, &IID_IMFVideoRenderer, (void **)&obj); + if (obj) + IUnknown_Release(obj); + + return hr == S_OK; +} + +static BOOL session_audio_renderer_test_func(IMFMediaSink *sink) +{ + return mf_is_sar_sink(sink); +} + +static HRESULT session_get_renderer_node_service(struct media_session *session, + p_renderer_node_test_func node_test_func, 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, @@ -1975,11 +1993,10 @@ static HRESULT session_get_video_render_service(struct media_session *session, R { if (SUCCEEDED(IMFStreamSink_GetMediaSink(stream_sink, &sink))) { - if (SUCCEEDED(IMFMediaSink_QueryInterface(sink, &IID_IMFVideoRenderer, (void **)&vr))) + if (node_test_func(sink)) { - if (FAILED(hr = MFGetService(vr, service, riid, obj))) - WARN("Failed to get service from video renderer %#x.\n", hr); - IUnknown_Release(vr); + if (FAILED(hr = MFGetService((IUnknown *)sink, service, riid, obj))) + WARN("Failed to get service from renderer node, %#x.\n", hr); } } IMFStreamSink_Release(stream_sink); @@ -1998,6 +2015,20 @@ static HRESULT session_get_video_render_service(struct media_session *session, R return hr; }
+static HRESULT session_get_audio_render_service(struct media_session *session, REFGUID service, + REFIID riid, void **obj) +{ + return session_get_renderer_node_service(session, session_audio_renderer_test_func, + service, riid, obj); +} + +static HRESULT session_get_video_render_service(struct media_session *session, REFGUID service, + REFIID riid, void **obj) +{ + return session_get_renderer_node_service(session, session_video_renderer_test_func, + service, riid, obj); +} + static HRESULT WINAPI session_get_service_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj) { struct media_session *session = impl_from_IMFGetService(iface); @@ -2040,6 +2071,10 @@ static HRESULT WINAPI session_get_service_GetService(IMFGetService *iface, REFGU { hr = session_get_video_render_service(session, service, riid, obj); } + else if (IsEqualGUID(service, &MR_POLICY_VOLUME_SERVICE)) + { + hr = session_get_audio_render_service(session, service, riid, obj); + } else FIXME("Unsupported service %s.\n", debugstr_guid(service));
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index df7a987bc55..91d8f0cac87 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -1975,12 +1975,12 @@ static BOOL session_audio_renderer_test_func(IMFMediaSink *sink) static HRESULT session_get_renderer_node_service(struct media_session *session, p_renderer_node_test_func node_test_func, REFGUID service, REFIID riid, void **obj) { + HRESULT hr = E_NOINTERFACE; IMFStreamSink *stream_sink; IMFTopologyNode *node; IMFCollection *nodes; IMFMediaSink *sink; unsigned int i = 0; - HRESULT hr = E_FAIL;
if (session->presentation.current_topology) {