decoder: h264: improve DPB bumping process for MVC.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Tue, 3 Jun 2014 15:36:38 +0000 (17:36 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Tue, 10 Jun 2014 16:33:59 +0000 (18:33 +0200)
While invoking the DPB bumping process in presence of many views,
it could be necessary to output previous pictures that are ready,
in a whole. i.e. emitting all view components from the very first
view order index zero to the very last one in its original access
unit; and not starting from the view order index of the picture
that caused the DPB bumping process to be invoked.

As a reminder, the maximum number of frames in DPB for MultiView
High profile with more than 2 views is not necessarily a multiple
of the number of views.

This fixes decoding of MVCNV-4.264.

gst-libs/gst/vaapi/gstvaapidecoder_h264.c

index 1ce2983..340f7e1 100644 (file)
@@ -771,32 +771,55 @@ dpb_find_lowest_voc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture,
 }
 
 static gboolean
-dpb_bump(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
+dpb_output_other_views(GstVaapiDecoderH264 *decoder,
+    GstVaapiPictureH264 *picture, guint voc)
 {
     GstVaapiDecoderH264Private * const priv = &decoder->priv;
     GstVaapiPictureH264 *found_picture;
     gint found_index;
     gboolean success;
 
-    found_index = dpb_find_lowest_poc(decoder, picture, &found_picture);
-    if (found_index < 0)
-        return FALSE;
-
-    success = dpb_output(decoder, priv->dpb[found_index], found_picture);
-    dpb_evict(decoder, found_picture, found_index);
     if (priv->max_views == 1)
-        return success;
+        return TRUE;
 
     /* Emit all other view components that were in the same access
        unit than the picture we have just found */
+    found_picture = picture;
     for (;;) {
         found_index = dpb_find_lowest_voc(decoder, found_picture,
             &found_picture);
-        if (found_index < 0)
+        if (found_index < 0 || found_picture->base.voc >= voc)
             break;
-        dpb_output(decoder, priv->dpb[found_index], found_picture);
+        success = dpb_output(decoder, priv->dpb[found_index], found_picture);
         dpb_evict(decoder, found_picture, found_index);
+        if (!success)
+            return FALSE;
     }
+    return TRUE;
+}
+
+static gboolean
+dpb_bump(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
+{
+    GstVaapiDecoderH264Private * const priv = &decoder->priv;
+    GstVaapiPictureH264 *found_picture;
+    gint found_index;
+    gboolean success;
+
+    found_index = dpb_find_lowest_poc(decoder, picture, &found_picture);
+    if (found_index < 0)
+        return FALSE;
+
+    if (picture && picture->base.poc != found_picture->base.poc)
+        dpb_output_other_views(decoder, found_picture, found_picture->base.voc);
+
+    success = dpb_output(decoder, priv->dpb[found_index], found_picture);
+    dpb_evict(decoder, found_picture, found_index);
+    if (priv->max_views == 1)
+        return success;
+
+    if (picture && picture->base.poc != found_picture->base.poc)
+        dpb_output_other_views(decoder, found_picture, G_MAXUINT32);
     return success;
 }