[vlc-commits] [Git][videolan/vlc][3.0.x] 3 commits: mmdevice: make default_device_changed an atomic bool

Steve Lhomme (@robUx4) gitlab at videolan.org
Thu May 7 14:22:37 UTC 2026



Steve Lhomme pushed to branch 3.0.x at VideoLAN / VLC


Commits:
04a49abb by Steve Lhomme at 2026-05-07T12:49:49+00:00
mmdevice: make default_device_changed an atomic bool

In Start() we check and reset it in one atomic call. It would be set to false later
in DeviceRequestLocked() via the DeviceRestartLocked() call.
It's still (re)set to false in case a new device is set before Start().

(cherry picked from commit 26741cab0c6b7399b8281659dab63c9446569ab4) (rebased)
rebased:
- VLC 3 requires <vlc_atomic.h> to use C atomics
- VLC 3 uses critical sections
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
cf22fac3 by Steve Lhomme at 2026-05-07T12:49:49+00:00
mmdevice: make device_name an atomic wchar_t *

It's always read/written under lock for now.

(cherry picked from commit 27ce8da8487cfcc1d2ff0ce9be57ee96822b8e18) (edited)
edited:
- use an atomic_uintptr_t for the pointer storage as we wan't use _Atomic() in VLC 3
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
8c4e5d61 by Steve Lhomme at 2026-05-07T12:49:49+00:00
mmdevice: remove lock from OnDefaultDeviceChange

sys->device_name may change after we read it.

If we trigger an unwanted restart (read as NULL and became a user selected value),
it's wasteful but supported. The new non-NULL sys->device_name will be used during
both restarts.

We may also miss a restart (read as non-NULL and became NULL=default).

In both cases, when the value sys->device_name is modified a restart will be
triggered anyway. So missing an extra one or adding one will make little
differences.

(cherry picked from commit 2e7b68670413a7f3ea4127590e3629b63b6e2080)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -


1 changed file:

- modules/audio_output/mmdevice.c


Changes:

=====================================
modules/audio_output/mmdevice.c
=====================================
@@ -48,6 +48,7 @@ DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd,
 #include <vlc_aout.h>
 #include <vlc_charset.h>
 #include <vlc_modules.h>
+#include <vlc_atomic.h>
 #include "mmdevice.h"
 
 DEFINE_GUID (GUID_VLC_AUD_OUT, 0x4533f59d, 0x59ee, 0x00c6,
@@ -105,8 +106,8 @@ struct aout_sys_t
     float requested_volume; /**< Requested volume, negative if none */
     signed char requested_mute; /**< Requested mute, negative if none */
     enum device_acquisition_status device_status;
-    wchar_t *device_name; /**< device identifier to use, NULL if default */
-    bool default_device_changed;
+    atomic_uintptr_t device_name; /**< device identifier to use, 0 if default */
+    atomic_bool default_device_changed;
     vlc_sem_t init_passed;
     CRITICAL_SECTION lock;
     CONDITION_VARIABLE work;
@@ -597,13 +598,11 @@ vlc_MMNotificationClient_OnDefaultDeviceChange(IMMNotificationClient *this,
     if (role != eConsole)
         return S_OK;
 
-    EnterCriticalSection(&sys->lock);
-    if (sys->device_name == NULL)
+    if (atomic_load(&sys->device_name) == 0)
     {
-        sys->default_device_changed = true;
+        atomic_store(&sys->default_device_changed, true);
         aout_RestartRequest(aout, AOUT_RESTART_OUTPUT);
     }
-    LeaveCriticalSection(&sys->lock);
     msg_Dbg(aout, "default device changed: %ls", wid ? wid : L"(disabled)");
 
     return S_OK;
@@ -749,7 +748,7 @@ static int DeviceRequestLocked(audio_output_t *aout)
     aout_sys_t *sys = aout->sys;
     assert(sys->device_status == DEVICE_PENDING);
 
-    sys->default_device_changed = false;
+    atomic_store(&sys->default_device_changed, false);
 
     WakeConditionVariable(&sys->work);
     while (sys->device_status == DEVICE_PENDING)
@@ -774,8 +773,7 @@ static int DeviceSelectLocked(audio_output_t *aout, const char *id)
         new_string = true;
         selected_device_name = ToWide(id);
     }
-    wchar_t *previous = sys->device_name;
-    sys->device_name = selected_device_name;
+    wchar_t *previous = (wchar_t *)(void*)atomic_exchange(&sys->device_name, (uintptr_t)(void*)selected_device_name);
     free(previous);
     if (unlikely(selected_device_name == NULL && new_string))
         return -1;
@@ -891,7 +889,7 @@ static HRESULT MMSession(audio_output_t *aout, IMMDeviceEnumerator *it)
 
     /* Yes, it's perfectly valid to request the same device, see Start()
      * comments. */
-    wchar_t *current = sys->device_name;
+    wchar_t *current = (wchar_t*)(void*)atomic_load(&sys->device_name);
     if (current != NULL) /* Device selected explicitly */
     {
         hr = IMMDeviceEnumerator_GetDevice(it, current, &sys->dev);
@@ -914,7 +912,7 @@ static HRESULT MMSession(audio_output_t *aout, IMMDeviceEnumerator *it)
     {   /* Default device selected by policy and with stream routing.
          * "Do not use eMultimedia" says MSDN. */
         msg_Dbg(aout, "using default device");
-        sys->device_name = NULL;
+        atomic_store(&sys->device_name, 0);
         free(current);
         current = NULL;
         hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(it, eRender,
@@ -1210,7 +1208,7 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
     EnterMTA();
     EnterCriticalSection(&sys->lock);
 
-    if ((sys->default_device_changed && DeviceRestartLocked(aout) != 0)
+    if ((atomic_exchange(&sys->default_device_changed, false) && DeviceRestartLocked(aout) != 0)
       || sys->dev == NULL)
     {
         /* Error if the device restart failed or if a request previously
@@ -1332,7 +1330,7 @@ static int Open(vlc_object_t *obj)
     sys->gain = 1.f;
     sys->requested_volume = -1.f;
     sys->requested_mute = -1;
-    sys->default_device_changed = false;
+    atomic_init(&sys->default_device_changed, false);
 
     if (!var_CreateGetBool(aout, "volume-save"))
         VolumeSetLocked(aout, var_InheritFloat(aout, "mmdevice-volume"));
@@ -1357,7 +1355,7 @@ static int Open(vlc_object_t *obj)
     {
         free(saved_device_b);
     }
-    sys->device_name = audio_device;
+    atomic_init(&sys->device_name, (uintptr_t)(void*)audio_device);
     sys->device_status = DEVICE_PENDING;
 
     if (vlc_clone(&sys->thread, MMThread, aout, VLC_THREAD_PRIORITY_LOW))
@@ -1396,8 +1394,7 @@ static void Close(vlc_object_t *obj)
     aout_sys_t *sys = aout->sys;
 
     EnterCriticalSection(&sys->lock);
-    wchar_t *previous = sys->device_name;
-    sys->device_name = NULL;
+    wchar_t *previous = (wchar_t *)(void*)atomic_exchange(&sys->device_name, 0);
     sys->device_status = DEVICE_PENDING; /* break out of MMSession() loop */
     sys->it = NULL; /* break out of MMThread() loop */
     WakeConditionVariable(&sys->work);



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/cae669e4b066fbc97684113e87d12a5b034f8f23...8c4e5d611b8e48b0fb031c530a943800a85829ad

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




More information about the vlc-commits mailing list