diff options
author | Janin Kolenc <janin.kolenc at marand.si> | 2009-04-09 23:53:39 +0200 |
---|---|---|
committer | Dave Robillard <dave@drobilla.net> | 2009-05-03 12:03:14 -0400 |
commit | 7d2e47cf7f947df007208f11b4ffaf074dbdc08a (patch) | |
tree | 82b8e375c30173a22f227d938c9b3b00b942732a /ext/x264/gstx264enc.c | |
parent | 6225d5a6bdf22ff968171d5c8b450a6afd7a8eb0 (diff) | |
download | gst-plugins-bad-7d2e47cf7f947df007208f11b4ffaf074dbdc08a.tar.gz gst-plugins-bad-7d2e47cf7f947df007208f11b4ffaf074dbdc08a.tar.bz2 gst-plugins-bad-7d2e47cf7f947df007208f11b4ffaf074dbdc08a.zip |
x264enc: add force keyframe event handling
Use the GstForceKeyUnit event to force a keyframe.
Fixes #578112.
Diffstat (limited to 'ext/x264/gstx264enc.c')
-rw-r--r-- | ext/x264/gstx264enc.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/ext/x264/gstx264enc.c b/ext/x264/gstx264enc.c index 2a777631..d9517729 100644 --- a/ext/x264/gstx264enc.c +++ b/ext/x264/gstx264enc.c @@ -217,6 +217,7 @@ static void gst_x264_enc_close_encoder (GstX264Enc * encoder); static gboolean gst_x264_enc_sink_set_caps (GstPad * pad, GstCaps * caps); static gboolean gst_x264_enc_sink_event (GstPad * pad, GstEvent * event); +static gboolean gst_x264_enc_src_event (GstPad * pad, GstEvent * event); static GstFlowReturn gst_x264_enc_chain (GstPad * pad, GstBuffer * buf); static void gst_x264_enc_flush_frames (GstX264Enc * encoder, gboolean send); static GstFlowReturn gst_x264_enc_encode_frame (GstX264Enc * encoder, @@ -418,6 +419,9 @@ gst_x264_enc_init (GstX264Enc * encoder, GstX264EncClass * klass) gst_pad_use_fixed_caps (encoder->srcpad); gst_element_add_pad (GST_ELEMENT (encoder), encoder->srcpad); + gst_pad_set_event_function (encoder->srcpad, + GST_DEBUG_FUNCPTR (gst_x264_enc_src_event)); + /* properties */ encoder->threads = ARG_THREADS_DEFAULT; encoder->pass = ARG_PASS_DEFAULT; @@ -452,6 +456,7 @@ gst_x264_enc_init (GstX264Enc * encoder, GstX264EncClass * klass) encoder->buffer_size = 100000; encoder->buffer = g_malloc (encoder->buffer_size); + encoder->i_type = X264_TYPE_AUTO; x264_param_default (&encoder->x264param); /* log callback setup; part of parameters */ @@ -804,6 +809,34 @@ gst_x264_enc_sink_set_caps (GstPad * pad, GstCaps * caps) } static gboolean +gst_x264_enc_src_event (GstPad * pad, GstEvent * event) +{ + gboolean ret; + GstX264Enc *encoder; + + encoder = GST_X264_ENC (gst_pad_get_parent (pad)); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_CUSTOM_UPSTREAM:{ + const GstStructure *s; + s = gst_event_get_structure (event); + if (gst_structure_has_name (s, "GstForceKeyUnit")) { + /* Set I frame request */ + encoder->i_type = X264_TYPE_I; + } + break; + } + default: + break; + } + + ret = gst_pad_push_event (encoder->sinkpad, event); + + gst_object_unref (encoder); + return ret; +} + +static gboolean gst_x264_enc_sink_event (GstPad * pad, GstEvent * event) { gboolean ret; @@ -817,6 +850,14 @@ gst_x264_enc_sink_event (GstPad * pad, GstEvent * event) break; /* no flushing if flush received, * buffers in encoder are considered (in the) past */ + case GST_EVENT_CUSTOM_DOWNSTREAM:{ + const GstStructure *s; + s = gst_event_get_structure (event); + if (gst_structure_has_name (s, "GstForceKeyUnit")) { + encoder->i_type = X264_TYPE_I; + } + break; + } default: break; } @@ -837,7 +878,6 @@ gst_x264_enc_chain (GstPad * pad, GstBuffer * buf) GstFlowReturn ret; x264_picture_t pic_in; gint i_nal, i; - if (G_UNLIKELY (encoder->x264enc == NULL)) goto not_inited; @@ -859,7 +899,11 @@ gst_x264_enc_chain (GstPad * pad, GstBuffer * buf) pic_in.img.i_stride[i] = encoder->stride[i]; } - pic_in.i_type = X264_TYPE_AUTO; + pic_in.i_type = encoder->i_type; + + /* Reset encoder forced picture type */ + encoder->i_type = X264_TYPE_AUTO; + pic_in.i_pts = GST_BUFFER_TIMESTAMP (buf); ret = gst_x264_enc_encode_frame (encoder, &pic_in, &i_nal, TRUE); |