mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 01:30:38 +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;
|
WriteFunc writefunc;
|
||||||
GstMessage *message;
|
GstMessage *message;
|
||||||
GValue val = { 0 };
|
GValue val = { 0 };
|
||||||
|
gpointer handle;
|
||||||
|
|
||||||
sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf));
|
sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf));
|
||||||
csink = GST_AUDIO_SINK_GET_CLASS (sink);
|
csink = GST_AUDIO_SINK_GET_CLASS (sink);
|
||||||
|
@ -220,7 +221,7 @@ audioringbuffer_thread_func (GstAudioRingBuffer * buf)
|
||||||
if (writefunc == NULL)
|
if (writefunc == NULL)
|
||||||
goto no_function;
|
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");
|
GST_WARNING_OBJECT (sink, "failed to set thread priority");
|
||||||
|
|
||||||
message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
|
message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
|
||||||
|
@ -306,6 +307,9 @@ stop_running:
|
||||||
g_value_unset (&val);
|
g_value_unset (&val);
|
||||||
GST_DEBUG_OBJECT (sink, "posting LEAVE stream status");
|
GST_DEBUG_OBJECT (sink, "posting LEAVE stream status");
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (sink), message);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,6 +187,7 @@ audioringbuffer_thread_func (GstAudioRingBuffer * buf)
|
||||||
ReadFunc readfunc;
|
ReadFunc readfunc;
|
||||||
GstMessage *message;
|
GstMessage *message;
|
||||||
GValue val = { 0 };
|
GValue val = { 0 };
|
||||||
|
gpointer handle;
|
||||||
|
|
||||||
src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
|
src = GST_AUDIO_SRC (GST_OBJECT_PARENT (buf));
|
||||||
csrc = GST_AUDIO_SRC_GET_CLASS (src);
|
csrc = GST_AUDIO_SRC_GET_CLASS (src);
|
||||||
|
@ -196,7 +197,7 @@ audioringbuffer_thread_func (GstAudioRingBuffer * buf)
|
||||||
if ((readfunc = csrc->read) == NULL)
|
if ((readfunc = csrc->read) == NULL)
|
||||||
goto no_function;
|
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");
|
GST_WARNING_OBJECT (src, "failed to set thread priority");
|
||||||
|
|
||||||
message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
|
message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
|
||||||
|
@ -281,6 +282,9 @@ stop_running:
|
||||||
g_value_unset (&val);
|
g_value_unset (&val);
|
||||||
GST_DEBUG_OBJECT (src, "posting LEAVE stream status");
|
GST_DEBUG_OBJECT (src, "posting LEAVE stream status");
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (src), message);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,20 +281,54 @@ __gst_audio_init_thread_priority (void)
|
||||||
* Increases the priority of the thread it's called from
|
* Increases the priority of the thread it's called from
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
__gst_audio_set_thread_priority (void)
|
__gst_audio_set_thread_priority (gpointer * handle)
|
||||||
{
|
{
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
DWORD taskIndex = 0;
|
DWORD taskIndex = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
g_return_val_if_fail (handle != NULL, FALSE);
|
||||||
|
|
||||||
|
*handle = NULL;
|
||||||
|
|
||||||
if (!__gst_audio_init_thread_priority ())
|
if (!__gst_audio_init_thread_priority ())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
/* This is only used from ringbuffer thread functions, so we don't need to
|
/* This is only used from ringbuffer thread functions */
|
||||||
* ever need to revert the thread priorities. */
|
*handle = (gpointer)
|
||||||
return _gst_audio_avrt_tbl.AvSetMmThreadCharacteristics (TEXT ("Pro Audio"),
|
_gst_audio_avrt_tbl.AvSetMmThreadCharacteristics (TEXT ("Pro Audio"),
|
||||||
&taskIndex) != 0;
|
&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
|
#else
|
||||||
return TRUE;
|
return TRUE;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -43,7 +43,10 @@ gboolean __gst_audio_encoded_audio_convert (GstAudioInfo * fmt, gint64 bytes,
|
||||||
gint64 * dest_value);
|
gint64 * dest_value);
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue