mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-27 01:28:34 +00:00
h265decoder: Fix DPB size calculation
MaxDpbSize specified in A.4.2 tells upper bound of decoded picture buffer size but does not tell actual required size. Use max_dec_pic_buffering value as a dpb size. Some backends such as DXVA and NVDEC might require pre-allocated DPB buffer and unnecessary large DPB size will result in waste of GPU memory. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6101>
This commit is contained in:
parent
144657dc0d
commit
d98c922995
1 changed files with 48 additions and 5 deletions
|
@ -462,9 +462,18 @@ gst_h265_decoder_get_max_dpb_size_from_sps (GstH265Decoder * self,
|
|||
guint PicSizeInSamplesY;
|
||||
/* Default is the worst case level 6.2 */
|
||||
guint32 MaxLumaPS = G_MAXUINT32;
|
||||
const gint MaxDpbPicBuf = 6;
|
||||
gint MaxDpbPicBuf = 6;
|
||||
gint max_dpb_size;
|
||||
|
||||
/* A.4.2, maxDpbPicBuf is equal to 6 for all profiles where the value of
|
||||
* sps_curr_pic_ref_enabled_flag is required to be equal to 0 and 7 for all
|
||||
* profiles where the value of sps_curr_pic_ref_enabled_flag is not required
|
||||
* to be equal to 0 */
|
||||
if (sps->sps_scc_extension_flag) {
|
||||
/* sps_curr_pic_ref_enabled_flag could be non-zero only if profile is SCC */
|
||||
MaxDpbPicBuf = 7;
|
||||
}
|
||||
|
||||
/* Unknown level */
|
||||
if (sps->profile_tier_level.level_idc == 0)
|
||||
return 16;
|
||||
|
@ -498,7 +507,25 @@ gst_h265_decoder_get_max_dpb_size_from_sps (GstH265Decoder * self,
|
|||
else
|
||||
max_dpb_size = MaxDpbPicBuf;
|
||||
|
||||
return MIN (max_dpb_size, 16);
|
||||
max_dpb_size = MIN (max_dpb_size, 16);
|
||||
|
||||
/* MaxDpbSize is not an actual maximum required buffer size.
|
||||
* Instead, it indicates upper bound for other syntax elements, such as
|
||||
* sps_max_dec_pic_buffering_minus1. If this bitstream can satisfy
|
||||
* the requirement, use this as our dpb size */
|
||||
if (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] + 1 <=
|
||||
max_dpb_size) {
|
||||
GST_DEBUG_OBJECT (self, "max_dec_pic_buffering_minus1 %d < MaxDpbSize %d",
|
||||
sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1],
|
||||
max_dpb_size);
|
||||
max_dpb_size =
|
||||
sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] + 1;
|
||||
} else {
|
||||
/* not reliable values, use 16 */
|
||||
max_dpb_size = 16;
|
||||
}
|
||||
|
||||
return max_dpb_size;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
@ -1793,12 +1820,28 @@ gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
/* TODO: According to 7.4.3.3.3, TwoVersionsOfCurrDecPicFlag
|
||||
* should be considered.
|
||||
*
|
||||
* NOTE: (See 8.1.3) if TwoVersionsOfCurrDecPicFlag is 1,
|
||||
* current picture requires two picture buffers allocated in DPB storage,
|
||||
* one is decoded picture *after* in-loop filter, and the other is
|
||||
* decoded picture *before* in-loop filter, so that current picture
|
||||
* can be used as a reference of the current picture
|
||||
* (e.g., intra block copy method in SCC).
|
||||
* Here TwoVersionsOfCurrDecPicFlag takes effect in order to ensure
|
||||
* at least two empty DPB buffer before starting current picture decoding.
|
||||
*
|
||||
* However, two DPB picture allocation is not implemented
|
||||
* in current baseclass (which would imply that we are doing reference
|
||||
* picture management wrongly in case of SCC).
|
||||
* Let's ignore TwoVersionsOfCurrDecPicFlag for now */
|
||||
guint max_dec_pic_buffering =
|
||||
sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] + 1;
|
||||
gst_h265_dpb_delete_unused (priv->dpb);
|
||||
while (gst_h265_dpb_needs_bump (priv->dpb,
|
||||
sps->max_num_reorder_pics[sps->max_sub_layers_minus1],
|
||||
priv->SpsMaxLatencyPictures,
|
||||
sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] +
|
||||
1)) {
|
||||
priv->SpsMaxLatencyPictures, max_dec_pic_buffering)) {
|
||||
to_output = gst_h265_dpb_bump (priv->dpb, FALSE);
|
||||
|
||||
/* Something wrong... */
|
||||
|
|
Loading…
Reference in a new issue