basetransform: fix sink event handling

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.
This commit is contained in:
Wim Taymans 2011-07-22 21:17:42 +02:00
parent 5dde10f0e4
commit 2ff17fb622
3 changed files with 37 additions and 32 deletions

View 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

View 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,

View 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;