diff -urp gst-plugins-bad-1.20.1.orig/gst-libs/gst/codecparsers/gsth265parser.c gst-plugins-bad-1.20.1/gst-libs/gst/codecparsers/gsth265parser.c
--- gst-plugins-bad-1.20.1.orig/gst-libs/gst/codecparsers/gsth265parser.c	2025-05-19 14:00:55.919424249 -0500
+++ gst-plugins-bad-1.20.1/gst-libs/gst/codecparsers/gsth265parser.c	2025-05-19 14:08:53.013176690 -0500
@@ -72,6 +72,8 @@
 #include <string.h>
 #include <math.h>
 
+#define MAX_DPB_SIZE 16
+
 #ifndef GST_DISABLE_GST_DEBUG
 #define GST_CAT_DEFAULT gst_h265_debug_category_get()
 static GstDebugCategory *
@@ -1686,7 +1688,7 @@ gst_h265_parse_vps (GstH265NalUnit * nal
   for (i =
       (vps->sub_layer_ordering_info_present_flag ? 0 :
           vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
-    READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
+    READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], MAX_DPB_SIZE - 1);
     READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
         vps->max_dec_pic_buffering_minus1[i]);
     READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
@@ -1881,7 +1883,7 @@ gst_h265_parse_sps (GstH265Parser * pars
   for (i =
       (sps->sub_layer_ordering_info_present_flag ? 0 :
           sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
-    READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
+    READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], MAX_DPB_SIZE - 1);
     READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
         sps->max_dec_pic_buffering_minus1[i]);
     READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
@@ -2508,6 +2510,8 @@ gst_h265_parser_parse_slice_hdr (GstH265
       READ_UINT8 (&nr, slice->colour_plane_id, 2);
 
     if (!GST_H265_IS_NAL_TYPE_IDR (nalu->type)) {
+      const GstH265ShortTermRefPicSet *ref_pic_sets = NULL;
+
       READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
           (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
 
@@ -2520,21 +2524,53 @@ gst_h265_parser_parse_slice_hdr (GstH265
           goto error;
 
         slice->short_term_ref_pic_set_size = nal_reader_get_pos (&nr) - pos;
+
+        ref_pic_sets = &slice->short_term_ref_pic_sets;
       } else if (sps->num_short_term_ref_pic_sets > 1) {
         const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
         READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
         CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
             sps->num_short_term_ref_pic_sets - 1);
+        ref_pic_sets =
+            &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
+      } else {
+        ref_pic_sets = &sps->short_term_ref_pic_set[0];
       }
 
       if (sps->long_term_ref_pics_present_flag) {
         guint32 limit;
+        gint max_num_long_term_pics = 0;
+        gint TwoVersionsOfCurrDecPicFlag = 0;
 
-        if (sps->num_long_term_ref_pics_sps > 0)
+        if (sps->num_long_term_ref_pics_sps > 0) {
           READ_UE_MAX (&nr, slice->num_long_term_sps,
               sps->num_long_term_ref_pics_sps);
+        }
+
+        /* 7.4.3.3.3 */
+        if (pps->pps_scc_extension_flag &&
+            pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag &&
+            (sps->sample_adaptive_offset_enabled_flag ||
+                !pps->deblocking_filter_disabled_flag ||
+                pps->deblocking_filter_override_enabled_flag)) {
+          TwoVersionsOfCurrDecPicFlag = 1;
+        }
+
+        /* Calculated upper bound num_long_term_pics can have. 7.4.7.1 */
+        max_num_long_term_pics =
+            /* sps_max_dec_pic_buffering_minus1[TemporalId], allowed max is
+             * MaxDpbSize - 1 */
+            MAX_DPB_SIZE - 1
+            - (gint) slice->num_long_term_sps
+            - (gint) ref_pic_sets->NumNegativePics
+            - (gint) ref_pic_sets->NumPositivePics -
+            TwoVersionsOfCurrDecPicFlag;
+        if (max_num_long_term_pics < 0) {
+          GST_WARNING ("Invalid stream, too many reference pictures");
+          goto error;
+        }
 
-        READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
+        READ_UE_MAX (&nr, slice->num_long_term_pics, max_num_long_term_pics);
         limit = slice->num_long_term_sps + slice->num_long_term_pics;
         for (i = 0; i < limit; i++) {
           if (i < slice->num_long_term_sps) {
