nvh265sldec: Sync up with d3d11h265dec implementation

Each RefPicSetStCurrBefore/RefPicSetStCurrAfter/RefPicSetLtCurr array
might have empty element (i.e., reference pictures might not be stored
sequentially). Don't error out for the empty element case,
but instead, iterates each array and fill NVDEC's reference list
as much as possible

Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1441
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3039>
This commit is contained in:
Seungha Yang 2022-09-17 05:01:55 +09:00 committed by GStreamer Marge Bot
parent f4260ecdc5
commit b6ca76eb68

View file

@ -725,7 +725,7 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
GstNvDecoderFrame *frame; GstNvDecoderFrame *frame;
GArray *dpb_array; GArray *dpb_array;
gint num_ref_pic; gint num_ref_pic;
gint i, j; gint i, j, k;
const GstH265ScalingList *scaling_list = NULL; const GstH265ScalingList *scaling_list = NULL;
/* both NVDEC and h265parser are using the same order */ /* both NVDEC and h265parser are using the same order */
@ -819,7 +819,6 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
} }
other_frame = gst_nv_h265_dec_get_decoder_frame_from_picture (self, other); other_frame = gst_nv_h265_dec_get_decoder_frame_from_picture (self, other);
if (other_frame) if (other_frame)
picture_index = other_frame->index; picture_index = other_frame->index;
@ -829,62 +828,52 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
num_ref_pic++; num_ref_pic++;
} }
g_array_unref (dpb_array); g_array_unref (dpb_array);
for (i = num_ref_pic; i < G_N_ELEMENTS (h265_params->RefPicIdx); i++) for (i = 0, j = 0; i < num_ref_pic; i++) {
h265_params->RefPicIdx[i] = -1; GstH265Picture *other = NULL;
for (i = 0; i < decoder->NumPocStCurrBefore; i++) { while (!other && j < decoder->NumPocStCurrBefore)
GstH265Picture *other; other = decoder->RefPicSetStCurrBefore[j++];
if (!decoder->RefPicSetStCurrBefore[i]) { if (other) {
GST_ERROR_OBJECT (self, "Empty RefPicSetStCurrBefore[%d]", i); for (k = 0; k < num_ref_pic; k++) {
return GST_FLOW_ERROR; if (h265_params->PicOrderCntVal[k] == other->pic_order_cnt) {
} h265_params->RefPicSetStCurrBefore[i] = k;
break;
other = decoder->RefPicSetStCurrBefore[i]; }
for (j = 0; j < num_ref_pic; j++) {
if (h265_params->PicOrderCntVal[j] == other->pic_order_cnt) {
h265_params->RefPicSetStCurrBefore[i] = j;
break;
} }
} }
} }
for (i = 0; i < decoder->NumPocStCurrAfter; i++) { for (i = 0, j = 0; i < num_ref_pic; i++) {
GstH265Picture *other; GstH265Picture *other = NULL;
if (!decoder->RefPicSetStCurrAfter[i]) { while (!other && j < decoder->NumPocStCurrAfter)
GST_ERROR_OBJECT (self, "Empty RefPicSetStCurrAfter[%d]", i); other = decoder->RefPicSetStCurrAfter[j++];
return GST_FLOW_ERROR;
}
other = decoder->RefPicSetStCurrAfter[i]; if (other) {
for (k = 0; k < num_ref_pic; k++) {
for (j = 0; j < num_ref_pic; j++) { if (h265_params->PicOrderCntVal[k] == other->pic_order_cnt) {
if (h265_params->PicOrderCntVal[j] == other->pic_order_cnt) { h265_params->RefPicSetStCurrAfter[i] = k;
h265_params->RefPicSetStCurrAfter[i] = j; break;
break; }
} }
} }
} }
for (i = 0; i < decoder->NumPocLtCurr; i++) { for (i = 0, j = 0; i < num_ref_pic; i++) {
GstH265Picture *other; GstH265Picture *other = NULL;
if (!decoder->RefPicSetLtCurr[i]) { while (!other && j < decoder->NumPocLtCurr)
GST_ERROR_OBJECT (self, "Empty RefPicSetLtCurr[%d]", i); other = decoder->RefPicSetLtCurr[j++];
return GST_FLOW_ERROR;
}
other = decoder->RefPicSetLtCurr[i]; if (other) {
for (k = 0; k < num_ref_pic; k++) {
for (j = 0; j < num_ref_pic; j++) { if (h265_params->PicOrderCntVal[k] == other->pic_order_cnt) {
if (h265_params->PicOrderCntVal[j] == other->pic_order_cnt) { h265_params->RefPicSetLtCurr[i] = k;
h265_params->RefPicSetLtCurr[i] = j; break;
break; }
} }
} }
} }