vlc | branch: master | Thomas Guillem <tho...@gllm.fr> | Thu Sep 15 11:10:09 
2016 +0200| [11174e3ab56e24bb0a6ae4485e79eddda1b926a3] | committer: Thomas 
Guillem

mmdevice: update device if the previous one failed

s->owner.device need to be updated with the new dev after DeviceSelect is
called.

This fix a crash when trying to load 2 time the same failing device (Once you
got a AUDCLNT_E_DEVICE_INVALIDATED error, you shouldn't use this device again).

closes #17391

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=11174e3ab56e24bb0a6ae4485e79eddda1b926a3
---

 modules/audio_output/mmdevice.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/modules/audio_output/mmdevice.c b/modules/audio_output/mmdevice.c
index 28bb1e0..161fde8 100644
--- a/modules/audio_output/mmdevice.c
+++ b/modules/audio_output/mmdevice.c
@@ -733,7 +733,7 @@ static int DevicesEnum(audio_output_t *aout, 
IMMDeviceEnumerator *it)
     return n;
 }
 
-static int DeviceSelect(audio_output_t *aout, const char *id)
+static int DeviceSelectLocked(audio_output_t *aout, const char *id)
 {
     aout_sys_t *sys = aout->sys;
     wchar_t *device;
@@ -747,14 +747,12 @@ static int DeviceSelect(audio_output_t *aout, const char 
*id)
     else
         device = default_device;
 
-    EnterCriticalSection(&sys->lock);
     assert(sys->device == NULL);
     sys->device = device;
 
     WakeConditionVariable(&sys->work);
     while (sys->device != NULL)
         SleepConditionVariableCS(&sys->ready, &sys->lock, INFINITE);
-    LeaveCriticalSection(&sys->lock);
 
     if (sys->stream != NULL && sys->dev != NULL)
         /* Request restart of stream with the new device */
@@ -762,6 +760,14 @@ static int DeviceSelect(audio_output_t *aout, const char 
*id)
     return (sys->dev != NULL) ? 0 : -1;
 }
 
+static int DeviceSelect(audio_output_t *aout, const char *id)
+{
+    EnterCriticalSection(&aout->sys->lock);
+    int ret = DeviceSelectLocked(aout, id);
+    LeaveCriticalSection(&aout->sys->lock);
+    return ret;
+}
+
 /*** Initialization / deinitialization **/
 static wchar_t *var_InheritWide(vlc_object_t *obj, const char *name)
 {
@@ -1081,20 +1087,22 @@ static int Start(audio_output_t *aout, 
audio_sample_format_t *restrict fmt)
     if (unlikely(s == NULL))
         return -1;
 
-    s->owner.device = sys->dev;
     s->owner.activate = ActivateDevice;
 
     EnterMTA();
+    EnterCriticalSection(&sys->lock);
     for (;;)
     {
         HRESULT hr;
+        s->owner.device = sys->dev;
 
         /* TODO: Do not overload the "aout" configuration item. */
         sys->module = vlc_module_load(s, "aout stream", "$aout", false,
                                       aout_stream_Start, s, fmt, &hr);
-        if (hr != AUDCLNT_E_DEVICE_INVALIDATED || DeviceSelect(aout, NULL))
+        if (hr != AUDCLNT_E_DEVICE_INVALIDATED || DeviceSelectLocked(aout, 
NULL))
             break;
     }
+    LeaveCriticalSection(&sys->lock);
     LeaveMTA();
 
     if (sys->module == NULL)

_______________________________________________
vlc-commits mailing list
vlc-commits@videolan.org
https://mailman.videolan.org/listinfo/vlc-commits

Reply via email to