From c442c9bd5e16b40cc386577ddffa6e404cd9bebe Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 31 May 2021 17:51:58 +0800 Subject: [PATCH] codecs: Integrate H265 DPB full check into need_bump(). 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: --- gst-libs/gst/codecs/gsth265decoder.c | 7 ------- gst-libs/gst/codecs/gsth265picture.c | 24 ++++++++++-------------- gst-libs/gst/codecs/gsth265picture.h | 3 --- 3 files changed, 10 insertions(+), 24 deletions(-) diff --git a/gst-libs/gst/codecs/gsth265decoder.c b/gst-libs/gst/codecs/gsth265decoder.c index 484b610cf7..21f44dc486 100644 --- a/gst-libs/gst/codecs/gsth265decoder.c +++ b/gst-libs/gst/codecs/gsth265decoder.c @@ -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; } diff --git a/gst-libs/gst/codecs/gsth265picture.c b/gst-libs/gst/codecs/gsth265picture.c index ecdd670c87..699ddb5ddc 100644 --- a/gst-libs/gst/codecs/gsth265picture.c +++ b/gst-libs/gst/codecs/gsth265picture.c @@ -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)", diff --git a/gst-libs/gst/codecs/gsth265picture.h b/gst-libs/gst/codecs/gsth265picture.h index fc03ff6f9d..5b007fd4db 100644 --- a/gst-libs/gst/codecs/gsth265picture.h +++ b/gst-libs/gst/codecs/gsth265picture.h @@ -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,