videoencoder: Require to chain up to the parent's sink event functions

This commit is contained in:
Sebastian Dröge 2012-04-24 19:42:04 +02:00
parent f7bc9cc5ba
commit 13b88908ce
2 changed files with 49 additions and 54 deletions

View file

@ -215,6 +215,11 @@ static gboolean gst_video_encoder_src_query (GstPad * pad, GstObject * parent,
static GstVideoCodecFrame *gst_video_encoder_new_frame (GstVideoEncoder * static GstVideoCodecFrame *gst_video_encoder_new_frame (GstVideoEncoder *
encoder, GstBuffer * buf, GstClockTime timestamp, GstClockTime duration); encoder, GstBuffer * buf, GstClockTime timestamp, GstClockTime duration);
static gboolean gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
GstEvent * event);
static gboolean gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
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
@ -270,6 +275,9 @@ gst_video_encoder_class_init (GstVideoEncoderClass * klass)
gstelement_class->change_state = gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_video_encoder_change_state); GST_DEBUG_FUNCPTR (gst_video_encoder_change_state);
klass->sink_event = gst_video_encoder_sink_event_default;
klass->src_event = gst_video_encoder_src_event_default;
} }
static void static void
@ -773,7 +781,8 @@ gst_video_encoder_push_event (GstVideoEncoder * encoder, GstEvent * event)
} }
static gboolean static gboolean
gst_video_encoder_sink_eventfunc (GstVideoEncoder * encoder, GstEvent * event) gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
GstEvent * event)
{ {
GstVideoEncoderClass *encoder_class; GstVideoEncoderClass *encoder_class;
gboolean ret = FALSE; gboolean ret = FALSE;
@ -788,6 +797,7 @@ gst_video_encoder_sink_eventfunc (GstVideoEncoder * encoder, GstEvent * event)
gst_event_parse_caps (event, &caps); gst_event_parse_caps (event, &caps);
ret = gst_video_encoder_setcaps (encoder, caps); ret = gst_video_encoder_setcaps (encoder, caps);
gst_event_unref (event); gst_event_unref (event);
event = NULL;
break; break;
} }
case GST_EVENT_EOS: case GST_EVENT_EOS:
@ -803,7 +813,7 @@ gst_video_encoder_sink_eventfunc (GstVideoEncoder * encoder, GstEvent * event)
flow_ret = GST_FLOW_OK; flow_ret = GST_FLOW_OK;
} }
ret = (flow_ret == GST_VIDEO_ENCODER_FLOW_DROPPED); ret = (flow_ret == GST_FLOW_OK);
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder); GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
break; break;
} }
@ -852,6 +862,7 @@ gst_video_encoder_sink_eventfunc (GstVideoEncoder * encoder, GstEvent * event)
GST_TIME_ARGS (running_time), all_headers, count); GST_TIME_ARGS (running_time), all_headers, count);
} }
gst_event_unref (event); gst_event_unref (event);
event = NULL;
ret = TRUE; ret = TRUE;
} }
break; break;
@ -860,6 +871,29 @@ gst_video_encoder_sink_eventfunc (GstVideoEncoder * encoder, GstEvent * event)
break; break;
} }
/* 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 simply
* not chain up to the parent class' event handler
*
* 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) {
ret = gst_video_encoder_push_event (encoder, event);
} else {
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
encoder->priv->current_frame_events =
g_list_prepend (encoder->priv->current_frame_events, event);
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
}
}
return ret; return ret;
} }
@ -869,7 +903,6 @@ gst_video_encoder_sink_event (GstPad * pad, GstObject * parent,
{ {
GstVideoEncoder *enc; GstVideoEncoder *enc;
GstVideoEncoderClass *klass; GstVideoEncoderClass *klass;
gboolean handled = FALSE;
gboolean ret = TRUE; gboolean ret = TRUE;
enc = GST_VIDEO_ENCODER (parent); enc = GST_VIDEO_ENCODER (parent);
@ -879,44 +912,16 @@ gst_video_encoder_sink_event (GstPad * pad, GstObject * parent,
GST_EVENT_TYPE_NAME (event)); GST_EVENT_TYPE_NAME (event));
if (klass->sink_event) if (klass->sink_event)
handled = klass->sink_event (enc, event); ret = klass->sink_event (enc, event);
if (!handled)
handled = gst_video_encoder_sink_eventfunc (enc, 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)
|| GST_EVENT_TYPE (event) == GST_EVENT_EOS
|| GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
ret = gst_video_encoder_push_event (enc, event);
} else {
GST_VIDEO_ENCODER_STREAM_LOCK (enc);
enc->priv->current_frame_events =
g_list_prepend (enc->priv->current_frame_events, event);
GST_VIDEO_ENCODER_STREAM_UNLOCK (enc);
}
}
GST_DEBUG_OBJECT (enc, "event handled");
return ret; return ret;
} }
static gboolean static gboolean
gst_video_encoder_src_eventfunc (GstVideoEncoder * encoder, GstEvent * event) gst_video_encoder_src_event_default (GstVideoEncoder * encoder,
GstEvent * event)
{ {
gboolean handled = FALSE; gboolean ret = FALSE;
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CUSTOM_UPSTREAM: case GST_EVENT_CUSTOM_UPSTREAM:
@ -942,7 +947,8 @@ gst_video_encoder_src_eventfunc (GstVideoEncoder * encoder, GstEvent * event)
GST_TIME_ARGS (running_time), all_headers, count); GST_TIME_ARGS (running_time), all_headers, count);
} }
gst_event_unref (event); gst_event_unref (event);
handled = TRUE; event = NULL;
ret = TRUE;
} }
break; break;
} }
@ -950,7 +956,12 @@ gst_video_encoder_src_eventfunc (GstVideoEncoder * encoder, GstEvent * event)
break; break;
} }
return handled; if (event)
ret =
gst_pad_event_default (encoder->srcpad, GST_OBJECT_CAST (encoder),
event);
return ret;
} }
static gboolean static gboolean
@ -959,7 +970,6 @@ gst_video_encoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
GstVideoEncoder *encoder; GstVideoEncoder *encoder;
GstVideoEncoderClass *klass; GstVideoEncoderClass *klass;
gboolean ret = FALSE; gboolean ret = FALSE;
gboolean handled = FALSE;
encoder = GST_VIDEO_ENCODER (parent); encoder = GST_VIDEO_ENCODER (parent);
klass = GST_VIDEO_ENCODER_GET_CLASS (encoder); klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
@ -967,13 +977,7 @@ gst_video_encoder_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
GST_LOG_OBJECT (encoder, "handling event: %" GST_PTR_FORMAT, event); GST_LOG_OBJECT (encoder, "handling event: %" GST_PTR_FORMAT, event);
if (klass->src_event) if (klass->src_event)
handled = klass->src_event (encoder, event); ret = klass->src_event (encoder, event);
if (!handled)
handled = gst_video_encoder_src_eventfunc (encoder, event);
if (!handled)
ret = gst_pad_event_default (pad, parent, event);
return ret; return ret;
} }

View file

@ -60,15 +60,6 @@ G_BEGIN_DECLS
*/ */
#define GST_VIDEO_ENCODER_SRC_NAME "src" #define GST_VIDEO_ENCODER_SRC_NAME "src"
/**
* GST_VIDEO_ENCODER_FLOW_DROPPED:
*
* Returned when the event/buffer should be dropped.
*
* Since: 0.10.36
*/
#define GST_VIDEO_ENCODER_FLOW_DROPPED GST_FLOW_CUSTOM_SUCCESS_1
/** /**
* GST_VIDEO_ENCODER_SRC_PAD: * GST_VIDEO_ENCODER_SRC_PAD:
* @obj: a #GstVideoEncoder * @obj: a #GstVideoEncoder