From f287756f875fda1684e6fca45534e3db3c3988d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 28 May 2013 15:46:43 +0200 Subject: [PATCH] gdkpixbufdec: Keep serialized events in order, and don't send SEGMENT before CAPS --- ext/gdk_pixbuf/gstgdkanimation.c | 13 +++++++++++-- ext/gdk_pixbuf/gstgdkpixbufdec.c | 25 +++++++++++++++++++++++-- ext/gdk_pixbuf/gstgdkpixbufdec.h | 1 + 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/ext/gdk_pixbuf/gstgdkanimation.c b/ext/gdk_pixbuf/gstgdkanimation.c index 786a8071c4..42037fe8f2 100644 --- a/ext/gdk_pixbuf/gstgdkanimation.c +++ b/ext/gdk_pixbuf/gstgdkanimation.c @@ -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"); diff --git a/ext/gdk_pixbuf/gstgdkpixbufdec.c b/ext/gdk_pixbuf/gstgdkpixbufdec.c index 8fd4e9d7cd..fc42ed1944 100644 --- a/ext/gdk_pixbuf/gstgdkpixbufdec.c +++ b/ext/gdk_pixbuf/gstgdkpixbufdec.c @@ -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; diff --git a/ext/gdk_pixbuf/gstgdkpixbufdec.h b/ext/gdk_pixbuf/gstgdkpixbufdec.h index 59be24923b..832a30b410 100644 --- a/ext/gdk_pixbuf/gstgdkpixbufdec.h +++ b/ext/gdk_pixbuf/gstgdkpixbufdec.h @@ -54,6 +54,7 @@ struct _GstGdkPixbufDec GstVideoInfo info; GstBufferPool *pool; + GList *pending_events; }; struct _GstGdkPixbufDecClass