diff options
author | He Junyan <junyan.he@hotmail.com> | 2020-05-13 16:05:59 +0800 |
---|---|---|
committer | GStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2020-06-05 09:51:19 +0000 |
commit | 5f92699a4b6057deeaf1d824e6c8363de3832a88 (patch) | |
tree | 5d44fdb978503017d1aec5c2e92052558b1653ea | |
parent | c956d91807958195aca59a9be203e58ded49dfdf (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.c | 40 |
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) */ |