gdkpixbufdec: Keep serialized events in order, and don't send SEGMENT before CAPS

This commit is contained in:
Sebastian Dröge 2013-05-28 15:46:43 +02:00
parent 80850df711
commit f287756f87
3 changed files with 35 additions and 4 deletions

View file

@ -70,6 +70,7 @@ gst_gdk_animation_get_type (void)
return object_type;
}
static void
gst_gdk_animation_class_init (gpointer g_class, gpointer class_data)
{
@ -85,6 +86,7 @@ gst_gdk_animation_class_init (gpointer g_class, gpointer class_data)
anim_class->get_size = gst_gdk_animation_get_size;
anim_class->get_iter = gst_gdk_animation_get_iter;
}
static void
gst_gdk_animation_finalize (GObject * object)
{
@ -210,6 +212,7 @@ gst_gdk_animation_iter_class_init (gpointer g_class, gpointer class_data)
gst_gdk_animation_iter_on_currently_loading_frame;
anim_iter_class->advance = gst_gdk_animation_iter_advance;
}
static void
gst_gdk_animation_iter_init (GTypeInstance * instance, gpointer g_class)
{
@ -218,6 +221,7 @@ gst_gdk_animation_iter_init (GTypeInstance * instance, gpointer g_class)
iter->buffers = g_queue_new ();
iter->eos = FALSE;
}
static void
gst_gdk_animation_iter_finalize (GObject * object)
{
@ -242,6 +246,7 @@ gst_gdk_animation_iter_finalize (GObject * object)
}
G_OBJECT_CLASS (iter_parent_class)->finalize (object);
}
static void
got_handoff (GstElement * fakesink, GstBuffer * buffer, GstPad * pad,
GstGdkAnimationIter * iter)
@ -373,12 +378,14 @@ gst_gdk_animation_get_more_buffers (GstGdkAnimationIter * iter)
} while (last == g_queue_peek_tail (iter->buffers));
return last != g_queue_peek_tail (iter->buffers);
}
static void
pixbuf_destroy_notify (guchar * pixels, gpointer data)
{
GST_LOG ("unreffing buffer %p because pixbuf was destroyed", data);
gst_data_unref (GST_DATA (data));
}
static void
gst_gdk_animation_iter_create_pixbuf (GstGdkAnimationIter * iter)
{
@ -427,6 +434,7 @@ gst_gdk_animation_iter_create_pixbuf (GstGdkAnimationIter * iter)
GST_LOG_OBJECT (iter, "created pixbuf %p from buffer %p (refcount %d)",
iter->pixbuf, buf, GST_DATA_REFCOUNT_VALUE (buf));
}
static GdkPixbufAnimationIter *
gst_gdk_animation_get_iter (GdkPixbufAnimation * anim,
const GTimeVal * start_time)
@ -583,6 +591,7 @@ gst_gdk_animation_iter_on_currently_loading_frame (GdkPixbufAnimationIter *
return TRUE;
}
static GdkPixbuf *
gst_gdk_animation_get_static_image (GdkPixbufAnimation * animation)
{
@ -617,8 +626,8 @@ gst_gdk_animation_get_static_image (GdkPixbufAnimation * animation)
gst_data_unref (GST_DATA (buf));
}
/* now we do evil stuff, be sure to get rid of the iterator afterwards */
if (!gst_element_send_event (gst_bin_get_by_name (GST_BIN (iter->
pipeline), "sink"),
if (!gst_element_send_event (gst_bin_get_by_name (GST_BIN
(iter->pipeline), "sink"),
gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, offset))) {
GST_INFO_OBJECT (ani, "seeking didn't work. Using next image");

View file

@ -295,6 +295,7 @@ gst_gdk_pixbuf_dec_flush (GstGdkPixbufDec * filter)
if (GST_VIDEO_INFO_FORMAT (&filter->info) == GST_VIDEO_FORMAT_UNKNOWN) {
GstVideoInfo info;
GstVideoFormat fmt;
GList *l;
GST_DEBUG ("Set size to %dx%d", width, height);
@ -323,6 +324,11 @@ gst_gdk_pixbuf_dec_flush (GstGdkPixbufDec * filter)
gst_caps_unref (caps);
gst_gdk_pixbuf_dec_setup_pool (filter, &info);
for (l = filter->pending_events; l; l = l->next)
gst_pad_push_event (filter->srcpad, l->data);
g_list_free (filter->pending_events);
filter->pending_events = NULL;
}
ret = gst_buffer_pool_acquire_buffer (filter->pool, &outbuf, NULL);
@ -412,8 +418,12 @@ gst_gdk_pixbuf_dec_sink_event (GstPad * pad, GstObject * parent,
}
}
break;
case GST_EVENT_SEGMENT:
case GST_EVENT_FLUSH_STOP:
g_list_free_full (pixbuf->pending_events,
(GDestroyNotify) gst_event_unref);
pixbuf->pending_events = NULL;
/* Fall through */
case GST_EVENT_SEGMENT:
if (pixbuf->pixbuf_loader != NULL) {
gdk_pixbuf_loader_close (pixbuf->pixbuf_loader, NULL);
g_object_unref (G_OBJECT (pixbuf->pixbuf_loader));
@ -424,7 +434,16 @@ gst_gdk_pixbuf_dec_sink_event (GstPad * pad, GstObject * parent,
break;
}
if (forward) {
ret = gst_pad_event_default (pad, parent, event);
if (!gst_pad_has_current_caps (pixbuf->srcpad) &&
GST_EVENT_IS_SERIALIZED (event)
&& GST_EVENT_TYPE (event) > GST_EVENT_CAPS
&& GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_STOP
&& GST_EVENT_TYPE (event) != GST_EVENT_EOS) {
ret = TRUE;
pixbuf->pending_events = g_list_prepend (pixbuf->pending_events, event);
} else {
ret = gst_pad_event_default (pad, parent, event);
}
} else {
gst_event_unref (event);
}
@ -516,6 +535,8 @@ gst_gdk_pixbuf_dec_change_state (GstElement * element,
gst_buffer_pool_set_active (dec->pool, FALSE);
gst_object_replace ((GstObject **) & dec->pool, NULL);
}
g_list_free_full (dec->pending_events, (GDestroyNotify) gst_event_unref);
dec->pending_events = NULL;
break;
default:
break;

View file

@ -54,6 +54,7 @@ struct _GstGdkPixbufDec
GstVideoInfo info;
GstBufferPool *pool;
GList *pending_events;
};
struct _GstGdkPixbufDecClass