diff --git a/gst-libs/gst/codecs/gsth265decoder.c b/gst-libs/gst/codecs/gsth265decoder.c index 1406da5aa2..8307d3e517 100644 --- a/gst-libs/gst/codecs/gsth265decoder.c +++ b/gst-libs/gst/codecs/gsth265decoder.c @@ -1340,7 +1340,7 @@ gst_h265_decoder_clear_dpb (GstH265Decoder * self, gboolean flush) /* If we are not flushing now, videodecoder baseclass will hold * GstVideoCodecFrame. Release frames manually */ if (!flush) { - while ((picture = gst_h265_dpb_bump (priv->dpb)) != NULL) { + while ((picture = gst_h265_dpb_bump (priv->dpb, TRUE)) != NULL) { GstVideoCodecFrame *frame = gst_video_decoder_get_frame (decoder, picture->system_frame_number); @@ -1360,7 +1360,7 @@ gst_h265_decoder_drain_internal (GstH265Decoder * self) GstH265DecoderPrivate *priv = self->priv; GstH265Picture *picture; - while ((picture = gst_h265_dpb_bump (priv->dpb)) != NULL) + while ((picture = gst_h265_dpb_bump (priv->dpb, TRUE)) != NULL) gst_h265_decoder_do_output_picture (self, picture); gst_h265_dpb_clear (priv->dpb); @@ -1394,7 +1394,7 @@ gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice, gst_h265_decoder_clear_dpb (self, FALSE); } else { gst_h265_dpb_delete_unused (priv->dpb); - while ((to_output = gst_h265_dpb_bump (priv->dpb)) != NULL) + while ((to_output = gst_h265_dpb_bump (priv->dpb, FALSE)) != NULL) gst_h265_decoder_do_output_picture (self, to_output); } } else { @@ -1404,7 +1404,7 @@ gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice, priv->SpsMaxLatencyPictures, sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] + 1)) { - to_output = gst_h265_dpb_bump (priv->dpb); + to_output = gst_h265_dpb_bump (priv->dpb, FALSE); /* Something wrong... */ if (!to_output) { @@ -1492,7 +1492,7 @@ gst_h265_decoder_finish_picture (GstH265Decoder * self, while (gst_h265_dpb_needs_bump (priv->dpb, sps->max_num_reorder_pics[sps->max_sub_layers_minus1], priv->SpsMaxLatencyPictures, 0)) { - GstH265Picture *to_output = gst_h265_dpb_bump (priv->dpb); + GstH265Picture *to_output = gst_h265_dpb_bump (priv->dpb, FALSE); /* Something wrong... */ if (!to_output) { diff --git a/gst-libs/gst/codecs/gsth265picture.c b/gst-libs/gst/codecs/gsth265picture.c index 573bcf70cb..5e95aabdd3 100644 --- a/gst-libs/gst/codecs/gsth265picture.c +++ b/gst-libs/gst/codecs/gsth265picture.c @@ -591,8 +591,11 @@ gst_h265_dpb_get_lowest_output_needed_picture (GstH265Dpb * dpb, /** * gst_h265_dpb_bump: * @dpb: a #GstH265Dpb + * @drain: whether draining or not * * Perform bumping process as defined in C.5.2.4 "Bumping" process. + * If @drain is %TRUE, @dpb will remove a #GstH265Picture from internal array + * so that returned #GstH265Picture could hold the last reference of it * * Returns: (nullable) (transfer full): a #GstH265Picture which is needed to be * outputted @@ -600,7 +603,7 @@ gst_h265_dpb_get_lowest_output_needed_picture (GstH265Dpb * dpb, * Since: 1.20 */ GstH265Picture * -gst_h265_dpb_bump (GstH265Dpb * dpb) +gst_h265_dpb_bump (GstH265Dpb * dpb, gboolean drain) { GstH265Picture *picture; gint index; @@ -618,7 +621,7 @@ gst_h265_dpb_bump (GstH265Dpb * dpb) dpb->num_output_needed--; g_assert (dpb->num_output_needed >= 0); - if (!picture->ref) + if (!picture->ref || drain) g_array_remove_index_fast (dpb->pic_list, index); return picture; diff --git a/gst-libs/gst/codecs/gsth265picture.h b/gst-libs/gst/codecs/gsth265picture.h index 281e4467b7..194aeaae70 100644 --- a/gst-libs/gst/codecs/gsth265picture.h +++ b/gst-libs/gst/codecs/gsth265picture.h @@ -203,7 +203,8 @@ gboolean gst_h265_dpb_needs_bump (GstH265Dpb * dpb, guint max_dec_pic_buffering); GST_CODECS_API -GstH265Picture * gst_h265_dpb_bump (GstH265Dpb * dpb); +GstH265Picture * gst_h265_dpb_bump (GstH265Dpb * dpb, + gboolean drain); G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstH265Picture, gst_h265_picture_unref)