[vlc-commits] [Git][videolan/vlc][master] mmdevice: move MTA initialization to the worker thread

Steve Lhomme (@robUx4) gitlab at videolan.org
Sat Jun 3 10:07:42 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
2fa81b6f by Pierre Lamot at 2023-06-03T09:46:40+00:00
mmdevice: move MTA initialization to the worker thread

MTA was checked in the Open function. As this function is called from libvlc
thread, this implies that a user of libvlc should have its own thread in MTA
which may not be possible for various reasons.

* MuteSet, VolumeSet, Play, DeviceSelect, Close callback don't require MTA
* Flush, Pause and Start callbacks still require MTA, but as these functions are
  called from VLC internal threads this is a lesser issue

- - - - -


1 changed file:

- modules/audio_output/mmdevice.c


Changes:

=====================================
modules/audio_output/mmdevice.c
=====================================
@@ -75,6 +75,12 @@ static void LeaveMTA(void)
 static wchar_t default_device[1] = L"";
 static char default_device_b[1] = "";
 
+enum initialisation_status_t {
+    INITIALISATION_PENDING,
+    INITIALISATION_FAILED,
+    INITIALISATION_SUCCEEDED,
+};
+
 typedef struct
 {
     struct aout_stream_owner *stream; /**< Underlying audio output stream */
@@ -96,6 +102,7 @@ typedef struct
     wchar_t *acquired_device; /**< Acquired device identifier, NULL if none */
     bool request_device_restart;
     HANDLE work_event;
+    enum initialisation_status_t initialisation_status;
     vlc_mutex_t lock;
     vlc_cond_t ready;
     vlc_thread_t thread; /**< Thread for audio session control */
@@ -924,6 +931,7 @@ static HRESULT MMSession(audio_output_t *aout, IMMDeviceEnumerator *it)
     }
 
     sys->requested_device = NULL;
+    sys->initialisation_status = INITIALISATION_SUCCEEDED;
     vlc_cond_signal(&sys->ready);
 
     if (SUCCEEDED(hr))
@@ -1095,14 +1103,29 @@ static void *MMThread(void *data)
 {
     audio_output_t *aout = data;
     aout_sys_t *sys = aout->sys;
-    IMMDeviceEnumerator *it = sys->it;
 
     vlc_thread_set_name("vlc-mmdevice");
 
-    EnterMTA();
+    /* Initialize MMDevice API */
+    if (TryEnterMTA(aout))
+        goto error;
+
+    void *pv;
+    HRESULT hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
+                                  &IID_IMMDeviceEnumerator, &pv);
+    if (FAILED(hr))
+    {
+        msg_Dbg(aout, "cannot create device enumerator (error 0x%lX)", hr);
+        LeaveMTA();
+        goto error;
+    }
+
+    IMMDeviceEnumerator *it = pv;
+    sys->it = it;
+
     IMMDeviceEnumerator_RegisterEndpointNotificationCallback(it,
                                                           &sys->device_events);
-    HRESULT hr = DevicesEnum(it, MMThread_DevicesEnum_Added, aout);
+    hr = DevicesEnum(it, MMThread_DevicesEnum_Added, aout);
     if (FAILED(hr))
         msg_Warn(aout, "cannot enumerate audio endpoints (error 0x%lX)", hr);
 
@@ -1124,6 +1147,13 @@ static void *MMThread(void *data)
     IMMDeviceEnumerator_Release(it);
     LeaveMTA();
     return NULL;
+
+error:
+    vlc_mutex_lock(&sys->lock);
+    sys->initialisation_status = INITIALISATION_FAILED;
+    vlc_cond_signal(&sys->ready);
+    vlc_mutex_unlock(&sys->lock);
+    return NULL;
 }
 
 /**
@@ -1338,33 +1368,20 @@ static int Open(vlc_object_t *obj)
         sys->requested_device = default_device;
     }
 
-    /* Initialize MMDevice API */
-    if (TryEnterMTA(aout))
-        goto error;
-
-    void *pv;
-    HRESULT hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
-                                  &IID_IMMDeviceEnumerator, &pv);
-    if (FAILED(hr))
-    {
-        LeaveMTA();
-        msg_Dbg(aout, "cannot create device enumerator (error 0x%lX)", hr);
-        goto error;
-    }
-    sys->it = pv;
-
+    sys->initialisation_status = INITIALISATION_PENDING;
     if (vlc_clone(&sys->thread, MMThread, aout))
-    {
-        IMMDeviceEnumerator_Release(sys->it);
-        LeaveMTA();
         goto error;
-    }
 
     vlc_mutex_lock(&sys->lock);
-    while (sys->requested_device != NULL)
+    while (sys->initialisation_status == INITIALISATION_PENDING)
         vlc_cond_wait(&sys->ready, &sys->lock);
     vlc_mutex_unlock(&sys->lock);
-    LeaveMTA(); /* Leave MTA after thread has entered MTA */
+
+    if (sys->initialisation_status == INITIALISATION_FAILED)
+    {
+        vlc_join(sys->thread, NULL);
+        goto error;
+    }
 
     aout->start = Start;
     aout->stop = Stop;



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/2fa81b6f15f268e1aaeaf55d93f5bb628714d8cb

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/2fa81b6f15f268e1aaeaf55d93f5bb628714d8cb
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