codecs: Integrate H265 DPB full check into need_bump().
authorHe Junyan <junyan.he@intel.com>
Mon, 31 May 2021 09:51:58 +0000 (17:51 +0800)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 2 Jun 2021 13:10:35 +0000 (13:10 +0000)
The current DPB check of H265 is not very correct. The current frame
is already in the DPB when we check whether the DPB is full.
For example, the DPB max size is 16 and we have 15 ref frames in the
DPB, so the gst_h265_dpb_delete_unused() cleans no one, and then plus
the current frame, the DPB is 16. This causes an error return, but in
fact, the stream is correct.
We now integrate the DPB full check into the need_bump() function.
We add the correct frame into to DPB and then check whether the picture
num is bigger than max_num_pics of DPB(which means there is no room for
the current picture). If true, we bump the DPB immediately.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2291>

gst-libs/gst/codecs/gsth265decoder.c
gst-libs/gst/codecs/gsth265picture.c
gst-libs/gst/codecs/gsth265picture.h

index 484b610cf78b171ecb6f91cfae6c98776df22819..21f44dc4863cde31506e3c65e4863b95feb69124 100644 (file)
@@ -1628,13 +1628,6 @@ gst_h265_decoder_finish_picture (GstH265Decoder * self,
     gst_h265_decoder_do_output_picture (self, to_output);
   }
 
-  if (gst_h265_dpb_is_full (priv->dpb)) {
-    /* If we haven't managed to output anything to free up space in DPB
-     * to store this picture, it's an error in the stream */
-    GST_WARNING_OBJECT (self, "Could not free up space in DPB");
-    return FALSE;
-  }
-
   return TRUE;
 }
 
index ecdd670c873404e54d3e1602c2c296448ea94aa2..699ddb5ddc799c6e7a78887c02c1d2f1781c9083 100644 (file)
@@ -450,20 +450,6 @@ gst_h265_dpb_get_size (GstH265Dpb * dpb)
   return dpb->pic_list->len;
 }
 
-/**
- * gst_h265_dpb_is_full:
- * @dpb: a #GstH265Dpb
- *
- * Return: %TRUE if @dpb is full
- */
-gboolean
-gst_h265_dpb_is_full (GstH265Dpb * dpb)
-{
-  g_return_val_if_fail (dpb != NULL, -1);
-
-  return dpb->pic_list->len >= dpb->max_num_pics;
-}
-
 /**
  * gst_h265_dpb_get_picture:
  * @dpb: a #GstH265Dpb
@@ -533,6 +519,16 @@ gst_h265_dpb_needs_bump (GstH265Dpb * dpb, guint max_num_reorder_pics,
   g_return_val_if_fail (dpb != NULL, FALSE);
   g_assert (dpb->num_output_needed >= 0);
 
+  /* If DPB is full and there is no empty space to store current picture,
+   * need bumping.
+   * NOTE: current picture was added already by our decoding flow, so we
+   * need to do bumping until dpb->pic_list->len == dpb->max_num_pic
+   */
+  if (dpb->pic_list->len > dpb->max_num_pics) {
+    GST_TRACE ("No empty frame buffer, need bumping");
+    return TRUE;
+  }
+
   /* C.5.2.3 */
   if (dpb->num_output_needed > max_num_reorder_pics) {
     GST_TRACE ("num_output_needed (%d) > max_num_reorder_pics (%d)",
index fc03ff6f9d82776e53bd068927f74ba89dac8207..5b007fd4dbd181d67fcff130a1fe4c953e9e4724 100644 (file)
@@ -191,9 +191,6 @@ GstH265Picture * gst_h265_dpb_get_picture      (GstH265Dpb * dpb,
 GST_CODECS_API
 gint  gst_h265_dpb_get_size   (GstH265Dpb * dpb);
 
-GST_CODECS_API
-gboolean gst_h265_dpb_is_full (GstH265Dpb * dpb);
-
 GST_CODECS_API
 gboolean gst_h265_dpb_needs_bump (GstH265Dpb * dpb,
                                   guint max_num_reorder_pics,