diff --git a/ext/assrender/gstassrender.c b/ext/assrender/gstassrender.c index 9cfe9970d6..771be41d11 100644 --- a/ext/assrender/gstassrender.c +++ b/ext/assrender/gstassrender.c @@ -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); diff --git a/ext/assrender/gstassrender.h b/ext/assrender/gstassrender.h index 72fa7bb584..4b58e25888 100644 --- a/ext/assrender/gstassrender.h +++ b/ext/assrender/gstassrender.h @@ -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;