nvh265sldec: Sync up with d3d11h265dec implementation
authorSeungha Yang <seungha@centricular.com>
Fri, 16 Sep 2022 20:01:55 +0000 (05:01 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 16 Sep 2022 20:25:23 +0000 (20:25 +0000)
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>

subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.c

index 2770db9..6f594ba 100644 (file)
@@ -725,7 +725,7 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
   GstNvDecoderFrame *frame;
   GArray *dpb_array;
   gint num_ref_pic;
-  gint i, j;
+  gint i, j, k;
   const GstH265ScalingList *scaling_list = NULL;
 
   /* 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);
-
     if (other_frame)
       picture_index = other_frame->index;
 
@@ -829,62 +828,52 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
 
     num_ref_pic++;
   }
-
   g_array_unref (dpb_array);
 
-  for (i = num_ref_pic; i < G_N_ELEMENTS (h265_params->RefPicIdx); i++)
-    h265_params->RefPicIdx[i] = -1;
-
-  for (i = 0; i < decoder->NumPocStCurrBefore; i++) {
-    GstH265Picture *other;
-
-    if (!decoder->RefPicSetStCurrBefore[i]) {
-      GST_ERROR_OBJECT (self, "Empty RefPicSetStCurrBefore[%d]", i);
-      return GST_FLOW_ERROR;
-    }
+  for (i = 0, j = 0; i < num_ref_pic; i++) {
+    GstH265Picture *other = NULL;
 
-    other = decoder->RefPicSetStCurrBefore[i];
+    while (!other && j < decoder->NumPocStCurrBefore)
+      other = decoder->RefPicSetStCurrBefore[j++];
 
-    for (j = 0; j < num_ref_pic; j++) {
-      if (h265_params->PicOrderCntVal[j] == other->pic_order_cnt) {
-        h265_params->RefPicSetStCurrBefore[i] = j;
-        break;
+    if (other) {
+      for (k = 0; k < num_ref_pic; k++) {
+        if (h265_params->PicOrderCntVal[k] == other->pic_order_cnt) {
+          h265_params->RefPicSetStCurrBefore[i] = k;
+          break;
+        }
       }
     }
   }
 
-  for (i = 0; i < decoder->NumPocStCurrAfter; i++) {
-    GstH265Picture *other;
+  for (i = 0, j = 0; i < num_ref_pic; i++) {
+    GstH265Picture *other = NULL;
 
-    if (!decoder->RefPicSetStCurrAfter[i]) {
-      GST_ERROR_OBJECT (self, "Empty RefPicSetStCurrAfter[%d]", i);
-      return GST_FLOW_ERROR;
-    }
-
-    other = decoder->RefPicSetStCurrAfter[i];
+    while (!other && j < decoder->NumPocStCurrAfter)
+      other = decoder->RefPicSetStCurrAfter[j++];
 
-    for (j = 0; j < num_ref_pic; j++) {
-      if (h265_params->PicOrderCntVal[j] == other->pic_order_cnt) {
-        h265_params->RefPicSetStCurrAfter[i] = j;
-        break;
+    if (other) {
+      for (k = 0; k < num_ref_pic; k++) {
+        if (h265_params->PicOrderCntVal[k] == other->pic_order_cnt) {
+          h265_params->RefPicSetStCurrAfter[i] = k;
+          break;
+        }
       }
     }
   }
 
-  for (i = 0; i < decoder->NumPocLtCurr; i++) {
-    GstH265Picture *other;
-
-    if (!decoder->RefPicSetLtCurr[i]) {
-      GST_ERROR_OBJECT (self, "Empty RefPicSetLtCurr[%d]", i);
-      return GST_FLOW_ERROR;
-    }
+  for (i = 0, j = 0; i < num_ref_pic; i++) {
+    GstH265Picture *other = NULL;
 
-    other = decoder->RefPicSetLtCurr[i];
+    while (!other && j < decoder->NumPocLtCurr)
+      other = decoder->RefPicSetLtCurr[j++];
 
-    for (j = 0; j < num_ref_pic; j++) {
-      if (h265_params->PicOrderCntVal[j] == other->pic_order_cnt) {
-        h265_params->RefPicSetLtCurr[i] = j;
-        break;
+    if (other) {
+      for (k = 0; k < num_ref_pic; k++) {
+        if (h265_params->PicOrderCntVal[k] == other->pic_order_cnt) {
+          h265_params->RefPicSetLtCurr[i] = k;
+          break;
+        }
       }
     }
   }