mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 03:00:35 +00:00
gstaudiosrc/sink: Set audio ringbuffer thread priority
On Windows, the ringbuffer thread function must have the "Pro Audio" priority set, otherwise it sometimes doesn't get scheduled for 200-300ms, which will immediately cause an underrun unless you set a very high latency-time and buffer-time. This has no compile-time deps since it tries to load avrt.dll at runtime to set the thread priority.
This commit is contained in:
parent
41b7a65b81
commit
1733233060
4 changed files with 76 additions and 0 deletions
|
@ -56,6 +56,7 @@
|
|||
|
||||
#include <gst/audio/audio.h>
|
||||
#include "gstaudiosink.h"
|
||||
#include "gstaudioutilsprivate.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_audio_sink_debug);
|
||||
#define GST_CAT_DEFAULT gst_audio_sink_debug
|
||||
|
@ -216,6 +217,9 @@ audioringbuffer_thread_func (GstAudioRingBuffer * buf)
|
|||
if (writefunc == NULL)
|
||||
goto no_function;
|
||||
|
||||
if (G_UNLIKELY (!__gst_audio_set_thread_priority ()))
|
||||
GST_WARNING_OBJECT (sink, "failed to set thread priority");
|
||||
|
||||
message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
|
||||
GST_STREAM_STATUS_TYPE_ENTER, GST_ELEMENT_CAST (sink));
|
||||
g_value_init (&val, GST_TYPE_G_THREAD);
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
#include <gst/audio/audio.h>
|
||||
#include "gstaudiosrc.h"
|
||||
#include "gstaudioutilsprivate.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_audio_src_debug);
|
||||
#define GST_CAT_DEFAULT gst_audio_src_debug
|
||||
|
@ -195,6 +196,9 @@ audioringbuffer_thread_func (GstAudioRingBuffer * buf)
|
|||
if ((readfunc = csrc->read) == NULL)
|
||||
goto no_function;
|
||||
|
||||
if (G_UNLIKELY (!__gst_audio_set_thread_priority ()))
|
||||
GST_WARNING_OBJECT (src, "failed to set thread priority");
|
||||
|
||||
message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
|
||||
GST_STREAM_STATUS_TYPE_ENTER, GST_ELEMENT_CAST (src));
|
||||
g_value_init (&val, GST_TYPE_G_THREAD);
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <gst/audio/audio.h>
|
||||
#include "gstaudioutilsprivate.h"
|
||||
|
||||
|
@ -212,3 +216,64 @@ __gst_audio_encoded_audio_convert (GstAudioInfo * fmt,
|
|||
exit:
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* *INDENT-OFF* */
|
||||
static struct
|
||||
{
|
||||
HMODULE dll;
|
||||
gboolean tried_loading;
|
||||
|
||||
HANDLE (WINAPI * AvSetMmThreadCharacteristics) (LPCSTR, LPDWORD);
|
||||
BOOL (WINAPI * AvRevertMmThreadCharacteristics) (HANDLE);
|
||||
} _gst_audio_avrt_tbl = { 0 };
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
__gst_audio_init_thread_priority (void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_gst_audio_avrt_tbl.tried_loading)
|
||||
return _gst_audio_avrt_tbl.dll != NULL;
|
||||
|
||||
if (!_gst_audio_avrt_tbl.dll)
|
||||
_gst_audio_avrt_tbl.dll = LoadLibrary (TEXT ("avrt.dll"));
|
||||
|
||||
if (!_gst_audio_avrt_tbl.dll) {
|
||||
GST_WARNING ("Failed to set thread priority, can't find avrt.dll");
|
||||
_gst_audio_avrt_tbl.tried_loading = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_gst_audio_avrt_tbl.AvSetMmThreadCharacteristics =
|
||||
GetProcAddress (_gst_audio_avrt_tbl.dll, "AvSetMmThreadCharacteristicsA");
|
||||
_gst_audio_avrt_tbl.AvRevertMmThreadCharacteristics =
|
||||
GetProcAddress (_gst_audio_avrt_tbl.dll,
|
||||
"AvRevertMmThreadCharacteristics");
|
||||
|
||||
_gst_audio_avrt_tbl.tried_loading = TRUE;
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Increases the priority of the thread it's called from
|
||||
*/
|
||||
gpointer
|
||||
__gst_audio_set_thread_priority (void)
|
||||
{
|
||||
if (!__gst_audio_init_thread_priority ())
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD taskIndex = 0;
|
||||
/* This is only used from ringbuffer thread functions, so we don't need to
|
||||
* ever need to revert the thread priorities. */
|
||||
return _gst_audio_avrt_tbl.AvSetMmThreadCharacteristics (TEXT ("Pro Audio"),
|
||||
&taskIndex);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -42,6 +42,9 @@ gboolean __gst_audio_encoded_audio_convert (GstAudioInfo * fmt, gint64 bytes,
|
|||
gint64 src_value, GstFormat * dest_format,
|
||||
gint64 * dest_value);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gpointer __gst_audio_set_thread_priority (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue