From 62b6224e37e180498990ba7d79a09bf87889e520 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Tue, 6 Feb 2018 23:45:02 +0530 Subject: [PATCH] wasapi: Increase thread priority to reduce glitches 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 | 18 ++++++++++++++++++ sys/wasapi/gstwasapisink.h | 1 + sys/wasapi/gstwasapisrc.c | 18 ++++++++++++++++++ sys/wasapi/gstwasapisrc.h | 1 + 4 files changed, 38 insertions(+) diff --git a/sys/wasapi/gstwasapisink.c b/sys/wasapi/gstwasapisink.c index 0f0d299d48..8a9d3f89dc 100644 --- a/sys/wasapi/gstwasapisink.c +++ b/sys/wasapi/gstwasapisink.c @@ -40,6 +40,8 @@ #include "gstwasapisink.h" +#include + 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); } diff --git a/sys/wasapi/gstwasapisink.h b/sys/wasapi/gstwasapisink.h index 882f46e2c6..588d5807db 100644 --- a/sys/wasapi/gstwasapisink.h +++ b/sys/wasapi/gstwasapisink.h @@ -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; diff --git a/sys/wasapi/gstwasapisrc.c b/sys/wasapi/gstwasapisrc.c index dec93f8293..49f1d31b54 100644 --- a/sys/wasapi/gstwasapisrc.c +++ b/sys/wasapi/gstwasapisrc.c @@ -38,6 +38,8 @@ #include "gstwasapisrc.h" +#include + 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); } diff --git a/sys/wasapi/gstwasapisrc.h b/sys/wasapi/gstwasapisrc.h index fc89391a9b..530fb2b927 100644 --- a/sys/wasapi/gstwasapisrc.h +++ b/sys/wasapi/gstwasapisrc.h @@ -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;