diff options
author | David Schleef <ds@schleef.org> | 2003-08-26 06:56:58 +0000 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2003-08-26 06:56:58 +0000 |
commit | 6310d277da5924e10c5172a449b033a608048bdd (patch) | |
tree | 4a3f3870911b61d0162963ac62889512365a04cb | |
parent | 295639cb4dfbce64fce288a14624573056bf77fc (diff) | |
download | gstreamer-plugins-base-6310d277da5924e10c5172a449b033a608048bdd.tar.gz |
rewrite state machine in _loop() function to handle buffer durations
Original commit message from CVS:
rewrite state machine in _loop() function to handle buffer durations
-rw-r--r-- | ext/pango/gsttextoverlay.c | 103 | ||||
-rw-r--r-- | ext/pango/gsttextoverlay.h | 6 |
2 files changed, 80 insertions, 29 deletions
diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index e17078e4f..304dcdd2c 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -371,13 +371,17 @@ gst_textoverlay_video_chain(GstPad *pad, GstBuffer *buf) gst_pad_push(overlay->srcpad, buf); } +#define PAST_END(buffer, time) \ + (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE && \ + GST_BUFFER_DURATION (buffer) != GST_CLOCK_TIME_NONE && \ + GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer) \ + < (time)) static void gst_textoverlay_loop(GstElement *element) { GstTextOverlay *overlay; GstBuffer *video_frame; - GstBuffer *new_text; guint64 now; g_return_if_fail(element != NULL); @@ -386,32 +390,74 @@ gst_textoverlay_loop(GstElement *element) video_frame = gst_pad_pull(overlay->video_sinkpad); now = GST_BUFFER_TIMESTAMP(video_frame); - if (now >= overlay->next_known_text_change) { - GST_DEBUG ( "rendering '%s'", overlay->next_known_text->str); + + /* + * This state machine has a bug that can't be resolved easily. + * (Needs a more complicated state machine.) Basically, if the + * text that came from a buffer from the sink pad is being + * displayed, and the default text is changed by set_parameter, + * we'll incorrectly display the default text. + * + * Otherwise, this is a pretty decent state machine that handles + * buffer timestamps and durations correctly. (I think) + */ + + while (overlay->next_buffer == NULL){ + GST_DEBUG("attempting to pull a buffer"); + + /* read all text buffers until we get one "in the future" */ + if(!GST_PAD_IS_USABLE(overlay->text_sinkpad)){ + break; + } + overlay->next_buffer = gst_pad_pull(overlay->text_sinkpad); + if (!overlay->next_buffer) + break; + + if (PAST_END(overlay->next_buffer, now)){ + gst_buffer_unref(overlay->next_buffer); + overlay->next_buffer = NULL; + } + } + + if (overlay->next_buffer && + (GST_BUFFER_TIMESTAMP(overlay->next_buffer) <= now || + GST_BUFFER_TIMESTAMP(overlay->next_buffer) == GST_CLOCK_TIME_NONE)){ + GST_DEBUG("using new buffer"); + + if (overlay->current_buffer){ + gst_buffer_unref (overlay->current_buffer); + } + overlay->current_buffer = overlay->next_buffer; + overlay->next_buffer = NULL; + + GST_DEBUG ( "rendering '%*s'", + GST_BUFFER_SIZE(overlay->current_buffer), + GST_BUFFER_DATA(overlay->current_buffer)); pango_layout_set_markup(overlay->layout, - overlay->next_known_text->str, - overlay->next_known_text->len); + GST_BUFFER_DATA(overlay->current_buffer), + GST_BUFFER_SIZE(overlay->current_buffer)); render_text(overlay); - overlay->next_known_text_change = 0; + overlay->need_render = FALSE; } - if (overlay->next_known_text_change == 0) { - /* read all text buffers until we get one "in the future" */ - while (1) { - new_text = gst_pad_pull(overlay->text_sinkpad); - if (!new_text) - break; - overlay->next_known_text_change = - GST_BUFFER_TIMESTAMP(new_text); - overlay->next_known_text = g_string_truncate - (overlay->next_known_text, 0); - overlay->next_known_text = g_string_append_len - (overlay->next_known_text, - (gchar *) GST_BUFFER_DATA(new_text), - GST_BUFFER_SIZE(new_text)); - gst_buffer_unref(new_text); - break; - } + + if (overlay->current_buffer && PAST_END(overlay->current_buffer, now)){ + GST_DEBUG("dropping old buffer"); + + gst_buffer_unref(overlay->current_buffer); + overlay->current_buffer = NULL; + + overlay->need_render = TRUE; + } + + if(overlay->need_render){ + GST_DEBUG ( "rendering '%s'", overlay->default_text); + pango_layout_set_markup(overlay->layout, + overlay->default_text, strlen(overlay->default_text)); + render_text(overlay); + + overlay->need_render = FALSE; } + gst_textoverlay_video_chain(overlay->srcpad, video_frame); } @@ -483,8 +529,8 @@ gst_textoverlay_init(GstTextOverlay *overlay) overlay->valign = GST_TEXT_OVERLAY_VALIGN_BASELINE; overlay->x0 = overlay->y0 = 0; - overlay->next_known_text = g_string_new(NULL); - overlay->next_known_text_change = 0; + overlay->default_text = g_strdup(""); + overlay->need_render = TRUE; gst_element_set_loop_function(GST_ELEMENT(overlay), gst_textoverlay_loop); } @@ -503,8 +549,11 @@ gst_textoverlay_set_property(GObject *object, guint prop_id, const GValue *value { case ARG_TEXT: - pango_layout_set_markup(overlay->layout, g_value_get_string(value), -1); - render_text(overlay); + if(overlay->default_text){ + g_free(overlay->default_text); + } + overlay->default_text = g_strdup(g_value_get_string(value)); + overlay->need_render = TRUE; break; case ARG_VALIGN: diff --git a/ext/pango/gsttextoverlay.h b/ext/pango/gsttextoverlay.h index ea8f5bf7e..b039acac3 100644 --- a/ext/pango/gsttextoverlay.h +++ b/ext/pango/gsttextoverlay.h @@ -54,8 +54,10 @@ struct _GstTextOverlay { GstTextOverlayHAlign halign; gint x0; gint y0; - guint64 next_known_text_change; - GString *next_known_text; + GstBuffer *current_buffer; + GstBuffer *next_buffer; + gchar *default_text; + gboolean need_render; }; struct _GstTextOverlayClass { |