mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-19 20:46:22 +00:00
videodecoder: Require to chain up to the parent classes event functions
This commit is contained in:
parent
13b88908ce
commit
63563e3d5e
2 changed files with 111 additions and 95 deletions
|
@ -275,6 +275,11 @@ static GstVideoCodecFrame *gst_video_decoder_new_frame (GstVideoDecoder *
|
||||||
|
|
||||||
static void gst_video_decoder_clear_queues (GstVideoDecoder * dec);
|
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
|
/* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init
|
||||||
* method to get to the padtemplates */
|
* method to get to the padtemplates */
|
||||||
GType
|
GType
|
||||||
|
@ -322,6 +327,9 @@ gst_video_decoder_class_init (GstVideoDecoderClass * klass)
|
||||||
|
|
||||||
gstelement_class->change_state =
|
gstelement_class->change_state =
|
||||||
GST_DEBUG_FUNCPTR (gst_video_decoder_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
|
static void
|
||||||
|
@ -667,12 +675,45 @@ gst_video_decoder_flush (GstVideoDecoder * dec, gboolean hard)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
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;
|
GstVideoDecoderClass *decoder_class;
|
||||||
GstVideoDecoderPrivate *priv;
|
GstVideoDecoderPrivate *priv;
|
||||||
gboolean handled = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
priv = decoder->priv;
|
priv = decoder->priv;
|
||||||
decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);
|
decoder_class = GST_VIDEO_DECODER_GET_CLASS (decoder);
|
||||||
|
@ -683,8 +724,9 @@ gst_video_decoder_sink_eventfunc (GstVideoDecoder * decoder, GstEvent * event)
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
|
||||||
gst_event_parse_caps (event, &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);
|
gst_event_unref (event);
|
||||||
|
event = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
|
@ -705,7 +747,7 @@ gst_video_decoder_sink_eventfunc (GstVideoDecoder * decoder, GstEvent * event)
|
||||||
flow_ret = GST_FLOW_OK;
|
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);
|
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -769,82 +811,18 @@ gst_video_decoder_sink_eventfunc (GstVideoDecoder * decoder, GstEvent * event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return handled;
|
/* Forward non-serialized events and EOS/FLUSH_STOP immediately.
|
||||||
|
* For EOS this is required because no buffer or serialized event
|
||||||
newseg_wrong_format:
|
* will come after EOS and nothing could trigger another
|
||||||
{
|
* _finish_frame() call. *
|
||||||
GST_DEBUG_OBJECT (decoder, "received non TIME newsegment");
|
* If the subclass handles sending of EOS manually it can return
|
||||||
gst_event_unref (event);
|
* _DROPPED from ::finish() and all other subclasses should have
|
||||||
/* SWALLOW EVENT */
|
* decoded/flushed all remaining data before this
|
||||||
/* FIXME : Ideally we'd like to return FALSE in the event handler */
|
*
|
||||||
return TRUE;
|
* For FLUSH_STOP this is required because it is expected
|
||||||
}
|
* to be forwarded immediately and no buffers are queued anyway.
|
||||||
}
|
*/
|
||||||
|
if (event) {
|
||||||
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.
|
|
||||||
*/
|
|
||||||
if (!GST_EVENT_IS_SERIALIZED (event)
|
if (!GST_EVENT_IS_SERIALIZED (event)
|
||||||
|| GST_EVENT_TYPE (event) == GST_EVENT_EOS
|
|| GST_EVENT_TYPE (event) == GST_EVENT_EOS
|
||||||
|| GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
|
|| GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
|
||||||
|
@ -858,6 +836,34 @@ gst_video_decoder_sink_event (GstPad * pad, GstObject * parent,
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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)
|
/* perform upstream byte <-> time conversion (duration, seeking)
|
||||||
|
@ -928,13 +934,12 @@ gst_video_decoder_do_seek (GstVideoDecoder * dec, GstEvent * event)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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;
|
GstVideoDecoderPrivate *priv;
|
||||||
gboolean res = FALSE;
|
gboolean res = FALSE;
|
||||||
|
|
||||||
decoder = GST_VIDEO_DECODER (parent);
|
|
||||||
priv = decoder->priv;
|
priv = decoder->priv;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (decoder,
|
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 */
|
/* ... though a non-time seek can be aided as well */
|
||||||
/* First bring the requested format to time */
|
/* First bring the requested format to time */
|
||||||
if (!(res =
|
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;
|
goto convert_error;
|
||||||
if (!(res =
|
if (!(res =
|
||||||
gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME,
|
gst_pad_query_convert (decoder->srcpad, format, stop,
|
||||||
&tstop)))
|
GST_FORMAT_TIME, &tstop)))
|
||||||
goto convert_error;
|
goto convert_error;
|
||||||
|
|
||||||
/* then seek with time on the peer */
|
/* then seek with time on the peer */
|
||||||
|
@ -1033,6 +1039,25 @@ convert_error:
|
||||||
goto done;
|
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
|
static gboolean
|
||||||
gst_video_decoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
gst_video_decoder_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
||||||
{
|
{
|
||||||
|
|
|
@ -91,15 +91,6 @@ G_BEGIN_DECLS
|
||||||
**/
|
**/
|
||||||
#define GST_VIDEO_DECODER_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS
|
#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:
|
* GST_VIDEO_DECODER_INPUT_SEGMENT:
|
||||||
* @obj: base decoder instance
|
* @obj: base decoder instance
|
||||||
|
|
Loading…
Reference in a new issue