diff --git a/common b/common
index 48a5d85..39ac2f5 160000
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 48a5d85ebf4a0bad1c997c83100f710fe2154fbf
+Subproject commit 39ac2f563e12d22100e320c95aaab8d8e5812ca9
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
index b97c550..0cf46da 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
@@ -747,6 +747,9 @@ dpb_output (GstVaapiDecoderH264 * decoder, GstVaapiFrameStore * fs)
   fs->output_called = 0;
   if (!picture)
     return TRUE;
+
+  GST_DEBUG ("sending picture poc %d", picture->base.poc);
+
   return gst_vaapi_picture_output (GST_VAAPI_PICTURE_CAST (picture));
 }
 
@@ -798,17 +801,31 @@ dpb_find_nearest_prev_poc (GstVaapiDecoderH264 * decoder,
 
 /* Finds the picture with the lowest POC that needs to be output */
 static gint
-dpb_find_lowest_poc (GstVaapiDecoderH264 * decoder,
-    GstVaapiPictureH264 * picture, GstVaapiPictureH264 ** found_picture_ptr)
+dpb_find_lowest_poc_for_output (GstVaapiDecoderH264 * decoder,
+    GstVaapiPictureH264 * picture, GstVaapiPictureH264 ** found_picture_ptr,
+    gboolean * can_be_output)
 {
   GstVaapiDecoderH264Private *const priv = &decoder->priv;
   GstVaapiPictureH264 *found_picture = NULL;
-  guint i, j, found_index = -1;
+  guint i, j, found_index = -1, found_poc = -1;
+  gboolean is_first = TRUE;
+  gint last_output_poc = -1;
 
   for (i = 0; i < priv->dpb_count; i++) {
     GstVaapiFrameStore *const fs = priv->dpb[i];
-    if (!fs->output_needed)
+    if (!fs->output_needed) {
+      /* find the maximum poc of any previously output frames that
+         are still held in the DPB. */
+      if (can_be_output != NULL) {
+        for (j = 0; j < fs->num_buffers; j++) {
+          if (is_first || fs->buffers[j]->base.poc > last_output_poc) {
+            is_first = FALSE;
+            last_output_poc = fs->buffers[j]->base.poc;
+          }
+        }
+      }
       continue;
+    }
     if (picture && picture->base.view_id != fs->view_id)
       continue;
     for (j = 0; j < fs->num_buffers; j++) {
@@ -817,8 +834,31 @@ dpb_find_lowest_poc (GstVaapiDecoderH264 * decoder,
         continue;
       if (!found_picture || found_picture->base.poc > pic->base.poc ||
           (found_picture->base.poc == pic->base.poc &&
-              found_picture->base.voc > pic->base.voc))
-        found_picture = pic, found_index = i;
+              found_picture->base.voc > pic->base.voc)) {
+        found_picture = pic;
+        found_index = i;
+        found_poc = pic->base.poc;
+      }
+    }
+  }
+
+  if (can_be_output != NULL) {
+    /* found_picture can be output if it's the first frame in
+       the DPB, or if there's no gap between it and the most
+       recently output frame. */
+    *can_be_output = FALSE;
+    if (found_picture &&
+        gst_vaapi_frame_store_is_complete (priv->dpb[found_index])) {
+      if (is_first) {
+        *can_be_output = TRUE;
+      } else if (((int) (found_poc)) > ((int) (last_output_poc))) {
+        *can_be_output = (found_poc - last_output_poc) <= 2;
+      } else {
+        /* A frame with a higher poc has already been sent.
+           No choice now but to drop this frame */
+        GST_WARNING ("dropping out-of-sequence frame");
+        priv->dpb[found_index]->output_needed = FALSE;
+      }
     }
   }
 
@@ -827,6 +867,16 @@ dpb_find_lowest_poc (GstVaapiDecoderH264 * decoder,
   return found_index;
 }
 
+/* Finds the picture with the lowest POC that needs to be output */
+static gint
+dpb_find_lowest_poc (GstVaapiDecoderH264 * decoder,
+    GstVaapiPictureH264 * picture, GstVaapiPictureH264 ** found_picture_ptr)
+{
+  return dpb_find_lowest_poc_for_output (decoder, picture, found_picture_ptr,
+      NULL);
+}
+
+
 /* Finds the picture with the lowest VOC that needs to be output */
 static gint
 dpb_find_lowest_voc (GstVaapiDecoderH264 * decoder,
@@ -1629,6 +1679,21 @@ is_valid_state (guint state, guint ref_state)
   return (state & ref_state) == ref_state;
 }
 
+
+static void
+send_ready_frames (GstVaapiDecoderH264 * decoder)
+{
+  GstVaapiDecoderH264Private *const priv = &decoder->priv;
+
+  gboolean can_output = FALSE;
+  gint found_index;
+  while (((found_index = dpb_find_lowest_poc_for_output (decoder,
+                  priv->current_picture, NULL,
+                  &can_output)) >= 0) && can_output) {
+    dpb_output (decoder, priv->dpb[found_index]);
+  }
+}
+
 static GstVaapiDecoderStatus
 decode_current_picture (GstVaapiDecoderH264 * decoder)
 {
@@ -1658,6 +1723,12 @@ decode_current_picture (GstVaapiDecoderH264 * decoder)
     goto error;
   if (!dpb_add (decoder, picture))
     goto error;
+
+  GST_DEBUG ("added %d to dpb", picture->base.poc);
+  /* TODO: only call the following if we're in optional
+     'low-latency' mode? */
+  send_ready_frames (decoder);
+
   gst_vaapi_picture_replace (&priv->current_picture, NULL);
   return GST_VAAPI_DECODER_STATUS_SUCCESS;
 
