diff --git a/omx/gstbasevideoencoder.c b/omx/gstbasevideoencoder.c
index ca201f3..19fc563 100644
--- a/omx/gstbasevideoencoder.c
+++ b/omx/gstbasevideoencoder.c
@@ -188,6 +188,7 @@ gst_base_video_encoder_reset (GstBaseVideoEncoder * base_video_encoder)
     gst_event_unref (base_video_encoder->force_keyunit_event);
     base_video_encoder->force_keyunit_event = NULL;
   }
+  gst_buffer_replace (&base_video_encoder->headers, NULL);
 
   g_list_foreach (base_video_encoder->current_frame_events,
       (GFunc) gst_event_unref, NULL);
@@ -226,11 +227,20 @@ gst_base_video_encoder_init (GstBaseVideoEncoder * base_video_encoder,
       GST_DEBUG_FUNCPTR (gst_base_video_encoder_src_event));
 
   base_video_encoder->a.at_eos = FALSE;
+  base_video_encoder->headers = NULL;
 
   /* encoder is expected to do so */
   base_video_encoder->sink_clipping = TRUE;
 }
 
+void
+gst_base_video_encoder_set_headers (GstBaseVideoEncoder *base_video_encoder,
+    GstBuffer *headers)
+{
+  GST_DEBUG_OBJECT (base_video_encoder, "new headers %p", headers);
+  gst_buffer_replace (&base_video_encoder->headers, headers);
+}
+
 static gboolean
 gst_base_video_encoder_drain (GstBaseVideoEncoder * enc)
 {
@@ -439,8 +449,13 @@ done:
 static void
 gst_base_video_encoder_finalize (GObject * object)
 {
+  GstBaseVideoEncoder *base_video_encoder;
+
   GST_DEBUG_OBJECT (object, "finalize");
 
+  base_video_encoder = GST_BASE_VIDEO_ENCODER (object);
+  gst_buffer_replace (&base_video_encoder->headers, NULL);
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -515,9 +530,15 @@ gst_base_video_encoder_sink_eventfunc (GstBaseVideoEncoder * base_video_encoder,
       if (gst_structure_has_name (s, "GstForceKeyUnit")) {
         GST_OBJECT_LOCK (base_video_encoder);
         base_video_encoder->force_keyframe = TRUE;
+        if (!gst_structure_get_boolean (s, "all-headers",
+            &base_video_encoder->force_keyframe_headers))
+          base_video_encoder->force_keyframe_headers = FALSE;
+
         if (base_video_encoder->force_keyunit_event)
           gst_event_unref (base_video_encoder->force_keyunit_event);
         base_video_encoder->force_keyunit_event = gst_event_copy (event);
+        GST_DEBUG_OBJECT (base_video_encoder, "GstForceKeyUnit, all-headers %d",
+            base_video_encoder->force_keyframe_headers);
         GST_OBJECT_UNLOCK (base_video_encoder);
         gst_event_unref (event);
         ret = TRUE;
@@ -602,9 +623,14 @@ gst_base_video_encoder_src_event (GstPad * pad, GstEvent * event)
       if (gst_structure_has_name (s, "GstForceKeyUnit")) {
         GST_OBJECT_LOCK (base_video_encoder);
         base_video_encoder->force_keyframe = TRUE;
+        if (!gst_structure_get_boolean (s, "all-headers",
+            &base_video_encoder->force_keyframe_headers))
+          base_video_encoder->force_keyframe_headers = FALSE;
         GST_OBJECT_UNLOCK (base_video_encoder);
 
         gst_event_unref (event);
+        GST_DEBUG_OBJECT (base_video_encoder, "GstForceKeyUnit, all-headers %d",
+            base_video_encoder->force_keyframe_headers);
         ret = TRUE;
       } else {
         ret =
@@ -841,6 +867,7 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
   GstFlowReturn ret = GST_FLOW_OK;
   GstBaseVideoEncoderClass *base_video_encoder_class;
   GList *l;
+  GstBuffer *headers = NULL;
 
   base_video_encoder_class =
       GST_BASE_VIDEO_ENCODER_GET_CLASS (base_video_encoder);
@@ -910,7 +937,15 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
   }
 
   if (frame->is_sync_point) {
-    GST_LOG_OBJECT (base_video_encoder, "key frame");
+    if (base_video_encoder->force_keyframe_headers) {
+      GST_DEBUG_OBJECT (base_video_encoder, "force_keyframe_headers");
+      if (base_video_encoder->headers) {
+        gst_buffer_ref (base_video_encoder->headers);
+        headers = base_video_encoder->headers;
+      }
+      base_video_encoder->force_keyframe_headers = FALSE;
+    }
+    GST_LOG_OBJECT (base_video_encoder, "key frame, headers %p", headers);
     base_video_encoder->distance_from_sync = 0;
     GST_BUFFER_FLAG_UNSET (frame->src_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
   } else {
@@ -933,6 +968,12 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
   GST_BUFFER_DURATION (frame->src_buffer) = frame->presentation_duration;
   GST_BUFFER_OFFSET (frame->src_buffer) = frame->decode_timestamp;
 
+  if (G_UNLIKELY (headers)) {
+    GST_BUFFER_TIMESTAMP (headers) = frame->presentation_timestamp;
+    GST_BUFFER_DURATION (headers) = 0;
+    GST_BUFFER_OFFSET (headers) = frame->decode_timestamp;
+  }
+
   /* update rate estimate */
   GST_BASE_VIDEO_CODEC (base_video_encoder)->bytes +=
       GST_BUFFER_SIZE (frame->src_buffer);
@@ -953,6 +994,12 @@ gst_base_video_encoder_finish_frame (GstBaseVideoEncoder * base_video_encoder,
   gst_buffer_set_caps (GST_BUFFER (frame->src_buffer),
       GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder)));
 
+  if (G_UNLIKELY (headers)) {
+    gst_buffer_set_caps (headers,
+        GST_PAD_CAPS (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder)));
+    gst_pad_push (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder), headers);
+  }
+
   if (base_video_encoder_class->shape_output) {
     ret = base_video_encoder_class->shape_output (base_video_encoder, frame);
   } else {
diff --git a/omx/gstbasevideoencoder.h b/omx/gstbasevideoencoder.h
index 1cb3805..c896ded 100644
--- a/omx/gstbasevideoencoder.h
+++ b/omx/gstbasevideoencoder.h
@@ -85,6 +85,7 @@ struct _GstBaseVideoEncoder
   int               distance_from_sync;
 
   gboolean          force_keyframe;
+  gboolean          force_keyframe_headers;
 
   /*< private >*/
   /* FIXME move to real private part ?
@@ -96,6 +97,7 @@ struct _GstBaseVideoEncoder
 
   GstEvent         *force_keyunit_event;
   GList            *current_frame_events;
+  GstBuffer        *headers;
 
   union {
     void *padding;
@@ -178,7 +180,8 @@ void                   gst_base_video_encoder_set_latency (GstBaseVideoEncoder *
                                                            GstClockTime min_latency, GstClockTime max_latency);
 void                   gst_base_video_encoder_set_latency_fields (GstBaseVideoEncoder *base_video_encoder,
                                                                   int n_fields);
-
+void                   gst_base_video_encoder_set_headers (GstBaseVideoEncoder *base_video_encoder,
+                                                                  GstBuffer *headers);
 G_END_DECLS
 
 #endif
diff --git a/omx/gstomxh264enc.c b/omx/gstomxh264enc.c
index af1ad6c..95e8f2e 100644
--- a/omx/gstomxh264enc.c
+++ b/omx/gstomxh264enc.c
@@ -341,7 +341,17 @@ gst_omx_h264_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port,
     if (buf->omx_buf->nFilledLen >= 4 &&
         GST_READ_UINT32_BE (buf->omx_buf->pBuffer +
             buf->omx_buf->nOffset) == 0x00000001) {
+      GstBuffer *hdrs;
+
+      GST_DEBUG_OBJECT (self, "got codecconfig in byte-stream format");
       buf->omx_buf->nFlags &= ~OMX_BUFFERFLAG_CODECCONFIG;
+
+      hdrs = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
+      memcpy (GST_BUFFER_DATA (hdrs),
+          buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
+          buf->omx_buf->nFilledLen);
+      gst_base_video_encoder_set_headers (GST_BASE_VIDEO_ENCODER (self), hdrs);
+      gst_buffer_unref (hdrs);
     }
   }
 
diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c
index 4f1084e..16c7ac4 100644
--- a/omx/gstomxvideoenc.c
+++ b/omx/gstomxvideoenc.c
@@ -757,6 +757,8 @@ gst_omx_video_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port,
         buf->omx_buf->nFilledLen);
 
     gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
+    gst_base_video_encoder_set_headers (GST_BASE_VIDEO_ENCODER (self),
+        codec_data);
     if (!gst_pad_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (self), caps)) {
       gst_caps_unref (caps);
       return GST_FLOW_NOT_NEGOTIATED;
