audiodecoder: chain up to parent for defaults

Chain up to the parent instead of using the FALSE return value from
the event function (because it's otherwise impossible to return an error).
This commit is contained in:
Wim Taymans 2012-02-15 13:42:19 +01:00
parent a7c80a9c87
commit c7d0fb556f
2 changed files with 39 additions and 41 deletions

View file

@ -276,6 +276,8 @@ static GstFlowReturn gst_audio_decoder_chain_reverse (GstAudioDecoder *
static GstStateChangeReturn gst_audio_decoder_change_state (GstElement *
element, GstStateChange transition);
static gboolean gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec,
GstEvent * event);
static gboolean gst_audio_decoder_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event);
static gboolean gst_audio_decoder_src_event (GstPad * pad, GstObject * parent,
@ -328,9 +330,11 @@ gst_audio_decoder_class_init (GstAudioDecoderClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *element_class;
GstAudioDecoderClass *audiodecoder_class;
gobject_class = G_OBJECT_CLASS (klass);
element_class = GST_ELEMENT_CLASS (klass);
audiodecoder_class = GST_AUDIO_DECODER_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
@ -363,6 +367,9 @@ gst_audio_decoder_class_init (GstAudioDecoderClass * klass)
g_param_spec_boolean ("plc", "Packet Loss Concealment",
"Perform packet loss concealment (if supported)",
DEFAULT_PLC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
audiodecoder_class->event =
GST_DEBUG_FUNCPTR (gst_audio_decoder_sink_eventfunc);
}
static void
@ -1436,7 +1443,7 @@ gst_audio_decoder_do_byte (GstAudioDecoder * dec)
static gboolean
gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event)
{
gboolean handled = FALSE;
gboolean ret;
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEGMENT:
@ -1473,6 +1480,8 @@ gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event)
} else {
GST_DEBUG_OBJECT (dec, "unsupported format; ignoring");
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
gst_event_unref (event);
ret = FALSE;
break;
}
}
@ -1518,14 +1527,12 @@ gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event)
dec->segment = seg;
dec->priv->pending_events =
g_list_append (dec->priv->pending_events, event);
handled = TRUE;
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
ret = TRUE;
break;
}
case GST_EVENT_FLUSH_START:
break;
case GST_EVENT_FLUSH_STOP:
GST_AUDIO_DECODER_STREAM_LOCK (dec);
/* prepare for fresh start */
@ -1535,12 +1542,20 @@ gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event)
g_list_free (dec->priv->pending_events);
dec->priv->pending_events = NULL;
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
/* Forward FLUSH_STOP, it is expected to be forwarded immediately
* and no buffers are queued anyway. */
ret = gst_pad_push_event (dec->srcpad, event);
break;
case GST_EVENT_EOS:
GST_AUDIO_DECODER_STREAM_LOCK (dec);
gst_audio_decoder_drain (dec);
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
/* Forward EOS because no buffer or serialized event will come after
* EOS and nothing could trigger another _finish_frame() call. */
ret = gst_pad_push_event (dec->srcpad, event);
break;
case GST_EVENT_CAPS:
@ -1550,14 +1565,23 @@ gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event)
gst_event_parse_caps (event, &caps);
gst_audio_decoder_sink_setcaps (dec, caps);
gst_event_unref (event);
handled = TRUE;
ret = TRUE;
break;
}
default:
if (!GST_EVENT_IS_SERIALIZED (event)) {
ret =
gst_pad_event_default (dec->sinkpad, GST_OBJECT_CAST (dec), event);
} else {
GST_AUDIO_DECODER_STREAM_LOCK (dec);
dec->priv->pending_events =
g_list_append (dec->priv->pending_events, event);
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
ret = TRUE;
}
break;
}
return handled;
return ret;
}
static gboolean
@ -1566,8 +1590,7 @@ gst_audio_decoder_sink_event (GstPad * pad, GstObject * parent,
{
GstAudioDecoder *dec;
GstAudioDecoderClass *klass;
gboolean handled = FALSE;
gboolean ret = TRUE;
gboolean ret;
dec = GST_AUDIO_DECODER (parent);
klass = GST_AUDIO_DECODER_GET_CLASS (dec);
@ -1576,35 +1599,11 @@ gst_audio_decoder_sink_event (GstPad * pad, GstObject * parent,
GST_EVENT_TYPE_NAME (event));
if (klass->event)
handled = klass->event (dec, event);
if (!handled)
handled = gst_audio_decoder_sink_eventfunc (dec, event);
if (!handled) {
/* Forward non-serialized events and EOS/FLUSH_STOP immediately.
* For EOS this is required because no buffer or serialized event
* will come after EOS and nothing could trigger another
* _finish_frame() call.
*
* For FLUSH_STOP this is required because it is expected
* to be forwarded immediately and no buffers are queued anyway.
*/
if (!GST_EVENT_IS_SERIALIZED (event)
|| GST_EVENT_TYPE (event) == GST_EVENT_EOS
|| GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
ret = gst_pad_event_default (pad, parent, event);
} else {
GST_AUDIO_DECODER_STREAM_LOCK (dec);
dec->priv->pending_events =
g_list_append (dec->priv->pending_events, event);
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
ret = TRUE;
}
ret = klass->event (dec, event);
else {
gst_event_unref (event);
ret = FALSE;
}
GST_DEBUG_OBJECT (dec, "event handled");
return ret;
}

View file

@ -193,9 +193,8 @@ struct _GstAudioDecoder
* @hard indicates whether a FLUSH is being processed,
* or otherwise a DISCONT (or conceptually similar).
* @event: Optional.
* Event handler on the sink pad. This function should return
* TRUE if the event was handled and should be discarded
* (i.e. not unref'ed).
* Event handler on the sink pad. Subclasses should chain up to
* the parent implementation to invoke the default handler.
* @pre_push: Optional.
* Called just prior to pushing (encoded data) buffer downstream.
* Subclass has full discretionary access to buffer,