basetransform: fix sink event handling
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 22 Jul 2011 19:17:42 +0000 (21:17 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Fri, 22 Jul 2011 19:17:42 +0000 (21:17 +0200)
Implement the sink event handling like the src event handler. Make the default
implementation parse and forward the event. This makes it possible to actually
return an error value from the event handler.

libs/gst/base/gstbasetransform.c
libs/gst/base/gstbasetransform.h
plugins/elements/gstidentity.c

index 395857d..fa67304 100644 (file)
@@ -371,7 +371,7 @@ gst_base_transform_class_init (GstBaseTransformClass * klass)
   gobject_class->finalize = gst_base_transform_finalize;
 
   klass->passthrough_on_same_caps = FALSE;
-  klass->event = GST_DEBUG_FUNCPTR (gst_base_transform_sink_eventfunc);
+  klass->sink_event = GST_DEBUG_FUNCPTR (gst_base_transform_sink_eventfunc);
   klass->src_event = GST_DEBUG_FUNCPTR (gst_base_transform_src_eventfunc);
   klass->accept_caps =
       GST_DEBUG_FUNCPTR (gst_base_transform_acceptcaps_default);
@@ -1568,7 +1568,6 @@ gst_base_transform_sink_event (GstPad * pad, GstEvent * event)
   GstBaseTransform *trans;
   GstBaseTransformClass *bclass;
   gboolean ret = TRUE;
-  gboolean forward = TRUE;
 
   trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
   if (G_UNLIKELY (trans == NULL)) {
@@ -1577,13 +1576,8 @@ gst_base_transform_sink_event (GstPad * pad, GstEvent * event)
   }
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
-  if (bclass->event)
-    forward = bclass->event (trans, event);
-
-  /* FIXME, do this in the default event handler so the subclass can do
-   * something different. */
-  if (forward)
-    ret = gst_pad_push_event (trans->srcpad, event);
+  if (bclass->sink_event)
+    ret = bclass->sink_event (trans, event);
   else
     gst_event_unref (event);
 
@@ -1595,7 +1589,7 @@ gst_base_transform_sink_event (GstPad * pad, GstEvent * event)
 static gboolean
 gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
 {
-  gboolean forward = TRUE;
+  gboolean ret = TRUE, forward = TRUE;
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_FLUSH_START:
@@ -1623,7 +1617,7 @@ gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
       GstCaps *caps;
 
       gst_event_parse_caps (event, &caps);
-      gst_base_transform_setcaps (trans, trans->sinkpad, caps);
+      ret = gst_base_transform_setcaps (trans, trans->sinkpad, caps);
 
       forward = FALSE;
       break;
@@ -1641,7 +1635,12 @@ gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
       break;
   }
 
-  return forward;
+  if (ret && forward)
+    ret = gst_pad_push_event (trans->srcpad, event);
+  else
+    gst_event_unref (event);
+
+  return ret;
 }
 
 static gboolean
index f61a776..d3ed1f9 100644 (file)
@@ -144,11 +144,18 @@ struct _GstBaseTransform {
 /**
  * GstBaseTransformClass:
  * @parent_class:   Element parent class
+ * @passthrough_on_same_caps: If set to TRUE, passthrough mode will be
+ *                            automatically enabled if the caps are the same.
  * @transform_caps: Optional.  Given the pad in this direction and the given
  *                  caps, what caps are allowed on the other pad in this
  *                  element ?
  * @fixate_caps:    Optional. Given the pad in this direction and the given
  *                  caps, fixate the caps on the other pad.
+ * @accept_caps:    Optional. Since 0.10.30
+ *                  Subclasses can override this method to check if @caps can be
+ *                  handled by the element. The default implementation might not be
+ *                  the most optimal way to check this in all cases.
+ * @set_caps:       allows the subclass to be notified of the actual caps set.
  * @transform_size: Optional. Given the size of a buffer in the given direction
  *                  with the given caps, calculate the size in bytes of a buffer
  *                  on the other pad with the given other caps.
@@ -156,7 +163,6 @@ struct _GstBaseTransform {
  *                  the number of units the same.
  * @get_unit_size:  Required if the transform is not in-place.
  *                  get the size in bytes of one unit for the given caps.
- * @set_caps:       allows the subclass to be notified of the actual caps set.
  * @start:          Optional.
  *                  Called when the element starts processing.
  *                  Allows opening external resources.
@@ -169,13 +175,12 @@ struct _GstBaseTransform {
  *                  of the outgoing buffer.
  * @transform_ip:   Required if the element operates in-place.
  *                  Transform the incoming buffer in-place.
- * @event:          Optional.
- *                  Event handler on the sink pad. This function should return
- *                  TRUE if the base class should forward the event.
+ * @sink_event:     Optional.
+ *                  Event handler on the sink pad. The default implementation
+ *                  handles the event and forwards it downstream.
  * @src_event:      Optional.
- *                  Event handler on the source pad.
- * @passthrough_on_same_caps: If set to TRUE, passthrough mode will be
- *                            automatically enabled if the caps are the same.
+ *                  Event handler on the source pad. The default implementation
+ *                  handles the event and forwards it upstream.
  * @prepare_output_buffer: Optional.
  *                         Subclasses can override this to do their own
  *                         allocation of output buffers.  Elements that only do
@@ -193,10 +198,6 @@ struct _GstBaseTransform {
  *                    This method is called right before the base class will
  *                    start processing. Dynamic properties or other delayed
  *                    configuration could be performed in this method.
- * @accept_caps: Optional. Since 0.10.30
- *               Subclasses can override this method to check if @caps can be
- *               handled by the element. The default implementation might not be
- *               the most optimal way to check this in all cases.
  *
  * Subclasses can override any of the available virtual methods or not, as
  * needed. At minimum either @transform or @transform_ip need to be overridden.
@@ -237,8 +238,8 @@ struct _GstBaseTransformClass {
   gboolean      (*start)        (GstBaseTransform *trans);
   gboolean      (*stop)         (GstBaseTransform *trans);
 
-  gboolean      (*event)        (GstBaseTransform *trans, GstEvent *event);
-  /* src event */
+  /* sink and src pad event handlers */
+  gboolean      (*sink_event)   (GstBaseTransform *trans, GstEvent *event);
   gboolean      (*src_event)    (GstBaseTransform *trans, GstEvent *event);
 
   GstFlowReturn (*prepare_output_buffer) (GstBaseTransform * trans,
index 22cbcaf..e1affa9 100644 (file)
@@ -103,11 +103,12 @@ static void gst_identity_set_property (GObject * object, guint prop_id,
 static void gst_identity_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static gboolean gst_identity_event (GstBaseTransform * trans, GstEvent * event);
+static gboolean gst_identity_sink_event (GstBaseTransform * trans,
+    GstEvent * event);
 static GstFlowReturn gst_identity_transform_ip (GstBaseTransform * trans,
     GstBuffer * buf);
-static GstFlowReturn gst_identity_prepare_output_buffer (GstBaseTransform
-    trans, GstBuffer * in_buf, GstBuffer ** out_buf);
+static GstFlowReturn gst_identity_prepare_output_buffer (GstBaseTransform *
+    trans, GstBuffer * in_buf, GstBuffer ** out_buf);
 static gboolean gst_identity_start (GstBaseTransform * trans);
 static gboolean gst_identity_stop (GstBaseTransform * trans);
 
@@ -266,7 +267,7 @@ gst_identity_class_init (GstIdentityClass * klass)
   gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&sinktemplate));
 
-  gstbasetrans_class->event = GST_DEBUG_FUNCPTR (gst_identity_event);
+  gstbasetrans_class->sink_event = GST_DEBUG_FUNCPTR (gst_identity_sink_event);
   gstbasetrans_class->transform_ip =
       GST_DEBUG_FUNCPTR (gst_identity_transform_ip);
   gstbasetrans_class->prepare_output_buffer =
@@ -318,7 +319,7 @@ gst_identity_notify_last_message (GstIdentity * identity)
 }
 
 static gboolean
-gst_identity_event (GstBaseTransform * trans, GstEvent * event)
+gst_identity_sink_event (GstBaseTransform * trans, GstEvent * event)
 {
   GstIdentity *identity;
   gboolean ret = TRUE;
@@ -353,6 +354,8 @@ gst_identity_event (GstBaseTransform * trans, GstEvent * event)
       GstSegment segment;
 
       gst_event_copy_segment (event, &segment);
+      gst_event_copy_segment (event, &trans->segment);
+      trans->have_segment = TRUE;
 
       /* This is the first segment, send out a (0, -1) segment */
       gst_segment_init (&segment, segment.format);
@@ -369,11 +372,13 @@ gst_identity_event (GstBaseTransform * trans, GstEvent * event)
     identity->prev_offset = identity->prev_offset_end = GST_BUFFER_OFFSET_NONE;
   }
 
-  ret = GST_BASE_TRANSFORM_CLASS (parent_class)->event (trans, event);
 
   if (identity->single_segment && (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT)) {
     /* eat up segments */
-    ret = FALSE;
+    gst_event_unref (event);
+    ret = TRUE;
+  } else {
+    ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
   }
 
   return ret;