wasapi: Set realtime thread priority at runtime

Use LoadLibrary() to set the thread characteristics at runtime so it
works automagically regardless of where or how the plugin was built.
This commit is contained in:
Nirbheek Chauhan 2018-02-14 20:12:07 +05:30
parent 0cb11c15ed
commit f7d0ce2477
4 changed files with 67 additions and 20 deletions

View 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);

View 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);

View 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);
}

View 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__ */