mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-24 06:56:26 +00:00
videoencoder: Require to chain up to the parent's sink event functions
This commit is contained in:
parent
f7bc9cc5ba
commit
13b88908ce
2 changed files with 49 additions and 54 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue