wasapi: Increase thread priority to reduce glitches
authorNirbheek Chauhan <nirbheek@centricular.com>
Tue, 6 Feb 2018 18:15:02 +0000 (23:45 +0530)
committerNirbheek Chauhan <nirbheek@centricular.com>
Thu, 8 Feb 2018 06:34:20 +0000 (12:04 +0530)
This is particularly important when running in exclusive mode because
any delays will immediately cause glitching.

The MinGW version in Cerbero is too old, so we can only enable this when
building with MSVC or when people build GStreamer for MSYS2 or other
MinGW-based distributions.

To force-enable this code when building with MinGW, build with
CFLAGS="-DGST_FORCE_WIN_AVRT -lavrt".

https://bugzilla.gnome.org/show_bug.cgi?id=793289

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

index 0f0d299..8a9d3f8 100644 (file)
@@ -40,6 +40,8 @@
 
 #include "gstwasapisink.h"
 
+#include <avrt.h>
+
 GST_DEBUG_CATEGORY_STATIC (gst_wasapi_sink_debug);
 #define GST_CAT_DEFAULT gst_wasapi_sink_debug
 
@@ -472,6 +474,15 @@ 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
+
   res = TRUE;
 
 beach:
@@ -489,6 +500,13 @@ gst_wasapi_sink_unprepare (GstAudioSink * asink)
   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);
+    self->thread_priority_handle = NULL;
+  }
+#endif
+
   if (self->client != NULL) {
     IAudioClient_Stop (self->client);
   }
index 882f46e..588d580 100644 (file)
@@ -44,6 +44,7 @@ struct _GstWasapiSink
   IAudioClient *client;
   IAudioRenderClient *render_client;
   HANDLE event_handle;
+  HANDLE thread_priority_handle;
 
   /* Actual size of the allocated buffer */
   guint buffer_frame_count;
index dec93f8..49f1d31 100644 (file)
@@ -38,6 +38,8 @@
 
 #include "gstwasapisrc.h"
 
+#include <avrt.h>
+
 GST_DEBUG_CATEGORY_STATIC (gst_wasapi_src_debug);
 #define GST_CAT_DEFAULT gst_wasapi_src_debug
 
@@ -477,6 +479,15 @@ 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
+
   res = TRUE;
 
 beach:
@@ -499,6 +510,13 @@ 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);
+    self->thread_priority_handle = NULL;
+  }
+#endif
+
   if (self->client != NULL) {
     IAudioClient_Stop (self->client);
   }
index fc89391..530fb2b 100644 (file)
@@ -46,6 +46,7 @@ struct _GstWasapiSrc
   guint64 client_clock_freq;
   IAudioCaptureClient *capture_client;
   HANDLE event_handle;
+  HANDLE thread_priority_handle;
 
   /* Actual size of the allocated buffer */
   guint buffer_frame_count;