summaryrefslogtreecommitdiffstats
path: root/ext/x264/gstx264enc.c
diff options
context:
space:
mode:
authorJanin Kolenc <janin.kolenc at marand.si>2009-04-09 23:53:39 +0200
committerDave Robillard <dave@drobilla.net>2009-05-03 12:03:14 -0400
commit7d2e47cf7f947df007208f11b4ffaf074dbdc08a (patch)
tree82b8e375c30173a22f227d938c9b3b00b942732a /ext/x264/gstx264enc.c
parent6225d5a6bdf22ff968171d5c8b450a6afd7a8eb0 (diff)
downloadgst-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.c48
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);