[vlc-commits] [Git][videolan/vlc][master] 5 commits: wasapi: call vlc_timer_disarm directly

Hugo Beauzée-Luyssen (@chouquette) gitlab at videolan.org
Wed Jul 20 09:44:36 UTC 2022



Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC


Commits:
cb1f84a3 by Thomas Guillem at 2022-07-20T09:24:19+00:00
wasapi: call vlc_timer_disarm directly

- - - - -
b71f9625 by Thomas Guillem at 2022-07-20T09:24:19+00:00
wasapi: fix double start leading to invalid state

Check that the stream is not started after disarming the timer. This
could lead to a double call to IAudioClient_Start().

The second call to IAudioClient_Start() fails (not critical) but the
started_state is set to STARTED_STATE_ERROR preventing any future
playback.

Fixes #27128

- - - - -
c0267647 by Thomas Guillem at 2022-07-20T09:24:19+00:00
wasapi: refactor start

- - - - -
42819895 by Thomas Guillem at 2022-07-20T09:24:19+00:00
wasapi: log stream start error

No need to log success since it's already done by mmdevice.

- - - - -
cb9014af by Thomas Guillem at 2022-07-20T09:24:19+00:00
wasapi: use StartNow() from Pause()

This will set the started_state in case of error, preventing any future
playback.

- - - - -


1 changed file:

- modules/audio_output/wasapi.c


Changes:

=====================================
modules/audio_output/wasapi.c
=====================================
@@ -125,12 +125,6 @@ typedef struct aout_stream_sys
     bool s24s32; /**< Output configured as S24N, but input as S32N */
 } aout_stream_sys_t;
 
-static void ResetTimer(aout_stream_t *s)
-{
-    aout_stream_sys_t *sys = s->sys;
-    vlc_timer_disarm(sys->timer);
-}
-
 /*** VLC audio output callbacks ***/
 static HRESULT TimeGet(aout_stream_t *s, vlc_tick_t *restrict delay)
 {
@@ -172,10 +166,24 @@ static HRESULT TimeGet(aout_stream_t *s, vlc_tick_t *restrict delay)
     return hr;
 }
 
+static HRESULT StartNow(aout_stream_t *s)
+{
+    aout_stream_sys_t *sys = s->sys;
+
+    HRESULT hr = IAudioClient_Start(sys->client);
+
+    atomic_store(&sys->started_state,
+                 SUCCEEDED(hr) ? STARTED_STATE_OK : STARTED_STATE_ERROR);
+
+    if (FAILED(hr))
+        msg_Err(s, "stream failed to start: 0x%lX", hr);
+
+    return hr;
+}
+
 static void StartDeferredCallback(void *val)
 {
     aout_stream_t *s = val;
-    aout_stream_sys_t *sys = s->sys;
 
     HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
     if (unlikely(FAILED(hr)))
@@ -184,12 +192,9 @@ static void StartDeferredCallback(void *val)
         return;
     }
 
-    hr = IAudioClient_Start(sys->client);
+    StartNow(s);
 
     CoUninitialize();
-
-    atomic_store(&sys->started_state,
-                 SUCCEEDED(hr) ? STARTED_STATE_OK : STARTED_STATE_ERROR);
 }
 
 static HRESULT StartDeferred(aout_stream_t *s, vlc_tick_t date)
@@ -197,29 +202,22 @@ static HRESULT StartDeferred(aout_stream_t *s, vlc_tick_t date)
     aout_stream_sys_t *sys = s->sys;
     vlc_tick_t written = vlc_tick_from_frac(sys->written, sys->rate);
     vlc_tick_t start_delay = date - vlc_tick_now() - written;
-    BOOL timer_updated = false;
 
     /* Create or update the current timer */
     if (start_delay > 0)
     {
         vlc_timer_schedule( sys->timer, false, start_delay, 0);
-        timer_updated = true;
+        msg_Dbg(s, "deferring start (%"PRId64" us)", start_delay);
     }
     else
-        ResetTimer(s);
-
-    if (!timer_updated)
     {
-        HRESULT hr = IAudioClient_Start(sys->client);
-        if (FAILED(hr))
-        {
-            atomic_store(&sys->started_state, STARTED_STATE_ERROR);
-            return hr;
-        }
-        atomic_store(&sys->started_state, STARTED_STATE_OK);
+        vlc_timer_disarm(sys->timer);
+
+        /* Check started_state again, since the timer callback could have been
+         * called before or while disarming the timer */
+        if (atomic_load(&sys->started_state) == STARTED_STATE_INIT)
+            return StartNow(s);
     }
-    else
-        msg_Dbg(s, "deferring start (%"PRId64" us)", start_delay);
 
     return S_OK;
 }
@@ -332,18 +330,19 @@ static HRESULT Pause(aout_stream_t *s, bool paused)
 
     if (paused)
     {
-        ResetTimer(s);
+        vlc_timer_disarm(sys->timer);
         if (atomic_load(&sys->started_state) == STARTED_STATE_OK)
+        {
             hr = IAudioClient_Stop(sys->client);
+            if (FAILED(hr))
+                msg_Warn(s, "cannot stop stream (error 0x%lX)", hr);
+        }
         else
             hr = S_OK;
         /* Don't reset the timer state, we won't have to start deferred again. */
     }
     else
-        hr = IAudioClient_Start(sys->client);
-    if (FAILED(hr))
-        msg_Warn(s, "cannot %s stream (error 0x%lX)",
-                 paused ? "stop" : "start", hr);
+        hr = StartNow(s);
     return hr;
 }
 
@@ -352,7 +351,7 @@ static HRESULT Flush(aout_stream_t *s)
     aout_stream_sys_t *sys = s->sys;
     HRESULT hr;
 
-    ResetTimer(s);
+    vlc_timer_disarm(sys->timer);
     /* Reset the timer state, the next start need to be deferred. */
     if (atomic_exchange(&sys->started_state, STARTED_STATE_INIT) == STARTED_STATE_OK)
     {
@@ -610,7 +609,7 @@ static void Stop(aout_stream_t *s)
 {
     aout_stream_sys_t *sys = s->sys;
 
-    ResetTimer(s);
+    vlc_timer_disarm(sys->timer);
 
     if (atomic_load(&sys->started_state) == STARTED_STATE_OK)
         IAudioClient_Stop(sys->client);



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/3a1a8d1d2466007b3a7bcab2e96e907d03afb2f7...cb9014af76be77267ff6928ece63dd8e986e0f96

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/3a1a8d1d2466007b3a7bcab2e96e907d03afb2f7...cb9014af76be77267ff6928ece63dd8e986e0f96
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list