From f7bd81439e7a69f5af5864809a0779c7a633366d Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 22 Apr 2020 16:32:11 +0300 Subject: [PATCH] mf: Implement IMFSimpleAudioVolume for SAR stream. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/mf/sar.c | 68 ++++++++++++++++++++++++++++++++++++++++------ dlls/mf/tests/mf.c | 25 +++++++++++++++-- 2 files changed, 82 insertions(+), 11 deletions(-) diff --git a/dlls/mf/sar.c b/dlls/mf/sar.c index 83d50b7f0bc..86a0c2f36ec 100644 --- a/dlls/mf/sar.c +++ b/dlls/mf/sar.c @@ -59,6 +59,7 @@ struct audio_renderer IMMDevice *device; IAudioClient *audio_client; IAudioStreamVolume *stream_volume; + ISimpleAudioVolume *audio_volume; HANDLE buffer_ready_event; enum stream_state state; BOOL is_shut_down; @@ -170,6 +171,9 @@ static void audio_renderer_release_audio_client(struct audio_renderer *renderer) if (renderer->stream_volume) IAudioStreamVolume_Release(renderer->stream_volume); renderer->stream_volume = NULL; + if (renderer->audio_volume) + ISimpleAudioVolume_Release(renderer->audio_volume); + renderer->audio_volume = NULL; } static ULONG WINAPI audio_renderer_sink_Release(IMFMediaSink *iface) @@ -754,30 +758,72 @@ static ULONG WINAPI audio_renderer_simple_volume_Release(IMFSimpleAudioVolume *i static HRESULT WINAPI audio_renderer_simple_volume_SetMasterVolume(IMFSimpleAudioVolume *iface, float level) { - FIXME("%p, %f.\n", iface, level); + struct audio_renderer *renderer = impl_from_IMFSimpleAudioVolume(iface); + HRESULT hr = S_OK; - return E_NOTIMPL; + TRACE("%p, %f.\n", iface, level); + + EnterCriticalSection(&renderer->cs); + if (renderer->audio_volume) + hr = ISimpleAudioVolume_SetMasterVolume(renderer->audio_volume, level, NULL); + LeaveCriticalSection(&renderer->cs); + + return hr; } static HRESULT WINAPI audio_renderer_simple_volume_GetMasterVolume(IMFSimpleAudioVolume *iface, float *level) { - FIXME("%p, %p.\n", iface, level); + struct audio_renderer *renderer = impl_from_IMFSimpleAudioVolume(iface); + HRESULT hr = S_OK; - return E_NOTIMPL; + TRACE("%p, %p.\n", iface, level); + + if (!level) + return E_POINTER; + + *level = 0.0f; + + EnterCriticalSection(&renderer->cs); + if (renderer->audio_volume) + hr = ISimpleAudioVolume_GetMasterVolume(renderer->audio_volume, level); + LeaveCriticalSection(&renderer->cs); + + return hr; } static HRESULT WINAPI audio_renderer_simple_volume_SetMute(IMFSimpleAudioVolume *iface, BOOL mute) { - FIXME("%p, %d.\n", iface, mute); + struct audio_renderer *renderer = impl_from_IMFSimpleAudioVolume(iface); + HRESULT hr = S_OK; - return E_NOTIMPL; + TRACE("%p, %d.\n", iface, mute); + + EnterCriticalSection(&renderer->cs); + if (renderer->audio_volume) + hr = ISimpleAudioVolume_SetMute(renderer->audio_volume, mute, NULL); + LeaveCriticalSection(&renderer->cs); + + return hr; } static HRESULT WINAPI audio_renderer_simple_volume_GetMute(IMFSimpleAudioVolume *iface, BOOL *mute) { - FIXME("%p, %p.\n", iface, mute); + struct audio_renderer *renderer = impl_from_IMFSimpleAudioVolume(iface); + HRESULT hr = S_OK; - return E_NOTIMPL; + TRACE("%p, %p.\n", iface, mute); + + if (!mute) + return E_POINTER; + + *mute = FALSE; + + EnterCriticalSection(&renderer->cs); + if (renderer->audio_volume) + hr = ISimpleAudioVolume_GetMute(renderer->audio_volume, mute); + LeaveCriticalSection(&renderer->cs); + + return hr; } static const IMFSimpleAudioVolumeVtbl audio_renderer_simple_volume_vtbl = @@ -1330,6 +1376,12 @@ static HRESULT audio_renderer_create_audio_client(struct audio_renderer *rendere return hr; } + if (FAILED(hr = IAudioClient_GetService(renderer->audio_client, &IID_ISimpleAudioVolume, (void **)&renderer->audio_volume))) + { + WARN("Failed to get audio volume control, hr %#x.\n", hr); + return hr; + } + if (FAILED(hr = IAudioClient_SetEventHandle(renderer->audio_client, renderer->buffer_ready_event))) { WARN("Failed to set event handle, hr %#x.\n", hr); diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 675bc0a443b..62e70954f00 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2726,6 +2726,7 @@ static void test_sar(void) IMFMediaTypeHandler *handler, *handler2; IMFPresentationTimeSource *time_source; IMFSimpleAudioVolume *simple_volume; + IMFAudioStreamVolume *stream_volume; IMFClockStateSink *state_sink; IMFMediaSink *sink, *sink2; IMFStreamSink *stream_sink; @@ -2817,6 +2818,15 @@ if (SUCCEEDED(hr)) hr = IMFClockStateSink_OnClockStart(state_sink, 0, 0); ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr); + hr = IMFClockStateSink_OnClockPause(state_sink, 0); + ok(hr == MF_E_INVALID_STATE_TRANSITION, "Unexpected hr %#x.\n", hr); + + hr = IMFClockStateSink_OnClockStop(state_sink, 0); + ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr); + + hr = IMFClockStateSink_OnClockRestart(state_sink, 0); + ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr); + IMFClockStateSink_Release(state_sink); hr = IMFMediaSink_SetPresentationClock(sink, NULL); @@ -2979,6 +2989,9 @@ todo_wine hr = IMFClockStateSink_OnClockRestart(state_sink, 0); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFClockStateSink_OnClockStop(state_sink, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IMFClockStateSink_Release(state_sink); IMFStreamSink_Release(stream_sink); @@ -2988,14 +3001,20 @@ todo_wine ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr); hr = IMFSimpleAudioVolume_GetMute(simple_volume, &mute); -todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); IMFSimpleAudioVolume_Release(simple_volume); - hr = MFGetService((IUnknown *)sink, &MR_STREAM_VOLUME_SERVICE, &IID_IMFAudioStreamVolume, (void **)&unk); + hr = MFGetService((IUnknown *)sink, &MR_STREAM_VOLUME_SERVICE, &IID_IMFAudioStreamVolume, (void **)&stream_volume); ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr); - IUnknown_Release(unk); + + hr = IMFAudioStreamVolume_GetChannelCount(stream_volume, &count); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFAudioStreamVolume_GetChannelCount(stream_volume, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + IMFAudioStreamVolume_Release(stream_volume); hr = MFGetService((IUnknown *)sink, &MR_AUDIO_POLICY_SERVICE, &IID_IMFAudioPolicy, (void **)&unk); todo_wine