[vlc-devel] [PATCH 2/3] wasapi: enable event-driven buffering

Thomas Guillem thomas at gllm.fr
Mon Sep 30 16:26:10 CEST 2019


And remove the sleep in case of full buffer. This will improve low delay
rendering.
---
 modules/audio_output/wasapi.c | 34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/modules/audio_output/wasapi.c b/modules/audio_output/wasapi.c
index 99506c6ef1..62827caa2e 100644
--- a/modules/audio_output/wasapi.c
+++ b/modules/audio_output/wasapi.c
@@ -90,6 +90,7 @@ static msftime_t GetQPC(void)
 typedef struct aout_stream_sys
 {
     IAudioClient *client;
+    HANDLE hEvent;
 
     uint8_t chans_table[AOUT_CHAN_MAX];
     uint8_t chans_to_reorder;
@@ -200,8 +201,13 @@ static HRESULT Play(aout_stream_t *s, block_t *block, vlc_tick_t date)
         if (block->i_nb_samples == 0)
             break; /* done */
 
-        /* Out of buffer space, sleep */
-        vlc_tick_sleep(sys->frames * VLC_TICK_FROM_MS(500) / sys->rate);
+        /* Wait for the next buffer event to be signaled */
+        DWORD retval = WaitForSingleObject(sys->hEvent, 2000);
+        if (retval != WAIT_OBJECT_0)
+        {
+            msg_Err(s, "audio event timeouted");
+            break; /* Timeout, should not happen */
+        }
     }
     IAudioRenderClient_Release(render);
 out:
@@ -461,6 +467,7 @@ static void Stop(aout_stream_t *s)
     aout_stream_sys_t *sys = s->sys;
 
     IAudioClient_Stop(sys->client); /* should not be needed */
+    CloseHandle(sys->hEvent);
     IAudioClient_Release(sys->client);
 
     free(sys);
@@ -478,6 +485,7 @@ static HRESULT Start(aout_stream_t *s, audio_sample_format_t *restrict pfmt,
     if (unlikely(sys == NULL))
         return E_OUTOFMEMORY;
     sys->client = NULL;
+    sys->hEvent = NULL;
 
     /* Configure audio stream */
     WAVEFORMATEXTENSIBLE_IEC61937 wf_iec61937;
@@ -598,8 +606,9 @@ static HRESULT Start(aout_stream_t *s, audio_sample_format_t *restrict pfmt,
     sys->block_align = pwf->nBlockAlign;
     sys->rate = pwf->nSamplesPerSec;
 
-    hr = IAudioClient_Initialize(sys->client, shared_mode, 0, buffer_duration,
-                                 0, pwf, sid);
+    hr = IAudioClient_Initialize(sys->client, shared_mode,
+                                 AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
+                                 buffer_duration, 0, pwf, sid);
     CoTaskMemFree(pwf_closest);
     if (FAILED(hr))
     {
@@ -624,6 +633,19 @@ static HRESULT Start(aout_stream_t *s, audio_sample_format_t *restrict pfmt,
         msg_Dbg(s, "minimum period : %"PRIu64"00 ns", minT);
     }
 
+    sys->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (sys->hEvent == NULL)
+    {
+        hr = E_FAIL;
+        goto error;
+    }
+    hr = IAudioClient_SetEventHandle(sys->client, sys->hEvent);
+    if (FAILED(hr))
+    {
+        msg_Err(s, "cannot set event handle");
+        goto error;
+    }
+
     CoTaskMemFree(pwf_mix);
     *pfmt = fmt;
     sys->written = 0;
@@ -637,7 +659,11 @@ static HRESULT Start(aout_stream_t *s, audio_sample_format_t *restrict pfmt,
 error:
     CoTaskMemFree(pwf_mix);
     if (sys->client != NULL)
+    {
+        if (sys->hEvent != NULL)
+            CloseHandle(sys->hEvent);
         IAudioClient_Release(sys->client);
+    }
     free(sys);
     return hr;
 }
-- 
2.20.1



More information about the vlc-devel mailing list