mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
audioutilsprivate: restore thread priority before ending
The priority of the thread that executes audioringbuffer_thread_func is incremented on Windows by the usage of the AvSetMmThreadCharacteristics API. This change has to be restored, as described on the documentation of the API (https://docs.microsoft.com/en-us/windows/win32/api/avrt/nf-avrt-avsetmmthreadcharacteristicsw#remarks), with a call to the AvRevertMmThreadCharacteristics. If this is not done, a handle will be leaked. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/760>
This commit is contained in:
parent
f0a9907097
commit
aa4bea913b
4 changed files with 53 additions and 8 deletions
|
@ -205,6 +205,7 @@ audioringbuffer_thread_func (GstAudioRingBuffer * buf)
|
|||
WriteFunc writefunc;
|
||||
GstMessage *message;
|
||||
GValue val = { 0 };
|
||||
gpointer handle;
|
||||
|
||||
sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf));
|
||||
csink = GST_AUDIO_SINK_GET_CLASS (sink);
|
||||
|
@ -220,7 +221,7 @@ audioringbuffer_thread_func (GstAudioRingBuffer * buf)
|
|||
if (writefunc == NULL)
|
||||
goto no_function;
|
||||
|
||||
if (G_UNLIKELY (!__gst_audio_set_thread_priority ()))
|
||||
if (G_UNLIKELY (!__gst_audio_set_thread_priority (&handle)))
|
||||
GST_WARNING_OBJECT (sink, "failed to set thread priority");
|
||||
|
||||
message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
|
||||
|
@ -306,6 +307,9 @@ stop_running:
|
|||
g_value_unset (&val);
|
||||
GST_DEBUG_OBJECT (sink, "posting LEAVE stream status");
|
||||
gst_element_post_message (GST_ELEMENT_CAST (sink), message);
|
||||
|
||||
if (G_UNLIKELY (!__gst_audio_restore_thread_priority (handle)))
|
||||
GST_WARNING_OBJECT (sink, "failed to restore thread priority");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,6 +187,7 @@ audioringbuffer_thread_func (GstAudioRingBuffer * buf)
|
|||
ReadFunc readfunc;
|
||||
GstMessage *message;
|
||||
GValue val = { 0 };
|
||||
gpointer handle;
|
||||
|
||||
src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
|
||||
csrc = GST_AUDIO_SRC_GET_CLASS (src);
|
||||
|
@ -196,7 +197,7 @@ audioringbuffer_thread_func (GstAudioRingBuffer * buf)
|
|||
if ((readfunc = csrc->read) == NULL)
|
||||
goto no_function;
|
||||
|
||||
if (G_UNLIKELY (!__gst_audio_set_thread_priority ()))
|
||||
if (G_UNLIKELY (!__gst_audio_set_thread_priority (&handle)))
|
||||
GST_WARNING_OBJECT (src, "failed to set thread priority");
|
||||
|
||||
message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
|
||||
|
@ -281,6 +282,9 @@ stop_running:
|
|||
g_value_unset (&val);
|
||||
GST_DEBUG_OBJECT (src, "posting LEAVE stream status");
|
||||
gst_element_post_message (GST_ELEMENT_CAST (src), message);
|
||||
|
||||
if (G_UNLIKELY (!__gst_audio_restore_thread_priority (handle)))
|
||||
GST_WARNING_OBJECT (src, "failed to restore thread priority");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -281,20 +281,54 @@ __gst_audio_init_thread_priority (void)
|
|||
* Increases the priority of the thread it's called from
|
||||
*/
|
||||
gboolean
|
||||
__gst_audio_set_thread_priority (void)
|
||||
__gst_audio_set_thread_priority (gpointer * handle)
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
DWORD taskIndex = 0;
|
||||
#endif
|
||||
|
||||
g_return_val_if_fail (handle != NULL, FALSE);
|
||||
|
||||
*handle = NULL;
|
||||
|
||||
if (!__gst_audio_init_thread_priority ())
|
||||
return FALSE;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
/* 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) != 0;
|
||||
/* This is only used from ringbuffer thread functions */
|
||||
*handle = (gpointer)
|
||||
_gst_audio_avrt_tbl.AvSetMmThreadCharacteristics (TEXT ("Pro Audio"),
|
||||
&taskIndex);
|
||||
if (*handle == 0) {
|
||||
gchar *errorMsg = g_win32_error_message (GetLastError ());
|
||||
|
||||
GST_WARNING
|
||||
("Failed to set thread priority, AvSetMmThreadCharacteristics returned: %s",
|
||||
errorMsg);
|
||||
g_free (errorMsg);
|
||||
}
|
||||
|
||||
return *handle != 0;
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Restores the priority of the thread that was increased
|
||||
* with __gst_audio_set_thread_priority.
|
||||
* This function must be called from the same thread that called the
|
||||
* __gst_audio_set_thread_priority function.
|
||||
* See https://docs.microsoft.com/en-us/windows/win32/api/avrt/nf-avrt-avsetmmthreadcharacteristicsw#remarks
|
||||
*/
|
||||
gboolean
|
||||
__gst_audio_restore_thread_priority (gpointer handle)
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
if (!handle)
|
||||
return FALSE;
|
||||
|
||||
return _gst_audio_avrt_tbl.AvRevertMmThreadCharacteristics ((HANDLE) handle);
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
|
|
|
@ -43,7 +43,10 @@ gboolean __gst_audio_encoded_audio_convert (GstAudioInfo * fmt, gint64 bytes,
|
|||
gint64 * dest_value);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean __gst_audio_set_thread_priority (void);
|
||||
gboolean __gst_audio_set_thread_priority (gpointer * handle);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean __gst_audio_restore_thread_priority (gpointer handle);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
Loading…
Reference in a new issue