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

Steve Lhomme (@robUx4) gitlab at videolan.org
Wed Apr 29 10:34:30 UTC 2026



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
26741cab by Steve Lhomme at 2026-04-29T09:47:42+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().

- - - - -
27ce8da8 by Steve Lhomme at 2026-04-29T09:47:42+00:00
mmdevice: make device_name an atomic wchar_t *

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

- - - - -
2e7b6867 by Steve Lhomme at 2026-04-29T09:47:42+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.

- - - - -


1 changed file:

- modules/audio_output/mmdevice.c


Changes:

=====================================
modules/audio_output/mmdevice.c
=====================================
@@ -99,8 +99,8 @@ typedef struct
     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(wchar_t *) device_name; /**< device identifier to use, NULL if default */
+    atomic_bool default_device_changed;
     HANDLE work_event;
     vlc_sem_t init_passed;
     vlc_mutex_t lock;
@@ -578,13 +578,11 @@ vlc_MMNotificationClient_OnDefaultDeviceChange(IMMNotificationClient *this,
     if (role != eConsole)
         return S_OK;
 
-    vlc_mutex_lock(&sys->lock);
-    if (sys->device_name == NULL)
+    if (atomic_load(&sys->device_name) == NULL)
     {
-        sys->default_device_changed = true;
+        atomic_store(&sys->default_device_changed, true);
         aout_RestartRequest(aout, true);
     }
-    vlc_mutex_unlock(&sys->lock);
     msg_Dbg(aout, "default device changed: %ls", wid ? wid : L"(disabled)");
 
     return S_OK;
@@ -730,7 +728,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);
 
     SetEvent(sys->work_event);
     while (sys->device_status == DEVICE_PENDING)
@@ -755,8 +753,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 = atomic_exchange(&sys->device_name, selected_device_name);
     free(previous);
     if (unlikely(selected_device_name == NULL && new_string))
         return -1;
@@ -870,8 +867,7 @@ static void MMSessionMainloop(audio_output_t *aout, ISimpleAudioVolume *volume)
             if (unlikely(hr == AUDCLNT_E_DEVICE_INVALIDATED ||
                          hr == AUDCLNT_E_RESOURCES_INVALIDATED))
             {
-                wchar_t *previous = sys->device_name;
-                sys->device_name = NULL;
+                wchar_t *previous = atomic_exchange(&sys->device_name, NULL);
                 free(previous);
                 sys->device_status = DEVICE_PENDING;
                 /* The restart of the stream will be requested asynchronously */
@@ -907,7 +903,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 = atomic_load(&sys->device_name);
     if (current != NULL) /* Device selected explicitly */
     {
         hr = IMMDeviceEnumerator_GetDevice(it, current, &sys->dev);
@@ -930,7 +926,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, NULL);
         free(current);
         current = NULL;
         hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(it, eRender,
@@ -1223,7 +1219,7 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
     EnterMTA();
     vlc_mutex_lock(&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
@@ -1352,7 +1348,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"));
@@ -1380,7 +1376,7 @@ static int Open(vlc_object_t *obj)
     {
         free(saved_device_b);
     }
-    sys->device_name = audio_device;
+    atomic_init(&sys->device_name, audio_device);
     sys->device_status = DEVICE_PENDING;
 
     if (vlc_clone(&sys->thread, MMThread, aout))
@@ -1419,8 +1415,7 @@ static void Close(vlc_object_t *obj)
     aout_sys_t *sys = aout->sys;
 
     vlc_mutex_lock(&sys->lock);
-    wchar_t *previous = sys->device_name;
-    sys->device_name = NULL;
+    wchar_t *previous = atomic_exchange(&sys->device_name, NULL);
     sys->device_status = DEVICE_PENDING; /* break out of MMSession() loop */
     sys->it = NULL; /* break out of MMThread() loop */
     vlc_mutex_unlock(&sys->lock);



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/7fd34a89163f5240b9c083c5a4fc75e96c454027...2e7b68670413a7f3ea4127590e3629b63b6e2080

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/7fd34a89163f5240b9c083c5a4fc75e96c454027...2e7b68670413a7f3ea4127590e3629b63b6e2080
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list