From b7f37f9afbd98a6d3ee800e9f87c4d85fff0cc5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Fri, 20 Nov 2009 21:32:31 -0500 Subject: [PATCH] x264enc: Make upstream GstForceKeyUnit thread-safe Also send the GstForceKeyUnit event downstream when an upstream on is received, allowing muxers or payloaders to take appropriate actions. https://bugzilla.gnome.org/show_bug.cgi?id=602556 --- ext/x264/gstx264enc.c | 33 ++++++++++++++++++++++++++++++--- ext/x264/gstx264enc.h | 1 + 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/ext/x264/gstx264enc.c b/ext/x264/gstx264enc.c index ff0f0faf57..e76adf2334 100644 --- a/ext/x264/gstx264enc.c +++ b/ext/x264/gstx264enc.c @@ -490,7 +490,6 @@ 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 */ @@ -507,6 +506,11 @@ gst_x264_enc_reset (GstX264Enc * encoder) encoder->x264enc = NULL; encoder->width = 0; encoder->height = 0; + + GST_OBJECT_LOCK (encoder); + encoder->i_type = X264_TYPE_AUTO; + encoder->send_forcekeyunit = FALSE; + GST_OBJECT_UNLOCK (encoder); } static void @@ -873,8 +877,9 @@ gst_x264_enc_sink_set_caps (GstPad * pad, GstCaps * caps) static gboolean gst_x264_enc_src_event (GstPad * pad, GstEvent * event) { - gboolean ret; + gboolean ret = TRUE; GstX264Enc *encoder; + gboolean forward = TRUE; encoder = GST_X264_ENC (gst_pad_get_parent (pad)); @@ -884,7 +889,12 @@ gst_x264_enc_src_event (GstPad * pad, GstEvent * event) s = gst_event_get_structure (event); if (gst_structure_has_name (s, "GstForceKeyUnit")) { /* Set I frame request */ + GST_OBJECT_LOCK (encoder); encoder->i_type = X264_TYPE_I; + encoder->send_forcekeyunit = TRUE; + GST_OBJECT_UNLOCK (encoder); + forward = FALSE; + gst_event_unref (event); } break; } @@ -892,7 +902,8 @@ gst_x264_enc_src_event (GstPad * pad, GstEvent * event) break; } - ret = gst_pad_push_event (encoder->sinkpad, event); + if (forward) + ret = gst_pad_push_event (encoder->sinkpad, event); gst_object_unref (encoder); return ret; @@ -916,7 +927,9 @@ gst_x264_enc_sink_event (GstPad * pad, GstEvent * event) const GstStructure *s; s = gst_event_get_structure (event); if (gst_structure_has_name (s, "GstForceKeyUnit")) { + GST_OBJECT_LOCK (encoder); encoder->i_type = X264_TYPE_I; + GST_OBJECT_UNLOCK (encoder); } break; } @@ -961,10 +974,12 @@ gst_x264_enc_chain (GstPad * pad, GstBuffer * buf) pic_in.img.i_stride[i] = encoder->stride[i]; } + GST_OBJECT_LOCK (encoder); pic_in.i_type = encoder->i_type; /* Reset encoder forced picture type */ encoder->i_type = X264_TYPE_AUTO; + GST_OBJECT_UNLOCK (encoder); pic_in.i_pts = GST_BUFFER_TIMESTAMP (buf); @@ -1008,6 +1023,7 @@ gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in, GstClockTime timestamp; GstClockTime duration; guint8 *data; + gboolean send_forcekeyunit; if (G_UNLIKELY (encoder->x264enc == NULL)) return GST_FLOW_NOT_NEGOTIATED; @@ -1086,6 +1102,17 @@ gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in, GST_BUFFER_FLAG_SET (out_buf, GST_BUFFER_FLAG_DELTA_UNIT); } + GST_OBJECT_LOCK (encoder); + send_forcekeyunit = encoder->send_forcekeyunit; + encoder->send_forcekeyunit = FALSE; + GST_OBJECT_UNLOCK (encoder); + if (send_forcekeyunit) + gst_pad_push_event (encoder->srcpad, + gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, + gst_structure_new ("GstForceKeyUnit", + "timestamp", G_TYPE_UINT64, GST_BUFFER_TIMESTAMP (out_buf), + NULL))); + return gst_pad_push (encoder->srcpad, out_buf); } diff --git a/ext/x264/gstx264enc.h b/ext/x264/gstx264enc.h index 15ffe65e76..be8931a778 100644 --- a/ext/x264/gstx264enc.h +++ b/ext/x264/gstx264enc.h @@ -98,6 +98,7 @@ struct _GstX264Enc gulong buffer_size; gint i_type; + gboolean send_forcekeyunit; }; struct _GstX264EncClass