videodecoder: Require to chain up to the parent classes event functions

This commit is contained in:
Sebastian Dröge 2012-04-24 19:51:30 +02:00
parent 13b88908ce
commit 63563e3d5e
2 changed files with 111 additions and 95 deletions

View file

@ -275,6 +275,11 @@ static GstVideoCodecFrame *gst_video_decoder_new_frame (GstVideoDecoder *
static void gst_video_decoder_clear_queues (GstVideoDecoder * dec);
static gboolean gst_video_decoder_sink_event_default (GstVideoDecoder * decoder,
GstEvent * event);
static gboolean gst_video_decoder_src_event_default (GstVideoDecoder * decoder,
GstEvent * event);
/* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init
* method to get to the padtemplates */
GType
@ -322,6 +327,9 @@ gst_video_decoder_class_init (GstVideoDecoderClass * klass)
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_video_decoder_change_state);
klass->sink_event = gst_video_decoder_sink_event_default;
klass->src_event = gst_video_decoder_src_event_default;
}
static void
@ -667,12 +675,45 @@ gst_video_decoder_flush (GstVideoDecoder * dec, gboolean hard)
return ret;
}
static gboolean
gst_video_decoder_sink_eventfunc (GstVideoDecoder * decoder, GstEvent * event)
gst_video_decoder_push_event (GstVideoDecoder * decoder, GstEvent * event)
{
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEGMENT:
{
GstSegment segment;
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
gst_event_copy_segment (event, &segment);
GST_DEBUG_OBJECT (decoder, "segment %" GST_SEGMENT_FORMAT, &segment);
if (segment.format != GST_FORMAT_TIME) {
GST_DEBUG_OBJECT (decoder, "received non TIME newsegment");
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
break;
}
decoder->output_segment = segment;
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
break;
}
default:
break;
}
return gst_pad_push_event (decoder->srcpad, event);
}
static gboolean
gst_video_decoder_sink_event_default (GstVideoDecoder * decoder,
GstEvent * event)
{
GstVideoDecoderClass *decoder_class;
GstVideoDecoderPrivate *priv;
gboolean handled = FALSE;
gboolean ret = FALSE;
priv = decoder->priv;
decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);
@ -683,8 +724,9 @@ gst_video_decoder_sink_eventfunc (GstVideoDecoder * decoder, GstEvent * event)
GstCaps *caps;
gst_event_parse_caps (event, &caps);
handled = gst_video_decoder_setcaps (decoder, caps);
ret = gst_video_decoder_setcaps (decoder, caps);
gst_event_unref (event);
event = NULL;
break;
}
case GST_EVENT_EOS:
@ -705,7 +747,7 @@ gst_video_decoder_sink_eventfunc (GstVideoDecoder * decoder, GstEvent * event)
flow_ret = GST_FLOW_OK;
}
handled = (flow_ret == GST_VIDEO_DECODER_FLOW_DROPPED);
ret = (flow_ret == GST_FLOW_OK);
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
break;
}
@ -769,82 +811,18 @@ gst_video_decoder_sink_eventfunc (GstVideoDecoder * decoder, GstEvent * event)
break;
}
return handled;
newseg_wrong_format:
{
GST_DEBUG_OBJECT (decoder, "received non TIME newsegment");
gst_event_unref (event);
/* SWALLOW EVENT */
/* FIXME : Ideally we'd like to return FALSE in the event handler */
return TRUE;
}
}
static gboolean
gst_video_decoder_push_event (GstVideoDecoder * decoder, GstEvent * event)
{
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEGMENT:
{
GstSegment segment;
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
gst_event_copy_segment (event, &segment);
GST_DEBUG_OBJECT (decoder, "segment %" GST_SEGMENT_FORMAT, &segment);
if (segment.format != GST_FORMAT_TIME) {
GST_DEBUG_OBJECT (decoder, "received non TIME newsegment");
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
break;
}
decoder->output_segment = segment;
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
break;
}
default:
break;
}
return gst_pad_push_event (decoder->srcpad, event);
}
static gboolean
gst_video_decoder_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event)
{
GstVideoDecoder *decoder;
GstVideoDecoderClass *decoder_class;
gboolean ret = FALSE;
gboolean handled = FALSE;
decoder = GST_VIDEO_DECODER (parent);
decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);
GST_DEBUG_OBJECT (decoder, "received event %d, %s", GST_EVENT_TYPE (event),
GST_EVENT_TYPE_NAME (event));
if (decoder_class->sink_event)
handled = decoder_class->sink_event (decoder, event);
if (!handled)
handled = gst_video_decoder_sink_eventfunc (decoder, 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. *
* If the subclass handles sending of EOS manually it can return
* _DROPPED from ::finish() and all other subclasses should have
* decoded/flushed all remaining data before this
*
* For FLUSH_STOP this is required because it is expected
* to be forwarded immediately and no buffers are queued anyway.
*/
/* 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. *
* If the subclass handles sending of EOS manually it can return
* _DROPPED from ::finish() and all other subclasses should have
* decoded/flushed all remaining data before this
*
* For FLUSH_STOP this is required because it is expected
* to be forwarded immediately and no buffers are queued anyway.
*/
if (event) {
if (!GST_EVENT_IS_SERIALIZED (event)
|| GST_EVENT_TYPE (event) == GST_EVENT_EOS
|| GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
@ -858,6 +836,34 @@ gst_video_decoder_sink_event (GstPad * pad, GstObject * parent,
}
return ret;
newseg_wrong_format:
{
GST_DEBUG_OBJECT (decoder, "received non TIME newsegment");
gst_event_unref (event);
/* SWALLOW EVENT */
return FALSE;
}
}
static gboolean
gst_video_decoder_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event)
{
GstVideoDecoder *decoder;
GstVideoDecoderClass *decoder_class;
gboolean ret = FALSE;
decoder = GST_VIDEO_DECODER (parent);
decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);
GST_DEBUG_OBJECT (decoder, "received event %d, %s", GST_EVENT_TYPE (event),
GST_EVENT_TYPE_NAME (event));
if (decoder_class->sink_event)
ret = decoder_class->sink_event (decoder, event);
return ret;
}
/* perform upstream byte <-> time conversion (duration, seeking)
@ -928,13 +934,12 @@ gst_video_decoder_do_seek (GstVideoDecoder * dec, GstEvent * event)
}
static gboolean
gst_video_decoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
gst_video_decoder_src_event_default (GstVideoDecoder * decoder,
GstEvent * event)
{
GstVideoDecoder *decoder;
GstVideoDecoderPrivate *priv;
gboolean res = FALSE;
decoder = GST_VIDEO_DECODER (parent);
priv = decoder->priv;
GST_DEBUG_OBJECT (decoder,
@ -970,11 +975,12 @@ gst_video_decoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
/* ... though a non-time seek can be aided as well */
/* First bring the requested format to time */
if (!(res =
gst_pad_query_convert (pad, format, cur, GST_FORMAT_TIME, &tcur)))
gst_pad_query_convert (decoder->srcpad, format, cur,
GST_FORMAT_TIME, &tcur)))
goto convert_error;
if (!(res =
gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME,
&tstop)))
gst_pad_query_convert (decoder->srcpad, format, stop,
GST_FORMAT_TIME, &tstop)))
goto convert_error;
/* then seek with time on the peer */
@ -1033,6 +1039,25 @@ convert_error:
goto done;
}
static gboolean
gst_video_decoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
GstVideoDecoder *decoder;
GstVideoDecoderClass *decoder_class;
gboolean ret = FALSE;
decoder = GST_VIDEO_DECODER (parent);
decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);
GST_DEBUG_OBJECT (decoder, "received event %d, %s", GST_EVENT_TYPE (event),
GST_EVENT_TYPE_NAME (event));
if (decoder_class->src_event)
ret = decoder_class->src_event (decoder, event);
return ret;
}
static gboolean
gst_video_decoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{

View file

@ -91,15 +91,6 @@ G_BEGIN_DECLS
**/
#define GST_VIDEO_DECODER_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS
/**
* GST_VIDEO_DECODER_FLOW_DROPPED:
*
* Returned when the event/buffer should be dropped.
*
* Since: 0.10.36
*/
#define GST_VIDEO_DECODER_FLOW_DROPPED GST_FLOW_CUSTOM_SUCCESS_1
/**
* GST_VIDEO_DECODER_INPUT_SEGMENT:
* @obj: base decoder instance