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
This commit is contained in:
David Schleef 2003-08-26 06:56:58 +00:00
parent 295639cb4d
commit 6310d277da
2 changed files with 80 additions and 29 deletions

View file

@ -371,13 +371,17 @@ gst_textoverlay_video_chain(GstPad *pad, GstBuffer *buf)
gst_pad_push(overlay->srcpad, 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 static void
gst_textoverlay_loop(GstElement *element) gst_textoverlay_loop(GstElement *element)
{ {
GstTextOverlay *overlay; GstTextOverlay *overlay;
GstBuffer *video_frame; GstBuffer *video_frame;
GstBuffer *new_text;
guint64 now; guint64 now;
g_return_if_fail(element != NULL); g_return_if_fail(element != NULL);
@ -386,32 +390,74 @@ gst_textoverlay_loop(GstElement *element)
video_frame = gst_pad_pull(overlay->video_sinkpad); video_frame = gst_pad_pull(overlay->video_sinkpad);
now = GST_BUFFER_TIMESTAMP(video_frame); 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, pango_layout_set_markup(overlay->layout,
overlay->next_known_text->str, GST_BUFFER_DATA(overlay->current_buffer),
overlay->next_known_text->len); GST_BUFFER_SIZE(overlay->current_buffer));
render_text(overlay); 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" */ if (overlay->current_buffer && PAST_END(overlay->current_buffer, now)){
while (1) { GST_DEBUG("dropping old buffer");
new_text = gst_pad_pull(overlay->text_sinkpad);
if (!new_text) gst_buffer_unref(overlay->current_buffer);
break; overlay->current_buffer = NULL;
overlay->next_known_text_change =
GST_BUFFER_TIMESTAMP(new_text); overlay->need_render = TRUE;
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->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); 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->valign = GST_TEXT_OVERLAY_VALIGN_BASELINE;
overlay->x0 = overlay->y0 = 0; overlay->x0 = overlay->y0 = 0;
overlay->next_known_text = g_string_new(NULL); overlay->default_text = g_strdup("");
overlay->next_known_text_change = 0; overlay->need_render = TRUE;
gst_element_set_loop_function(GST_ELEMENT(overlay), gst_textoverlay_loop); 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: case ARG_TEXT:
pango_layout_set_markup(overlay->layout, g_value_get_string(value), -1); if(overlay->default_text){
render_text(overlay); g_free(overlay->default_text);
}
overlay->default_text = g_strdup(g_value_get_string(value));
overlay->need_render = TRUE;
break; break;
case ARG_VALIGN: case ARG_VALIGN:

View file

@ -54,8 +54,10 @@ struct _GstTextOverlay {
GstTextOverlayHAlign halign; GstTextOverlayHAlign halign;
gint x0; gint x0;
gint y0; gint y0;
guint64 next_known_text_change; GstBuffer *current_buffer;
GString *next_known_text; GstBuffer *next_buffer;
gchar *default_text;
gboolean need_render;
}; };
struct _GstTextOverlayClass { struct _GstTextOverlayClass {