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; return object_type;
} }
static void static void
gst_gdk_animation_class_init (gpointer g_class, gpointer class_data) 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_size = gst_gdk_animation_get_size;
anim_class->get_iter = gst_gdk_animation_get_iter; anim_class->get_iter = gst_gdk_animation_get_iter;
} }
static void static void
gst_gdk_animation_finalize (GObject * object) 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; gst_gdk_animation_iter_on_currently_loading_frame;
anim_iter_class->advance = gst_gdk_animation_iter_advance; anim_iter_class->advance = gst_gdk_animation_iter_advance;
} }
static void static void
gst_gdk_animation_iter_init (GTypeInstance * instance, gpointer g_class) 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->buffers = g_queue_new ();
iter->eos = FALSE; iter->eos = FALSE;
} }
static void static void
gst_gdk_animation_iter_finalize (GObject * object) 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); G_OBJECT_CLASS (iter_parent_class)->finalize (object);
} }
static void static void
got_handoff (GstElement * fakesink, GstBuffer * buffer, GstPad * pad, got_handoff (GstElement * fakesink, GstBuffer * buffer, GstPad * pad,
GstGdkAnimationIter * iter) GstGdkAnimationIter * iter)
@ -373,12 +378,14 @@ gst_gdk_animation_get_more_buffers (GstGdkAnimationIter * iter)
} while (last == g_queue_peek_tail (iter->buffers)); } while (last == g_queue_peek_tail (iter->buffers));
return last != g_queue_peek_tail (iter->buffers); return last != g_queue_peek_tail (iter->buffers);
} }
static void static void
pixbuf_destroy_notify (guchar * pixels, gpointer data) pixbuf_destroy_notify (guchar * pixels, gpointer data)
{ {
GST_LOG ("unreffing buffer %p because pixbuf was destroyed", data); GST_LOG ("unreffing buffer %p because pixbuf was destroyed", data);
gst_data_unref (GST_DATA (data)); gst_data_unref (GST_DATA (data));
} }
static void static void
gst_gdk_animation_iter_create_pixbuf (GstGdkAnimationIter * iter) 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)", GST_LOG_OBJECT (iter, "created pixbuf %p from buffer %p (refcount %d)",
iter->pixbuf, buf, GST_DATA_REFCOUNT_VALUE (buf)); iter->pixbuf, buf, GST_DATA_REFCOUNT_VALUE (buf));
} }
static GdkPixbufAnimationIter * static GdkPixbufAnimationIter *
gst_gdk_animation_get_iter (GdkPixbufAnimation * anim, gst_gdk_animation_get_iter (GdkPixbufAnimation * anim,
const GTimeVal * start_time) const GTimeVal * start_time)
@ -583,6 +591,7 @@ gst_gdk_animation_iter_on_currently_loading_frame (GdkPixbufAnimationIter *
return TRUE; return TRUE;
} }
static GdkPixbuf * static GdkPixbuf *
gst_gdk_animation_get_static_image (GdkPixbufAnimation * animation) 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)); gst_data_unref (GST_DATA (buf));
} }
/* now we do evil stuff, be sure to get rid of the iterator afterwards */ /* 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-> if (!gst_element_send_event (gst_bin_get_by_name (GST_BIN
pipeline), "sink"), (iter->pipeline), "sink"),
gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET | gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, offset))) { GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, offset))) {
GST_INFO_OBJECT (ani, "seeking didn't work. Using next image"); 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) { if (GST_VIDEO_INFO_FORMAT (&filter->info) == GST_VIDEO_FORMAT_UNKNOWN) {
GstVideoInfo info; GstVideoInfo info;
GstVideoFormat fmt; GstVideoFormat fmt;
GList *l;
GST_DEBUG ("Set size to %dx%d", width, height); 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_caps_unref (caps);
gst_gdk_pixbuf_dec_setup_pool (filter, &info); 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); 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; break;
case GST_EVENT_SEGMENT:
case GST_EVENT_FLUSH_STOP: 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) { if (pixbuf->pixbuf_loader != NULL) {
gdk_pixbuf_loader_close (pixbuf->pixbuf_loader, NULL); gdk_pixbuf_loader_close (pixbuf->pixbuf_loader, NULL);
g_object_unref (G_OBJECT (pixbuf->pixbuf_loader)); g_object_unref (G_OBJECT (pixbuf->pixbuf_loader));
@ -424,7 +434,16 @@ gst_gdk_pixbuf_dec_sink_event (GstPad * pad, GstObject * parent,
break; break;
} }
if (forward) { if (forward) {
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); ret = gst_pad_event_default (pad, parent, event);
}
} else { } else {
gst_event_unref (event); 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_buffer_pool_set_active (dec->pool, FALSE);
gst_object_replace ((GstObject **) & dec->pool, NULL); gst_object_replace ((GstObject **) & dec->pool, NULL);
} }
g_list_free_full (dec->pending_events, (GDestroyNotify) gst_event_unref);
dec->pending_events = NULL;
break; break;
default: default:
break; break;

View file

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