wasapi: Set realtime thread priority at runtime
authorNirbheek Chauhan <nirbheek@centricular.com>
Wed, 14 Feb 2018 14:42:07 +0000 (20:12 +0530)
committerNirbheek Chauhan <nirbheek@centricular.com>
Mon, 26 Feb 2018 10:53:11 +0000 (16:23 +0530)
Use LoadLibrary() to set the thread characteristics at runtime so it
works automagically regardless of where or how the plugin was built.

sys/wasapi/gstwasapisink.c
sys/wasapi/gstwasapisrc.c
sys/wasapi/gstwasapiutil.c
sys/wasapi/gstwasapiutil.h

index a1cb31b..7ef0516 100644 (file)
@@ -501,14 +501,8 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
   gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SINK
       (self)->ringbuffer, self->positions);
 
-#if defined(_MSC_VER) || defined(GST_FORCE_WIN_AVRT)
   /* Increase the thread priority to reduce glitches */
-  {
-    DWORD taskIndex = 0;
-    self->thread_priority_handle =
-        AvSetMmThreadCharacteristics (TEXT ("Pro Audio"), &taskIndex);
-  }
-#endif
+  self->thread_priority_handle = gst_wasapi_util_set_thread_characteristics ();
 
   res = TRUE;
 
@@ -530,12 +524,11 @@ gst_wasapi_sink_unprepare (GstAudioSink * asink)
       !gst_wasapi_util_have_audioclient3 ())
     CoUninitialize ();
 
-#if defined(_MSC_VER) || defined(GST_FORCE_WIN_AVRT)
   if (self->thread_priority_handle != NULL) {
-    AvRevertMmThreadCharacteristics (self->thread_priority_handle);
+    gst_wasapi_util_revert_thread_characteristics
+        (self->thread_priority_handle);
     self->thread_priority_handle = NULL;
   }
-#endif
 
   if (self->client != NULL) {
     IAudioClient_Stop (self->client);
index aa555c9..93b166e 100644 (file)
@@ -448,14 +448,8 @@ gst_wasapi_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
   gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SRC
       (self)->ringbuffer, self->positions);
 
-#if defined(_MSC_VER) || defined(GST_FORCE_WIN_AVRT)
   /* Increase the thread priority to reduce glitches */
-  {
-    DWORD taskIndex = 0;
-    self->thread_priority_handle =
-        AvSetMmThreadCharacteristics (TEXT ("Pro Audio"), &taskIndex);
-  }
-#endif
+  self->thread_priority_handle = gst_wasapi_util_set_thread_characteristics ();
 
   res = TRUE;
 beach:
@@ -475,12 +469,11 @@ gst_wasapi_src_unprepare (GstAudioSrc * asrc)
   if (self->sharemode == AUDCLNT_SHAREMODE_EXCLUSIVE)
     CoUninitialize ();
 
-#if defined(_MSC_VER) || defined(GST_FORCE_WIN_AVRT)
   if (self->thread_priority_handle != NULL) {
-    AvRevertMmThreadCharacteristics (self->thread_priority_handle);
+    gst_wasapi_util_revert_thread_characteristics
+        (self->thread_priority_handle);
     self->thread_priority_handle = NULL;
   }
-#endif
 
   if (self->client != NULL) {
     IAudioClient_Stop (self->client);
index 7002d05..be005af 100644 (file)
@@ -104,6 +104,16 @@ static struct
 
 static int windows_major_version = 0;
 
+static struct
+{
+  HMODULE dll;
+  gboolean tried_loading;
+
+    HANDLE (WINAPI * AvSetMmThreadCharacteristics) (LPCSTR, LPDWORD);
+    BOOL (WINAPI * AvRevertMmThreadCharacteristics) (HANDLE);
+} gst_wasapi_avrt_tbl = {
+0};
+
 gboolean
 gst_wasapi_util_have_audioclient3 (void)
 {
@@ -938,3 +948,50 @@ gst_wasapi_util_initialize_audioclient3 (GstElement * self,
   *ret_devicep_frames = devicep_frames;
   return TRUE;
 }
+
+static gboolean
+gst_wasapi_util_init_thread_priority (void)
+{
+  if (gst_wasapi_avrt_tbl.tried_loading)
+    return gst_wasapi_avrt_tbl.dll != NULL;
+
+  if (!gst_wasapi_avrt_tbl.dll)
+    gst_wasapi_avrt_tbl.dll = LoadLibrary (TEXT ("avrt.dll"));
+
+  if (!gst_wasapi_avrt_tbl.dll) {
+    GST_WARNING ("Failed to set thread priority, can't find avrt.dll");
+    gst_wasapi_avrt_tbl.tried_loading = TRUE;
+    return FALSE;
+  }
+
+  gst_wasapi_avrt_tbl.AvSetMmThreadCharacteristics =
+      GetProcAddress (gst_wasapi_avrt_tbl.dll, "AvSetMmThreadCharacteristicsA");
+  gst_wasapi_avrt_tbl.AvRevertMmThreadCharacteristics =
+      GetProcAddress (gst_wasapi_avrt_tbl.dll,
+      "AvRevertMmThreadCharacteristics");
+
+  gst_wasapi_avrt_tbl.tried_loading = TRUE;
+
+  return TRUE;
+}
+
+HANDLE
+gst_wasapi_util_set_thread_characteristics (void)
+{
+  DWORD taskIndex = 0;
+
+  if (!gst_wasapi_util_init_thread_priority ())
+    return NULL;
+
+  return gst_wasapi_avrt_tbl.AvSetMmThreadCharacteristics (TEXT ("Pro Audio"),
+      &taskIndex);
+}
+
+void
+gst_wasapi_util_revert_thread_characteristics (HANDLE handle)
+{
+  if (!gst_wasapi_util_init_thread_priority ())
+    return;
+
+  gst_wasapi_avrt_tbl.AvRevertMmThreadCharacteristics (handle);
+}
index 67b39b0..251c224 100644 (file)
@@ -110,4 +110,8 @@ gboolean gst_wasapi_util_initialize_audioclient3 (GstElement * element,
     GstAudioRingBufferSpec * spec, IAudioClient3 * client,
     WAVEFORMATEX * format, gboolean low_latency, guint * ret_devicep_frames);
 
+HANDLE gst_wasapi_util_set_thread_characteristics (void);
+
+void gst_wasapi_util_revert_thread_characteristics (HANDLE handle);
+
 #endif /* __GST_WASAPI_UTIL_H__ */