From aeaef855077384f4d669dc8013948a17b5ce38cc Mon Sep 17 00:00:00 2001 From: Richard Schorrig Date: Tue, 22 Feb 2022 21:05:41 +0100 Subject: [PATCH] WasapiOutputPlugin pause bug fix Wasapi output plugin won't start playing after being paused The cause is that the scope guard in the WASAPI work thread (WasapiOutputPlugin.cxx, function WasapiOutputThread::Work(), in the while (true) loop) is set up too 'late' in the execution. There is one condition ("if (data_in_frames >= buffer_size_in_frames)") when it is hit, the loop will continue without executing the scope guard. This scope guard is responsible for emptying the buffer again, and if the buffer is not emptied, the above mentioned condition will stay true. Closes https://github.com/MusicPlayerDaemon/MPD/issues/1451 --- NEWS | 1 + .../plugins/wasapi/WasapiOutputPlugin.cxx | 20 +++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index daa2b77a7..cdc114954 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ ver 0.23.6 (not yet released) - opus: fix "readpicture" on Opus files * output - pipewire: fix crash bug if setting volume before playback starts + - wasapi: fix resume after pause ver 0.23.5 (2021/12/01) * protocol diff --git a/src/output/plugins/wasapi/WasapiOutputPlugin.cxx b/src/output/plugins/wasapi/WasapiOutputPlugin.cxx index bedd9f756..992dc2e67 100644 --- a/src/output/plugins/wasapi/WasapiOutputPlugin.cxx +++ b/src/output/plugins/wasapi/WasapiOutputPlugin.cxx @@ -471,6 +471,16 @@ try { } UINT32 write_in_frames = buffer_size_in_frames; + DWORD mode = 0; + AtScopeExit(&) { + render_client->ReleaseBuffer(write_in_frames, mode); + + if (!started) { + Start(client); + started = true; + } + }; + if (!is_exclusive) { UINT32 data_in_frames = GetCurrentPaddingFrames(client); @@ -481,7 +491,6 @@ try { } BYTE *data; - DWORD mode = 0; if (HRESULT result = render_client->GetBuffer(write_in_frames, &data); @@ -489,15 +498,6 @@ try { throw MakeHResultError(result, "Failed to get buffer"); } - AtScopeExit(&) { - render_client->ReleaseBuffer(write_in_frames, mode); - - if (!started) { - Start(client); - started = true; - } - }; - const UINT32 write_size = write_in_frames * frame_size; UINT32 new_data_size = 0; new_data_size = spsc_buffer.pop(data, write_size);