diff --git a/ext/x264/gstx264enc.c b/ext/x264/gstx264enc.c
index 66e7647..58c165f 100644
--- a/ext/x264/gstx264enc.c
+++ b/ext/x264/gstx264enc.c
@@ -1216,9 +1216,8 @@ gst_x264_enc_init_encoder (GstX264Enc * encoder)
 
   encoder->reconfig = FALSE;
 
-  GST_OBJECT_UNLOCK (encoder);
-
   encoder->x264enc = x264_encoder_open (&encoder->x264param);
+  GST_OBJECT_UNLOCK (encoder);
   if (!encoder->x264enc) {
     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE,
         ("Can not initialize x264 encoder."), (NULL));
@@ -1546,16 +1545,17 @@ gst_x264_enc_src_event (GstPad * pad, GstEvent * event)
 static gboolean
 gst_x264_enc_sink_event (GstPad * pad, GstEvent * event)
 {
-  gboolean ret;
   GstX264Enc *encoder;
-
+  gboolean ret = TRUE;
   encoder = GST_X264_ENC (gst_pad_get_parent (pad));
 
+
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_EOS:
       gst_x264_enc_flush_frames (encoder, TRUE);
+      ret = gst_pad_push_event (encoder->srcpad, event);
       break;
-    case GST_EVENT_TAG:{
+    case GST_EVENT_TAG: {
       GstTagList *tags = NULL;
 
       event =
@@ -1567,12 +1567,19 @@ gst_x264_enc_sink_event (GstPad * pad, GstEvent * event)
       gst_tag_list_remove_tag (tags, GST_TAG_CODEC);
       gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_ENCODER, "x264",
           GST_TAG_ENCODER_VERSION, X264_BUILD, NULL);
-      /* push is done below */
+      ret = gst_pad_push_event (encoder->srcpad, event);
+
+      break;
+    }
+    case GST_EVENT_FLUSH_START: {
+
+      ret = gst_pad_push_event (encoder->srcpad, event);
+      gst_x264_enc_flush_frames (encoder, FALSE);
+      gst_x264_enc_close_encoder (encoder);
+      gst_x264_enc_init_encoder (encoder);
       break;
-      /* no flushing if flush received,
-       * buffers in encoder are considered (in the) past */
     }
-    case GST_EVENT_CUSTOM_DOWNSTREAM:{
+    case GST_EVENT_CUSTOM_DOWNSTREAM: {
       const GstStructure *s;
       s = gst_event_get_structure (event);
       if (gst_structure_has_name (s, "GstForceKeyUnit")) {
@@ -1583,10 +1590,10 @@ gst_x264_enc_sink_event (GstPad * pad, GstEvent * event)
       break;
     }
     default:
+      ret = gst_pad_push_event (encoder->srcpad, event);
       break;
   }
 
-  ret = gst_pad_push_event (encoder->srcpad, event);
 
   gst_object_unref (encoder);
   return ret;
@@ -1614,7 +1621,7 @@ gst_x264_enc_chain (GstPad * pad, GstBuffer * buf)
   g_queue_push_tail (encoder->delay, buf);
 
   /* set up input picture */
-  memset (&pic_in, 0, sizeof (pic_in));
+  x264_picture_init (&pic_in);
 
   pic_in.img.i_csp = X264_CSP_I420;
   pic_in.img.i_plane = 3;
@@ -1676,17 +1683,20 @@ gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in,
   if (G_UNLIKELY (encoder->x264enc == NULL))
     return GST_FLOW_NOT_NEGOTIATED;
 
+  x264_picture_init (&pic_out);
+
   GST_OBJECT_LOCK (encoder);
   if (encoder->reconfig) {
     encoder->reconfig = FALSE;
     if (x264_encoder_reconfig (encoder->x264enc, &encoder->x264param) < 0)
       GST_WARNING_OBJECT (encoder, "Could not reconfigure");
   }
-  GST_OBJECT_UNLOCK (encoder);
 
   encoder_return = x264_encoder_encode (encoder->x264enc,
       &nal, i_nal, pic_in, &pic_out);
 
+  GST_OBJECT_UNLOCK (encoder);
+
   if (encoder_return < 0) {
     GST_ELEMENT_ERROR (encoder, STREAM, ENCODE, ("Encode x264 frame failed."),
         ("x264_encoder_encode return code=%d", encoder_return));
@@ -1722,7 +1732,9 @@ gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in,
   data = nal[0].p_payload;
 #endif
 
+  GST_OBJECT_LOCK (encoder);
   in_buf = g_queue_pop_head (encoder->delay);
+  GST_OBJECT_UNLOCK (encoder);
   if (in_buf) {
     duration = GST_BUFFER_DURATION (in_buf);
     gst_buffer_unref (in_buf);
@@ -1793,8 +1805,10 @@ gst_x264_enc_flush_frames (GstX264Enc * encoder, gboolean send)
 #endif
 
   /* in any case, make sure the delay queue is emptied */
-  while (!g_queue_is_empty (encoder->delay))
-    gst_buffer_unref (g_queue_pop_head (encoder->delay));
+ GST_OBJECT_LOCK (encoder);
+ while (!g_queue_is_empty (encoder->delay))
+   gst_buffer_unref (g_queue_pop_head (encoder->delay));
+ GST_OBJECT_UNLOCK (encoder);
 }
 
 static GstStateChangeReturn
