ext/gdk_pixbuf/gstgdkpixbuf.c: Add state change function where we set 0/1 as default...
authorTim-Philipp Müller <tim@centricular.net>
Thu, 28 Jun 2007 13:25:05 +0000 (13:25 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Thu, 28 Jun 2007 13:25:05 +0000 (13:25 +0000)
Original commit message from CVS:
* ext/gdk_pixbuf/gstgdkpixbuf.c: (gst_gdk_pixbuf_sink_setcaps),
(gst_gdk_pixbuf_class_init), (gst_gdk_pixbuf_flush),
(gst_gdk_pixbuf_sink_event), (gst_gdk_pixbuf_change_state):
Add state change function where we set 0/1 as default framerate in
case our setcaps function isn't called, like it might not in a
filesrc ! gdkpixbufdec scenario. Fixes assertion triggered by
gdkpixbufdec trying to create caps with a 0/0 framerate.
Also post an error message on the bus if gst_pad_push() fails when
called from our sink event handler (+1 for flow returns for event
functions in 0.11) instead of failing silently.

ChangeLog
ext/gdk_pixbuf/gstgdkpixbuf.c

index 2fa7dca..cea8dd8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2007-06-28  Tim-Philipp Müller  <tim at centricular dot net>
+
+       * ext/gdk_pixbuf/gstgdkpixbuf.c: (gst_gdk_pixbuf_sink_setcaps),
+       (gst_gdk_pixbuf_class_init), (gst_gdk_pixbuf_flush),
+       (gst_gdk_pixbuf_sink_event), (gst_gdk_pixbuf_change_state):
+         Add state change function where we set 0/1 as default framerate in
+         case our setcaps function isn't called, like it might not in a
+         filesrc ! gdkpixbufdec scenario. Fixes assertion triggered by
+         gdkpixbufdec trying to create caps with a 0/0 framerate.
+         Also post an error message on the bus if gst_pad_push() fails when
+         called from our sink event handler (+1 for flow returns for event
+         functions in 0.11) instead of failing silently.
+
 2007-06-27  Wim Taymans  <wim@fluendo.com>
 
        * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_configure_caps):
index d0e6fc3..4289a95 100644 (file)
@@ -86,6 +86,8 @@ static void gst_gdk_pixbuf_set_property (GObject * object, guint prop_id,
 static void gst_gdk_pixbuf_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
+static GstStateChangeReturn
+gst_gdk_pixbuf_change_state (GstElement * element, GstStateChange transition);
 static GstFlowReturn gst_gdk_pixbuf_chain (GstPad * pad, GstBuffer * buffer);
 static gboolean gst_gdk_pixbuf_sink_event (GstPad * pad, GstEvent * event);
 
@@ -102,19 +104,20 @@ gst_gdk_pixbuf_sink_setcaps (GstPad * pad, GstCaps * caps)
   const GValue *framerate;
   GstStructure *s;
 
-  filter = GST_GDK_PIXBUF (gst_pad_get_parent (pad));
+  filter = GST_GDK_PIXBUF (GST_PAD_PARENT (pad));
   s = gst_caps_get_structure (caps, 0);
 
-  filter->framerate_numerator = 0;
-  filter->framerate_denominator = 1;
   if ((framerate = gst_structure_get_value (s, "framerate")) != NULL) {
     filter->framerate_numerator = gst_value_get_fraction_numerator (framerate);
     filter->framerate_denominator =
         gst_value_get_fraction_denominator (framerate);
-    GST_DEBUG ("got framerate of %d/%d fps => packetized mode",
+    GST_DEBUG_OBJECT (filter, "got framerate of %d/%d fps => packetized mode",
         filter->framerate_numerator, filter->framerate_denominator);
+  } else {
+    filter->framerate_numerator = 0;
+    filter->framerate_denominator = 1;
+    GST_DEBUG_OBJECT (filter, "no framerate, assuming single image");
   }
-  gst_object_unref (filter);
 
   return TRUE;
 }
@@ -186,6 +189,9 @@ gst_gdk_pixbuf_class_init (GstGdkPixbufClass * klass)
   g_object_class_install_property (gobject_class, ARG_SILENT,
       g_param_spec_boolean ("silent", "Silent",
           "Produce verbose output ? (deprecated)", FALSE, G_PARAM_READWRITE));
+
+  gstelement_class->change_state =
+      GST_DEBUG_FUNCPTR (gst_gdk_pixbuf_change_state);
 }
 
 static void
@@ -280,7 +286,12 @@ gst_gdk_pixbuf_flush (GstGdkPixbuf * filter)
   }
 
   GST_DEBUG ("pushing... %d bytes", GST_BUFFER_SIZE (outbuf));
-  return gst_pad_push (filter->srcpad, outbuf);
+  ret = gst_pad_push (filter->srcpad, outbuf);
+
+  if (ret != GST_FLOW_OK)
+    GST_DEBUG_OBJECT (filter, "flow: %s", gst_flow_get_name (ret));
+
+  return ret;
 
   /* ERRORS */
 no_pixbuf:
@@ -317,6 +328,13 @@ gst_gdk_pixbuf_sink_event (GstPad * pad, GstEvent * event)
         res = gst_gdk_pixbuf_flush (pixbuf);
         g_object_unref (G_OBJECT (pixbuf->pixbuf_loader));
         pixbuf->pixbuf_loader = NULL;
+        /* as long as we don't have flow returns for event functions we need
+         * to post an error here, or the application might never know that
+         * things failed */
+        if (res != GST_FLOW_OK && res != GST_FLOW_WRONG_STATE) {
+          GST_ELEMENT_ERROR (pixbuf, STREAM, FAILED, (NULL),
+              ("Flow: %s", gst_flow_get_name (res)));
+        }
       }
       break;
     case GST_EVENT_NEWSEGMENT:
@@ -431,6 +449,38 @@ gst_gdk_pixbuf_get_property (GObject * object, guint prop_id,
   }
 }
 
+static GstStateChangeReturn
+gst_gdk_pixbuf_change_state (GstElement * element, GstStateChange transition)
+{
+  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+  GstGdkPixbuf *dec = GST_GDK_PIXBUF (element);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      /* default to single image mode, setcaps function might not be called */
+      dec->framerate_numerator = 0;
+      dec->framerate_denominator = 1;
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+  if (ret == GST_STATE_CHANGE_FAILURE)
+    return ret;
+
+  switch (transition) {
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      dec->framerate_numerator = 0;
+      dec->framerate_denominator = 0;
+      break;
+    default:
+      break;
+  }
+
+  return ret;
+}
+
 #define GST_GDK_PIXBUF_TYPE_FIND_SIZE 1024
 
 #ifdef enable_typefind