From: Bernhard Kölbl besentv@gmail.com
--- dlls/mfmediaengine/main.c | 58 ++++++++++++++++++++---- dlls/mfmediaengine/tests/mfmediaengine.c | 3 ++ 2 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index b2ddc376db8..c15fdbd164c 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -174,6 +174,10 @@ struct media_engine } cb; } d3d11; } video_frame; + struct + { + IMFMediaSink *sar; + } audio_renderer; CRITICAL_SECTION cs; };
@@ -1002,27 +1006,36 @@ static HRESULT media_engine_create_source_node(IMFMediaSource *source, IMFPresen static HRESULT media_engine_create_audio_renderer(struct media_engine *engine, IMFTopologyNode **node) { unsigned int category, role; - IMFActivate *sar_activate; + IMFAttributes *attrs; + IMFStreamSink *sink; + IMFMediaSink *sar; HRESULT hr;
*node = NULL;
- if (FAILED(hr = MFCreateAudioRendererActivate(&sar_activate))) + if (FAILED(hr = MFCreateAttributes(&attrs, 2))) return hr;
/* Configuration attributes keys differ between Engine and SAR. */ if (SUCCEEDED(IMFAttributes_GetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_CATEGORY, &category))) - IMFActivate_SetUINT32(sar_activate, &MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY, category); + IMFAttributes_SetUINT32(attrs, &MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY, category); if (SUCCEEDED(IMFAttributes_GetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE, &role))) - IMFActivate_SetUINT32(sar_activate, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, role); + IMFAttributes_SetUINT32(attrs, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, role); + + if (FAILED(hr = MFCreateAudioRenderer(attrs, &sar))) + return hr; + + if (FAILED(hr = IMFMediaSink_GetStreamSinkByIndex(sar, 0, &sink))) + return hr;
if (SUCCEEDED(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, node))) { - IMFTopologyNode_SetObject(*node, (IUnknown *)sar_activate); + IMFTopologyNode_SetObject(*node, (IUnknown *)sink); IMFTopologyNode_SetUINT32(*node, &MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE); }
- IMFActivate_Release(sar_activate); + IMFStreamSink_Release(sink); + engine->audio_renderer.sar = sar;
return hr; } @@ -1084,6 +1097,12 @@ static void media_engine_clear_presentation(struct media_engine *engine) if (engine->presentation.pd) IMFPresentationDescriptor_Release(engine->presentation.pd); memset(&engine->presentation, 0, sizeof(engine->presentation)); + if (engine->audio_renderer.sar) + { + IMFMediaSink_Shutdown(engine->audio_renderer.sar); + IMFMediaSink_Release(engine->audio_renderer.sar); + engine->audio_renderer.sar = NULL; + } }
static HRESULT media_engine_create_topology(struct media_engine *engine, IMFMediaSource *source) @@ -1999,6 +2018,7 @@ static double WINAPI media_engine_GetVolume(IMFMediaEngineEx *iface) static HRESULT WINAPI media_engine_SetVolume(IMFMediaEngineEx *iface, double volume) { struct media_engine *engine = impl_from_IMFMediaEngineEx(iface); + IMFGetService *service = NULL; HRESULT hr = S_OK;
TRACE("%p, %f.\n", iface, volume); @@ -2008,9 +2028,31 @@ static HRESULT WINAPI media_engine_SetVolume(IMFMediaEngineEx *iface, double vol hr = MF_E_SHUTDOWN; else if (volume != engine->volume) { - engine->volume = volume; - IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_VOLUMECHANGE, 0, 0); + IMFSimpleAudioVolume *sa_volume; + + if (!engine->audio_renderer.sar) + { + hr = E_FAIL; + goto done; + } + + if (FAILED(hr = IMFMediaSink_QueryInterface(engine->audio_renderer.sar, &IID_IMFGetService, (void **)&service))) + goto done; + + if (FAILED(hr = IMFGetService_GetService(service, &MR_POLICY_VOLUME_SERVICE, &IID_IMFSimpleAudioVolume, (void **)&sa_volume))) + goto done; + + if (SUCCEEDED(hr = IMFSimpleAudioVolume_SetMasterVolume(sa_volume, (float)volume))) + { + engine->volume = volume; + IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_VOLUMECHANGE, 0, 0); + } + + IMFSimpleAudioVolume_Release(sa_volume); } +done: + if (service) + IMFGetService_Release(service); LeaveCriticalSection(&engine->cs);
return hr; diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index df662e356af..0d4d89af0f3 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -1472,6 +1472,9 @@ static void test_video_playback(void) res = WaitForSingleObject(notify.ready_event, 5000); ok(!res, "Unexpected res %#lx.\n", res);
+ hr = IMFMediaEngineEx_SetVolume(media_engine, 0.1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(notify.error)) { win_skip("Media engine reported error %#lx, skipping tests.\n", notify.error);