diff --git a/ext/theora/gsttheoraenc.c b/ext/theora/gsttheoraenc.c
index c580675..7bee872 100644
--- a/ext/theora/gsttheoraenc.c
+++ b/ext/theora/gsttheoraenc.c
@@ -544,6 +544,7 @@ theora_enc_clear (GstTheoraEnc * enc)
   enc->bytes_out = 0;
   enc->granulepos_offset = 0;
   enc->timestamp_offset = 0;
+  enc->dups = 0;
 
   enc->next_ts = GST_CLOCK_TIME_NONE;
   enc->next_discont = FALSE;
@@ -1129,6 +1130,13 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
     return GST_FLOW_OK;
   }
 
+  /* buffers with a gap flag set mark duplicate frames */
+  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_GAP)) {
+    enc->dups++;
+    gst_buffer_unref (buffer);
+    return GST_FLOW_OK;
+  }
+ 
   GST_OBJECT_LOCK (enc);
   if (enc->bitrate_changed) {
     long int bitrate = enc->video_bitrate;
@@ -1267,6 +1275,15 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer)
       }
     }
 
+    if (enc->dups != 0) {
+      res = th_encode_ctl (enc->encoder, TH_ENCCTL_SET_DUP_COUNT, enc->dups, 0);
+      if (res < 0) {
+        GST_WARNING_OBJECT (enc, "Failed marking dups for last frame");
+        /* we can continue anyway, it'll just be slower */
+      }
+      enc->dups = 0;
+    }
+
     res = th_encode_ycbcr_in (enc->encoder, ycbcr);
     /* none of the failure cases can happen here */
     g_assert (res == 0);
diff --git a/ext/theora/gsttheoraenc.h b/ext/theora/gsttheoraenc.h
index 08707d8..2df8c47 100644
--- a/ext/theora/gsttheoraenc.h
+++ b/ext/theora/gsttheoraenc.h
@@ -103,6 +103,7 @@ struct _GstTheoraEnc
   gint width, height;
   gint fps_n, fps_d;
   GstClockTime next_ts;
+  gint dups;
 
   GstClockTime expected_ts;
   gboolean next_discont;
