summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHe Junyan <junyan.he@hotmail.com>2020-05-13 16:05:59 +0800
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2020-06-05 09:51:19 +0000
commit5f92699a4b6057deeaf1d824e6c8363de3832a88 (patch)
tree5d44fdb978503017d1aec5c2e92052558b1653ea
parentc956d91807958195aca59a9be203e58ded49dfdf (diff)
libs: decoder: update reference list for SCC.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/311>
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder_h265.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c
index f6be666e..015c870e 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c
@@ -1345,7 +1345,21 @@ decode_current_picture (GstVaapiDecoderH265 * decoder)
priv->decoder_state |= sps_pi->state;
if (!(priv->decoder_state & GST_H265_VIDEO_STATE_GOT_I_FRAME)) {
- if (priv->decoder_state & GST_H265_VIDEO_STATE_GOT_P_SLICE)
+ const GstH265PPS *pps = get_pps (decoder);
+ /* 7.4.3.3.3: the picture is an IRAP picture, nuh_layer_id is equal to 0,
+ and pps_curr_pic_ref_enabled_flag is equal to 0, slice_type shall be
+ equal to 2(I Slice).
+ And F.8.3.4: Decoding process for reference picture lists construction
+ is invoked at the beginning of the decoding process for each P or B
+ slice.
+ so if pps_curr_pic_ref_enabled_flag is set, which means the picture can
+ ref to itself, the IRAP picture may be set to P/B slice, in order to
+ generate the ref lists. If the slice_type is I, no ref list will be
+ constructed and no MV data for that slice according to the syntax.
+ That kind of CVS may start with P/B slice, but in fact it is a intra
+ frame. */
+ if (priv->decoder_state & GST_H265_VIDEO_STATE_GOT_P_SLICE &&
+ !pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag)
goto drop_frame;
sps_pi->state |= GST_H265_VIDEO_STATE_GOT_I_FRAME;
}
@@ -1670,6 +1684,7 @@ init_picture_refs (GstVaapiDecoderH265 * decoder,
guint num_ref_idx_l0_active_minus1 = 0;
guint num_ref_idx_l1_active_minus1 = 0;
GstH265RefPicListModification *ref_pic_list_modification;
+ GstH265PPS *const pps = get_pps (decoder);
guint type;
memset (priv->RefPicList0, 0, sizeof (GstVaapiPictureH265 *) * 16);
@@ -1702,6 +1717,8 @@ init_picture_refs (GstVaapiDecoderH265 * decoder,
for (i = 0; i < priv->NumPocLtCurr && rIdx < NumRpsCurrTempList0;
rIdx++, i++)
RefPicListTemp0[rIdx] = priv->RefPicSetLtCurr[i];
+ if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag)
+ RefPicListTemp0[rIdx++] = picture;
}
/* construct RefPicList0 (8-9) */
@@ -1710,6 +1727,10 @@ init_picture_refs (GstVaapiDecoderH265 * decoder,
ref_pic_list_modification->ref_pic_list_modification_flag_l0 ?
RefPicListTemp0[ref_pic_list_modification->list_entry_l0[rIdx]] :
RefPicListTemp0[rIdx];
+ if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag
+ && !ref_pic_list_modification->ref_pic_list_modification_flag_l0
+ && (NumRpsCurrTempList0 > num_ref_idx_l0_active_minus1 + 1))
+ priv->RefPicList0[rIdx++] = picture;
priv->RefPicList0_count = rIdx;
if (type == GST_H265_B_SLICE) {
@@ -1726,6 +1747,8 @@ init_picture_refs (GstVaapiDecoderH265 * decoder,
for (i = 0; i < priv->NumPocLtCurr && rIdx < NumRpsCurrTempList1;
rIdx++, i++)
RefPicListTemp1[rIdx] = priv->RefPicSetLtCurr[i];
+ if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag)
+ RefPicListTemp1[rIdx++] = picture;
}
/* construct RefPicList1 (8-10) */
@@ -1898,6 +1921,17 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture)
if (n >= G_N_ELEMENTS (pic_param->ReferenceFrames))
break;
}
+ /* 7.4.3.3.3, the current decoded picture is marked as "used for
+ long-term reference", no matter TwoVersionsOfCurrDecPicFlag */
+ if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag
+ && n < G_N_ELEMENTS (pic_param->ReferenceFrames) - 1) {
+ gst_vaapi_picture_h265_set_reference (picture,
+ GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
+ vaapi_fill_picture (&pic_param->ReferenceFrames[n++], picture,
+ picture->structure);
+ gst_vaapi_picture_h265_set_reference (picture, 0);
+ }
+
for (; n < G_N_ELEMENTS (pic_param->ReferenceFrames); n++)
vaapi_init_picture (&pic_param->ReferenceFrames[n]);
@@ -2277,6 +2311,7 @@ decode_ref_pic_set (GstVaapiDecoderH265 * decoder,
GstVaapiDecoderH265Private *const priv = &decoder->priv;
GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
GstH265SPS *const sps = get_sps (decoder);
+ GstH265PPS *const pps = get_pps (decoder);
const gint32 MaxPicOrderCntLsb =
1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
@@ -2297,6 +2332,7 @@ decode_ref_pic_set (GstVaapiDecoderH265 * decoder,
memset (priv->PocLtFoll, 0, sizeof (guint) * 16);
priv->NumPocStCurrBefore = priv->NumPocStCurrAfter = priv->NumPocStFoll = 0;
priv->NumPocLtCurr = priv->NumPocLtFoll = 0;
+ priv->NumPocTotalCurr = 0;
} else {
GstH265ShortTermRefPicSet *stRefPic = NULL;
gint32 num_lt_pics, pocLt;
@@ -2346,6 +2382,8 @@ decode_ref_pic_set (GstVaapiDecoderH265 * decoder,
numtotalcurr++;
}
+ if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag)
+ numtotalcurr++;
priv->NumPocTotalCurr = numtotalcurr;
/* The variable DeltaPocMsbCycleLt[i] is derived as follows: (7-38) */