textoverlay: Use an external lock

Conflicts:

	ext/pango/gsttextoverlay.c
	ext/pango/gsttextoverlay.h
This commit is contained in:
Andre Moreira Magalhaes (andrunko) 2012-05-28 14:18:10 -03:00 committed by Sebastian Dröge
parent c66da2c74b
commit bac5fd4c6a
2 changed files with 55 additions and 49 deletions

View file

@ -293,10 +293,13 @@ gst_base_text_overlay_line_align_get_type (void)
return base_text_overlay_line_align_type;
}
#define GST_BASE_TEXT_OVERLAY_GET_COND(ov) (((GstBaseTextOverlay *)ov)->cond)
#define GST_BASE_TEXT_OVERLAY_WAIT(ov) (g_cond_wait (&GST_BASE_TEXT_OVERLAY_GET_COND (ov), GST_OBJECT_GET_LOCK (ov)))
#define GST_BASE_TEXT_OVERLAY_SIGNAL(ov) (g_cond_signal (&GST_BASE_TEXT_OVERLAY_GET_COND (ov)))
#define GST_BASE_TEXT_OVERLAY_BROADCAST(ov)(g_cond_broadcast (&GST_BASE_TEXT_OVERLAY_GET_COND (ov)))
#define GST_BASE_TEXT_OVERLAY_GET_LOCK(ov) (&GST_BASE_TEXT_OVERLAY (ov)->lock)
#define GST_BASE_TEXT_OVERLAY_GET_COND(ov) (&GST_BASE_TEXT_OVERLAY (ov)->cond)
#define GST_BASE_TEXT_OVERLAY_LOCK(ov) (g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_LOCK (ov)))
#define GST_BASE_TEXT_OVERLAY_UNLOCK(ov) (g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_LOCK (ov)))
#define GST_BASE_TEXT_OVERLAY_WAIT(ov) (g_cond_wait (GST_BASE_TEXT_OVERLAY_GET_COND (ov), GST_BASE_TEXT_OVERLAY_GET_LOCK (ov)))
#define GST_BASE_TEXT_OVERLAY_SIGNAL(ov) (g_cond_signal (GST_BASE_TEXT_OVERLAY_GET_COND (ov)))
#define GST_BASE_TEXT_OVERLAY_BROADCAST(ov)(g_cond_broadcast (GST_BASE_TEXT_OVERLAY_GET_COND (ov)))
static GstElementClass *parent_class = NULL;
static void gst_base_text_overlay_base_init (gpointer g_class);
@ -599,6 +602,7 @@ gst_base_text_overlay_finalize (GObject * object)
overlay->text_buffer = NULL;
}
g_mutex_clear (&overlay->lock);
g_cond_clear (&overlay->cond);
G_OBJECT_CLASS (parent_class)->finalize (object);
@ -689,6 +693,7 @@ gst_base_text_overlay_init (GstBaseTextOverlay * overlay,
overlay->text_buffer = NULL;
overlay->text_linked = FALSE;
g_mutex_init (&overlay->lock);
g_cond_init (&overlay->cond);
gst_segment_init (&overlay->segment, GST_FORMAT_TIME);
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
@ -771,11 +776,11 @@ gst_base_text_overlay_setcaps (GstBaseTextOverlay * overlay, GstCaps * caps)
ret = gst_pad_push_event (overlay->srcpad, gst_event_new_caps (caps));
if (ret) {
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
gst_base_text_overlay_update_wrap_mode (overlay);
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
}
return ret;
@ -794,7 +799,7 @@ gst_base_text_overlay_set_property (GObject * object, guint prop_id,
{
GstBaseTextOverlay *overlay = GST_BASE_TEXT_OVERLAY (object);
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
switch (prop_id) {
case PROP_TEXT:
g_free (overlay->default_text);
@ -918,7 +923,7 @@ gst_base_text_overlay_set_property (GObject * object, guint prop_id,
}
overlay->need_render = TRUE;
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
}
static void
@ -927,7 +932,7 @@ gst_base_text_overlay_get_property (GObject * object, guint prop_id,
{
GstBaseTextOverlay *overlay = GST_BASE_TEXT_OVERLAY (object);
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
switch (prop_id) {
case PROP_TEXT:
g_value_set_string (value, overlay->default_text);
@ -989,7 +994,7 @@ gst_base_text_overlay_get_property (GObject * object, guint prop_id,
}
overlay->need_render = TRUE;
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
}
static gboolean
@ -1050,11 +1055,11 @@ gst_base_text_overlay_src_event (GstPad * pad, GstObject * parent,
gst_pad_push_event (overlay->srcpad, gst_event_new_flush_start ());
/* Mark ourself as flushing, unblock chains */
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
overlay->video_flushing = TRUE;
overlay->text_flushing = TRUE;
gst_base_text_overlay_pop_text (overlay);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
/* Seek on each sink pad */
gst_event_ref (event);
@ -2173,11 +2178,11 @@ gst_base_text_overlay_text_event (GstPad * pad, GstObject * parent,
gst_event_parse_segment (event, &segment);
if (segment->format == GST_FORMAT_TIME) {
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
gst_segment_copy_into (segment, &overlay->text_segment);
GST_DEBUG_OBJECT (overlay, "TEXT SEGMENT now: %" GST_SEGMENT_FORMAT,
&overlay->text_segment);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
} else {
GST_ELEMENT_WARNING (overlay, STREAM, MUX, (NULL),
("received non-TIME newsegment event on text input"));
@ -2188,39 +2193,39 @@ gst_base_text_overlay_text_event (GstPad * pad, GstObject * parent,
/* wake up the video chain, it might be waiting for a text buffer or
* a text segment update */
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_BROADCAST (overlay);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
break;
}
case GST_EVENT_FLUSH_STOP:
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
GST_INFO_OBJECT (overlay, "text flush stop");
overlay->text_flushing = FALSE;
overlay->text_eos = FALSE;
gst_base_text_overlay_pop_text (overlay);
gst_segment_init (&overlay->text_segment, GST_FORMAT_TIME);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
gst_event_unref (event);
ret = TRUE;
break;
case GST_EVENT_FLUSH_START:
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
GST_INFO_OBJECT (overlay, "text flush start");
overlay->text_flushing = TRUE;
GST_BASE_TEXT_OVERLAY_BROADCAST (overlay);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
gst_event_unref (event);
ret = TRUE;
break;
case GST_EVENT_EOS:
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
overlay->text_eos = TRUE;
GST_INFO_OBJECT (overlay, "text EOS");
/* wake up the video chain, it might be waiting for a text buffer or
* a text segment update */
GST_BASE_TEXT_OVERLAY_BROADCAST (overlay);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
gst_event_unref (event);
ret = TRUE;
break;
@ -2275,27 +2280,27 @@ gst_base_text_overlay_video_event (GstPad * pad, GstObject * parent,
break;
}
case GST_EVENT_EOS:
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
GST_INFO_OBJECT (overlay, "video EOS");
overlay->video_eos = TRUE;
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
ret = gst_pad_event_default (pad, parent, event);
break;
case GST_EVENT_FLUSH_START:
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
GST_INFO_OBJECT (overlay, "video flush start");
overlay->video_flushing = TRUE;
GST_BASE_TEXT_OVERLAY_BROADCAST (overlay);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
ret = gst_pad_event_default (pad, parent, event);
break;
case GST_EVENT_FLUSH_STOP:
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
GST_INFO_OBJECT (overlay, "video flush stop");
overlay->video_flushing = FALSE;
overlay->video_eos = FALSE;
gst_segment_init (&overlay->segment, GST_FORMAT_TIME);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
ret = gst_pad_event_default (pad, parent, event);
break;
default:
@ -2366,17 +2371,17 @@ gst_base_text_overlay_text_chain (GstPad * pad, GstObject * parent,
overlay = GST_BASE_TEXT_OVERLAY (parent);
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
if (overlay->text_flushing) {
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
ret = GST_FLOW_FLUSHING;
GST_LOG_OBJECT (overlay, "text flushing");
goto beach;
}
if (overlay->text_eos) {
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
ret = GST_FLOW_EOS;
GST_LOG_OBJECT (overlay, "text EOS");
goto beach;
@ -2415,7 +2420,7 @@ gst_base_text_overlay_text_chain (GstPad * pad, GstObject * parent,
GST_BASE_TEXT_OVERLAY_WAIT (overlay);
GST_DEBUG ("Pad %s:%s resuming", GST_DEBUG_PAD_NAME (pad));
if (overlay->text_flushing) {
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
ret = GST_FLOW_FLUSHING;
goto beach;
}
@ -2432,7 +2437,7 @@ gst_base_text_overlay_text_chain (GstPad * pad, GstObject * parent,
GST_BASE_TEXT_OVERLAY_BROADCAST (overlay);
}
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
beach:
@ -2515,7 +2520,7 @@ gst_base_text_overlay_video_chain (GstPad * pad, GstObject * parent,
wait_for_text_buf:
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
if (overlay->video_flushing)
goto flushing;
@ -2524,7 +2529,7 @@ wait_for_text_buf:
goto have_eos;
if (overlay->silent) {
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
ret = gst_pad_push (overlay->srcpad, buffer);
/* Update position */
@ -2544,7 +2549,7 @@ wait_for_text_buf:
GST_LOG_OBJECT (overlay, "Text pad not linked, rendering default "
"text: '%s'", GST_STR_NULL (text));
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
if (text != NULL && *text != '\0') {
/* Render and push */
@ -2607,11 +2612,11 @@ wait_for_text_buf:
GST_LOG_OBJECT (overlay, "text buffer too old, popping");
pop_text = FALSE;
gst_base_text_overlay_pop_text (overlay);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
goto wait_for_text_buf;
} else if (valid_text_time && vid_running_time_end <= text_running_time) {
GST_LOG_OBJECT (overlay, "text in future, pushing video buf");
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
/* Push the video frame */
ret = gst_pad_push (overlay->srcpad, buffer);
} else {
@ -2660,7 +2665,7 @@ wait_for_text_buf:
gst_buffer_unmap (overlay->text_buffer, &map);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
ret = gst_base_text_overlay_push_frame (overlay, buffer);
if (valid_text_time && text_running_time_end <= vid_running_time_end) {
@ -2669,9 +2674,9 @@ wait_for_text_buf:
}
}
if (pop_text) {
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
gst_base_text_overlay_pop_text (overlay);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
}
} else {
gboolean wait_for_text_buf = TRUE;
@ -2709,10 +2714,10 @@ wait_for_text_buf:
GST_DEBUG_OBJECT (overlay, "no text buffer, need to wait for one");
GST_BASE_TEXT_OVERLAY_WAIT (overlay);
GST_DEBUG_OBJECT (overlay, "resuming");
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
goto wait_for_text_buf;
} else {
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
GST_LOG_OBJECT (overlay, "no need to wait for a text buffer");
ret = gst_pad_push (overlay->srcpad, buffer);
}
@ -2735,14 +2740,14 @@ missing_timestamp:
flushing:
{
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
GST_DEBUG_OBJECT (overlay, "flushing, discarding buffer");
gst_buffer_unref (buffer);
return GST_FLOW_FLUSHING;
}
have_eos:
{
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
GST_DEBUG_OBJECT (overlay, "eos, discarding buffer");
gst_buffer_unref (buffer);
return GST_FLOW_EOS;
@ -2764,13 +2769,13 @@ gst_base_text_overlay_change_state (GstElement * element,
switch (transition) {
case GST_STATE_CHANGE_PAUSED_TO_READY:
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
overlay->text_flushing = TRUE;
overlay->video_flushing = TRUE;
/* pop_text will broadcast on the GCond and thus also make the video
* chain exit if it's waiting for a text buffer */
gst_base_text_overlay_pop_text (overlay);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
break;
default:
break;
@ -2782,14 +2787,14 @@ gst_base_text_overlay_change_state (GstElement * element,
switch (transition) {
case GST_STATE_CHANGE_READY_TO_PAUSED:
GST_OBJECT_LOCK (overlay);
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
overlay->text_flushing = FALSE;
overlay->video_flushing = FALSE;
overlay->video_eos = FALSE;
overlay->text_eos = FALSE;
gst_segment_init (&overlay->segment, GST_FORMAT_TIME);
gst_segment_init (&overlay->text_segment, GST_FORMAT_TIME);
GST_OBJECT_UNLOCK (overlay);
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
break;
default:
break;

View file

@ -109,6 +109,7 @@ struct _GstBaseTextOverlay {
gboolean text_flushing;
gboolean text_eos;
GMutex lock;
GCond cond; /* to signal removal of a queued text
* buffer, arrival of a text buffer,
* a text segment update, or a change