av1parser: Fix segmentation params update
authorSeungha Yang <seungha@centricular.com>
Fri, 15 Sep 2023 18:13:33 +0000 (03:13 +0900)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 16 Sep 2023 00:37:26 +0000 (01:37 +0100)
Even if the segmentation feature value is not updated,
the parsed "segmentation_update_map" and "segmentation_temporal_update"
values should not be cleared as it's referenced during lower
level bitstream parsing. Also, don't use assert() in parser
unless it's clearly impossible condition.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5336>

subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstav1parser.c

index 22ffefd16861d338ba0235f3fd84f543852a8176..9fda4fbb58c5e253bbe5f334cb1ba9fa2fec7f1e 100644 (file)
@@ -2129,20 +2129,37 @@ gst_av1_parse_segmentation_params (GstAV1Parser * parser, GstBitReader * br,
         }
       }
     } else {
+      gint8 ref_idx;
+      GstAV1SegmenationParams *ref_seg_params;
+
       /* Copy it from prime_ref */
-      g_assert (frame_header->primary_ref_frame != GST_AV1_PRIMARY_REF_NONE);
-      g_assert (parser->state.ref_info.
-          entry[frame_header->ref_frame_idx[frame_header->primary_ref_frame]].
-          ref_valid);
-      memcpy (seg_params,
-          &parser->state.ref_info.
-          entry[frame_header->ref_frame_idx[frame_header->
-                  primary_ref_frame]].ref_segmentation_params,
-          sizeof (GstAV1SegmenationParams));
-
-      seg_params->segmentation_update_map = 0;
-      seg_params->segmentation_temporal_update = 0;
-      seg_params->segmentation_update_data = 0;
+      if (frame_header->primary_ref_frame >= GST_AV1_PRIMARY_REF_NONE) {
+        GST_WARNING ("Invalid primary_ref_frame %d",
+            frame_header->primary_ref_frame);
+        return GST_AV1_PARSER_BITSTREAM_ERROR;
+      }
+
+      ref_idx = frame_header->ref_frame_idx[frame_header->primary_ref_frame];
+      if (ref_idx >= GST_AV1_NUM_REF_FRAMES || ref_idx < 0) {
+        GST_WARNING ("Invalid ref_frame_idx %d", ref_idx);
+        return GST_AV1_PARSER_BITSTREAM_ERROR;
+      }
+
+      if (!parser->state.ref_info.entry[ref_idx].ref_valid) {
+        GST_WARNING ("Reference frame at index %d is unavailable", ref_idx);
+        return GST_AV1_PARSER_BITSTREAM_ERROR;
+      }
+
+      ref_seg_params =
+          &parser->state.ref_info.entry[ref_idx].ref_segmentation_params;
+
+      for (i = 0; i < GST_AV1_MAX_SEGMENTS; i++) {
+        for (j = 0; j < GST_AV1_SEG_LVL_MAX; j++) {
+          seg_params->feature_enabled[i][j] =
+              ref_seg_params->feature_enabled[i][j];
+          seg_params->feature_data[i][j] = ref_seg_params->feature_data[i][j];
+        }
+      }
     }
   } else {
     seg_params->segmentation_update_map = 0;