mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-01 21:18:52 +00:00
assrender: Protect libass structures from concurrent access from multiple threads
Fixes bug #608751.
This commit is contained in:
parent
e9990ea6bb
commit
0dbe95a97d
2 changed files with 21 additions and 2 deletions
|
@ -234,6 +234,7 @@ gst_ass_render_init (GstAssRender * render, GstAssRenderClass * gclass)
|
|||
gst_segment_init (&render->video_segment, GST_FORMAT_TIME);
|
||||
gst_segment_init (&render->subtitle_segment, GST_FORMAT_TIME);
|
||||
|
||||
render->ass_mutex = g_mutex_new ();
|
||||
render->ass_library = ass_library_init ();
|
||||
#if defined(LIBASS_VERSION) && LIBASS_VERSION >= 0x00907000
|
||||
ass_set_message_cb (render->ass_library, _libass_message_cb, render);
|
||||
|
@ -274,6 +275,9 @@ gst_ass_render_finalize (GObject * object)
|
|||
ass_library_done (render->ass_library);
|
||||
}
|
||||
|
||||
if (render->ass_mutex)
|
||||
g_mutex_free (render->ass_mutex);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -289,7 +293,9 @@ gst_ass_render_set_property (GObject * object, guint prop_id,
|
|||
break;
|
||||
case PROP_EMBEDDEDFONTS:
|
||||
render->embeddedfonts = g_value_get_boolean (value);
|
||||
g_mutex_lock (render->ass_mutex);
|
||||
ass_set_extract_fonts (render->ass_library, render->embeddedfonts);
|
||||
g_mutex_unlock (render->ass_mutex);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
@ -348,9 +354,11 @@ gst_ass_render_change_state (GstElement * element, GstStateChange transition)
|
|||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
g_mutex_lock (render->ass_mutex);
|
||||
if (render->ass_track)
|
||||
ass_free_track (render->ass_track);
|
||||
render->ass_track = NULL;
|
||||
g_mutex_unlock (render->ass_mutex);
|
||||
render->track_init_ok = FALSE;
|
||||
render->renderer_init_ok = FALSE;
|
||||
break;
|
||||
|
@ -781,6 +789,7 @@ gst_ass_render_setcaps_video (GstPad * pad, GstCaps * caps)
|
|||
goto out;
|
||||
}
|
||||
|
||||
g_mutex_lock (render->ass_mutex);
|
||||
ass_set_frame_size (render->ass_renderer, render->width, render->height);
|
||||
|
||||
dar = (((gdouble) par_n) * ((gdouble) render->width))
|
||||
|
@ -803,6 +812,7 @@ gst_ass_render_setcaps_video (GstPad * pad, GstCaps * caps)
|
|||
#endif
|
||||
ass_set_margins (render->ass_renderer, 0, 0, 0, 0);
|
||||
ass_set_use_margins (render->ass_renderer, 0);
|
||||
g_mutex_unlock (render->ass_mutex);
|
||||
|
||||
render->renderer_init_ok = TRUE;
|
||||
|
||||
|
@ -832,6 +842,7 @@ gst_ass_render_setcaps_text (GstPad * pad, GstCaps * caps)
|
|||
|
||||
value = gst_structure_get_value (structure, "codec_data");
|
||||
|
||||
g_mutex_lock (render->ass_mutex);
|
||||
if (value != NULL) {
|
||||
priv = gst_value_get_buffer (value);
|
||||
g_return_val_if_fail (priv != NULL, FALSE);
|
||||
|
@ -857,6 +868,7 @@ gst_ass_render_setcaps_text (GstPad * pad, GstCaps * caps)
|
|||
|
||||
ret = TRUE;
|
||||
}
|
||||
g_mutex_unlock (render->ass_mutex);
|
||||
|
||||
gst_object_unref (render);
|
||||
|
||||
|
@ -881,7 +893,9 @@ gst_ass_render_process_text (GstAssRender * render, GstBuffer * buffer,
|
|||
"Processing subtitles with running time %" GST_TIME_FORMAT
|
||||
" and duration %" GST_TIME_FORMAT, GST_TIME_ARGS (running_time),
|
||||
GST_TIME_ARGS (duration));
|
||||
g_mutex_lock (render->ass_mutex);
|
||||
ass_process_chunk (render->ass_track, data, size, pts_start, pts_end);
|
||||
g_mutex_unlock (render->ass_mutex);
|
||||
gst_buffer_unref (buffer);
|
||||
}
|
||||
|
||||
|
@ -1008,6 +1022,7 @@ gst_ass_render_chain_video (GstPad * pad, GstBuffer * buffer)
|
|||
/* libass needs timestamps in ms */
|
||||
timestamp = running_time / GST_MSECOND;
|
||||
|
||||
g_mutex_lock (render->ass_mutex);
|
||||
#ifndef GST_DISABLE_GST_DEBUG
|
||||
/* only for testing right now. could possibly be used for optimizations? */
|
||||
step = ass_step_sub (render->ass_track, timestamp, 1);
|
||||
|
@ -1019,6 +1034,7 @@ gst_ass_render_chain_video (GstPad * pad, GstBuffer * buffer)
|
|||
/* not sure what the last parameter to this call is for (detect_change) */
|
||||
ass_image = ass_render_frame (render->ass_renderer, render->ass_track,
|
||||
timestamp, NULL);
|
||||
g_mutex_unlock (render->ass_mutex);
|
||||
|
||||
if (ass_image != NULL) {
|
||||
buffer = gst_buffer_make_writable (buffer);
|
||||
|
@ -1185,9 +1201,11 @@ gst_ass_render_handle_tags (GstAssRender * render, GstTagList * taglist)
|
|||
}
|
||||
|
||||
if (valid_mimetype || valid_extension) {
|
||||
g_mutex_lock (render->ass_mutex);
|
||||
ass_add_font (render->ass_library, (gchar *) filename,
|
||||
(gchar *) GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
||||
GST_DEBUG_OBJECT (render, "registered new font %s", filename);
|
||||
g_mutex_unlock (render->ass_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1307,17 +1325,17 @@ gst_ass_render_event_text (GstPad * pad, GstEvent * event)
|
|||
break;
|
||||
case GST_EVENT_FLUSH_START:
|
||||
GST_DEBUG_OBJECT (render, "begin flushing");
|
||||
g_mutex_lock (render->ass_mutex);
|
||||
if (render->ass_track) {
|
||||
GST_OBJECT_LOCK (render);
|
||||
/* delete any events on the ass_track */
|
||||
for (i = 0; i < render->ass_track->n_events; i++) {
|
||||
GST_DEBUG_OBJECT (render, "deleted event with eid %i", i);
|
||||
ass_free_event (render->ass_track, i);
|
||||
}
|
||||
render->ass_track->n_events = 0;
|
||||
GST_OBJECT_UNLOCK (render);
|
||||
GST_DEBUG_OBJECT (render, "done flushing");
|
||||
}
|
||||
g_mutex_unlock (render->ass_mutex);
|
||||
g_mutex_lock (render->subtitle_mutex);
|
||||
if (render->subtitle_pending)
|
||||
gst_buffer_unref (render->subtitle_pending);
|
||||
|
|
|
@ -68,6 +68,7 @@ struct _GstAssRender
|
|||
gboolean subtitle_flushing;
|
||||
GstSegment subtitle_segment;
|
||||
|
||||
GMutex *ass_mutex;
|
||||
ASS_Library *ass_library;
|
||||
ASS_Renderer *ass_renderer;
|
||||
ASS_Track *ass_track;
|
||||
|
|
Loading…
Reference in a new issue