Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package gstreamer-plugins-good for 
openSUSE:Factory checked in at 2026-08-06 16:19:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gstreamer-plugins-good (Old)
 and      /work/SRC/openSUSE:Factory/.gstreamer-plugins-good.new.16738 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gstreamer-plugins-good"

Thu Aug  6 16:19:20 2026 rev:133 rq:1369819 version:1.28.6

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/gstreamer-plugins-good/gstreamer-plugins-good.changes
    2026-07-12 16:21:30.480718762 +0200
+++ 
/work/SRC/openSUSE:Factory/.gstreamer-plugins-good.new.16738/gstreamer-plugins-good.changes
 2026-08-06 16:19:42.619229640 +0200
@@ -1,0 +2,19 @@
+Wed Aug  5 15:57:08 UTC 2026 - Bjørn Lie <[email protected]>
+
+- Update to version 1.28.6:
+  + aacparse: Don't assert on parsing errors or insufficient data
+  + avidemux: Make sure enough data is available when parsing
+    FUJIFILM strd and various other fixes
+  + matroskademux: Make sure enough data is available when parsing
+    FLAC headers
+  + rtph264depay: rtph265depay: Limit the maximum fragmentation
+    unit size
+  + rtpqcelpdepay: Handle changes in interleave value correctly
+  + rtpsource: fix bitrate estimation for RTX
+  + v4l2: Use MPLANE flag to determine n_v4l_planes directly
+  + y4mdec: Some parsing fixes
+  + tests: qtmux: drain to EOS before teardown in test_caps_renego
+  + Remove incorrect G_GNUC_CONST annotation for _get_type()
+    functions and some other functions
+
+-------------------------------------------------------------------

Old:
----
  gst-plugins-good-1.28.5.obscpio

New:
----
  gst-plugins-good-1.28.6.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ gstreamer-plugins-good.spec ++++++
--- /var/tmp/diff_new_pack.CA7I8Y/_old  2026-08-06 16:19:43.359255458 +0200
+++ /var/tmp/diff_new_pack.CA7I8Y/_new  2026-08-06 16:19:43.363255597 +0200
@@ -33,7 +33,7 @@
 %endif
 
 Name:           gstreamer-plugins-good
-Version:        1.28.5
+Version:        1.28.6
 Release:        0
 Summary:        GStreamer Streaming-Media Framework Plug-Ins
 License:        LGPL-2.1-or-later

++++++ _service ++++++
--- /var/tmp/diff_new_pack.CA7I8Y/_old  2026-08-06 16:19:43.399256853 +0200
+++ /var/tmp/diff_new_pack.CA7I8Y/_new  2026-08-06 16:19:43.399256853 +0200
@@ -5,7 +5,7 @@
     <param 
name="url">https://gitlab.freedesktop.org/gstreamer/gstreamer.git</param>
     <param name="subdir">subprojects/gst-plugins-good</param>
     <param name="filename">gst-plugins-good</param>
-    <param name="revision">1.28.5</param>
+    <param name="revision">1.28.6</param>
     <param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param>
     <param name="versionrewrite-pattern">v?(.*)\+0</param>
     <param name="versionrewrite-replacement">\1</param>

++++++ gst-plugins-good-1.28.5.obscpio -> gst-plugins-good-1.28.6.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/docs/gst_plugins_cache.json 
new/gst-plugins-good-1.28.6/docs/gst_plugins_cache.json
--- old/gst-plugins-good-1.28.5/docs/gst_plugins_cache.json     2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/docs/gst_plugins_cache.json     2026-08-05 
13:59:39.000000000 +0200
@@ -15760,6 +15760,20 @@
                     }
                 },
                 "properties": {
+                    "max-fragmentation-unit-size": {
+                        "blurb": "Maximum size in bytes for a fragmentation 
unit (0 = auto)",
+                        "conditionally-available": false,
+                        "construct": false,
+                        "construct-only": false,
+                        "controllable": false,
+                        "default": "33554432",
+                        "max": "-1",
+                        "min": "0",
+                        "mutable": "null",
+                        "readable": true,
+                        "type": "guint",
+                        "writable": true
+                    },
                     "request-keyframe": {
                         "blurb": "Request new keyframe when packet loss is 
detected",
                         "conditionally-available": false,
@@ -15880,6 +15894,20 @@
                     }
                 },
                 "properties": {
+                    "max-fragmentation-unit-size": {
+                        "blurb": "Maximum size in bytes for a fragmentation 
unit (0 = auto)",
+                        "conditionally-available": false,
+                        "construct": false,
+                        "construct-only": false,
+                        "controllable": false,
+                        "default": "33554432",
+                        "max": "-1",
+                        "min": "0",
+                        "mutable": "null",
+                        "readable": true,
+                        "type": "guint",
+                        "writable": true
+                    },
                     "request-keyframe": {
                         "blurb": "Request new keyframe when packet loss is 
detected",
                         "conditionally-available": false,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-good-1.28.5/ext/gdk_pixbuf/gstgdkanimation.h 
new/gst-plugins-good-1.28.6/ext/gdk_pixbuf/gstgdkanimation.h
--- old/gst-plugins-good-1.28.5/ext/gdk_pixbuf/gstgdkanimation.h        
2026-07-08 23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/ext/gdk_pixbuf/gstgdkanimation.h        
2026-08-05 13:59:39.000000000 +0200
@@ -110,7 +110,7 @@
   GdkPixbufAnimationIterClass   parent_class;
 };
 
-GType gst_gdk_animation_iter_get_type (void) G_GNUC_CONST;
+GType gst_gdk_animation_iter_get_type (void);
 
 G_END_DECLS
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-good-1.28.5/gst/audioparsers/gstaacparse.c 
new/gst-plugins-good-1.28.6/gst/audioparsers/gstaacparse.c
--- old/gst-plugins-good-1.28.5/gst/audioparsers/gstaacparse.c  2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/audioparsers/gstaacparse.c  2026-08-05 
13:59:39.000000000 +0200
@@ -963,11 +963,13 @@
   return FALSE;
 }
 
-/* caller ensure sufficient data */
-static inline void
+static inline gboolean
 gst_aac_parse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
-    gint * rate, gint * channels, gint * object, gint * version)
+    const guint avail, gint * rate, gint * channels, gint * object,
+    gint * version)
 {
+  if (avail < 4)
+    return FALSE;
 
   if (rate) {
     gint sr_idx = (data[2] & 0x3c) >> 2;
@@ -984,6 +986,8 @@
     *version = (data[1] & 0x08) ? 2 : 4;
   if (object)
     *object = ((data[2] & 0xc0) >> 6) + 1;
+
+  return TRUE;
 }
 
 /**
@@ -1054,8 +1058,12 @@
 
     GST_INFO ("ADTS ID: %d, framesize: %d", (data[1] & 0x08) >> 3, *framesize);
 
-    gst_aac_parse_parse_adts_header (aacparse, data, &rate, &channels,
-        &aacparse->object_type, &aacparse->mpegversion);
+    if (!gst_aac_parse_parse_adts_header (aacparse, data, avail, &rate,
+            &channels, &aacparse->object_type, &aacparse->mpegversion)) {
+      GST_DEBUG_OBJECT (aacparse,
+          "impossible ADTS configuration or not enough data");
+      return FALSE;
+    }
 
     if (!channels || !framesize) {
       GST_DEBUG_OBJECT (aacparse, "impossible ADTS configuration");
@@ -1484,8 +1492,17 @@
     /* see above */
     frame->overhead = 7;
 
-    gst_aac_parse_parse_adts_header (aacparse, map.data,
-        &rate, &channels, NULL, NULL);
+    if (!gst_aac_parse_parse_adts_header (aacparse, map.data, map.size,
+            &rate, &channels, NULL, NULL)) {
+      /* This is pretty normal when skipping data at the start of
+       * random stream (MPEG-TS capture for example) */
+      GST_DEBUG_OBJECT (aacparse, "Error reading ADTS header. Skipping.");
+      /* Since we don't fully parsed the ADTS header, we don't know for sure
+       * how much to skip. Just skip 1 to end up to the next marker and
+       * resume parsing from there */
+      *skipsize = 1;
+      goto exit;
+    }
 
     GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/avi/gstavidemux.c 
new/gst-plugins-good-1.28.6/gst/avi/gstavidemux.c
--- old/gst-plugins-good-1.28.5/gst/avi/gstavidemux.c   2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/avi/gstavidemux.c   2026-08-05 
13:59:39.000000000 +0200
@@ -127,7 +127,7 @@
 static void gst_avi_demux_parse_strd (GstAviDemux * avi, GstBuffer * buf);
 
 static void parse_tag_value (GstAviDemux * avi, GstTagList * taglist,
-    const gchar * type, guint8 * ptr, guint tsize);
+    const gchar * type, const guint8 * ptr, guint tsize);
 
 /* GObject methods */
 
@@ -1241,7 +1241,7 @@
     GstBuffer * buf, guint64 ** _indexes)
 {
   GstMapInfo map;
-  guint8 *data;
+  const guint8 *data;
   guint16 bpe = 16;
   guint32 num, i;
   guint64 *indexes;
@@ -1283,8 +1283,13 @@
 
   indexes = g_new (guint64, num + 1);
   for (i = 0; i < num; i++) {
-    if (size < 24 + bpe * (i + 1))
+    gsize required_size;
+
+    if (!g_size_checked_mul (&required_size, bpe, i + 1))
       break;
+    if (size - 24 < required_size)
+      break;
+
     indexes[i] = GST_READ_UINT64_LE (&data[24 + bpe * i]);
     GST_DEBUG_OBJECT (avi, "index %d at %" G_GUINT64_FORMAT, i, indexes[i]);
   }
@@ -1529,7 +1534,7 @@
     GstBuffer * buf)
 {
   GstMapInfo map;
-  guint8 *data;
+  const guint8 *data;
   guint16 bpe;
   guint32 num, i;
   guint64 baseoff;
@@ -1567,12 +1572,19 @@
   if (num == 0)
     goto empty_index;
 
+  /* this can't work out well ... */
+  if (num > G_MAXUINT32 >> 1)
+    goto invalid_params;
+
   GST_INFO_OBJECT (avi, "Parsing subindex, nr_entries = %6d", num);
 
   for (i = 0; i < num; i++) {
     GstAviIndexEntry entry;
+    gsize required_size;
 
-    if (map.size < 24 + bpe * (i + 1))
+    if (!g_size_checked_mul (&required_size, bpe, i + 1))
+      break;
+    if (map.size - 24 < required_size)
       break;
 
     /* fill in offset and size. offset contains the keyframe flag in the
@@ -1615,6 +1627,11 @@
     gst_buffer_unref (buf);
     return FALSE;
   }
+invalid_params:
+  {
+    GST_ERROR_OBJECT (avi, "invalid subindex parameters (num = %d)", num);
+    goto done;                  /* continue */
+  }
 empty_index:
   {
     GST_DEBUG_OBJECT (avi, "the index is empty");
@@ -1814,7 +1831,8 @@
 
   /* size checking */
   /* calculate fields based on size */
-  k = (size - G_STRUCT_OFFSET (gst_riff_vprp, field_info)) / vprp->fields;
+  k = (size - G_STRUCT_OFFSET (gst_riff_vprp,
+          field_info)) / sizeof (vprp->field_info[0]);
   if (vprp->fields > k) {
     GST_WARNING_OBJECT (element,
         "vprp header indicated %d fields, only %d available", vprp->fields, k);
@@ -1980,7 +1998,7 @@
     /* some muxers put invalid bytestream stuff in h264 extra data */
     val = gst_structure_get_value (s, "codec_data");
     if (val && (buf = gst_value_get_buffer (val))) {
-      guint8 *data;
+      const guint8 *data;
       gint size;
       GstMapInfo map;
 
@@ -2743,7 +2761,7 @@
 {
   GstMapInfo map;
   guint i, num, n;
-  gst_riff_index_entry *index;
+  const gst_riff_index_entry *index;
   GstClockTime stamp;
   GstAviStream *stream;
   GstAviIndexEntry entry;
@@ -3727,7 +3745,7 @@
 gst_avi_demux_parse_idit (GstAviDemux * avi, GstBuffer * buf)
 {
   GstMapInfo map;
-  gchar *ptr;
+  const gchar *ptr;
   gsize left;
   gchar *safedata = NULL;
 
@@ -3745,7 +3763,7 @@
    */
 
   /* skip eventual initial whitespace */
-  ptr = (gchar *) map.data;
+  ptr = (const gchar *) map.data;
   left = map.size;
 
   while (left > 0 && g_ascii_isspace (ptr[0])) {
@@ -3782,7 +3800,7 @@
 
 static void
 parse_tag_value (GstAviDemux * avi, GstTagList * taglist, const gchar * type,
-    guint8 * ptr, guint tsize)
+    const guint8 * ptr, guint tsize)
 {
   static const gchar *env_vars[] = { "GST_AVI_TAG_ENCODING",
     "GST_RIFF_TAG_ENCODING", "GST_TAG_ENCODING", NULL
@@ -3822,7 +3840,7 @@
 
   gst_buffer_map (buf, &map, GST_MAP_READ);
   if (map.size > 4) {
-    guint8 *ptr = map.data;
+    const guint8 *ptr = map.data;
     gsize left = map.size;
 
     /* parsing based on
@@ -3834,13 +3852,13 @@
 
       ptr += 98;
       left -= 98;
-      if (!memcmp (ptr, "FUJIFILM", 8)) {
+      if (left >= 10 && !memcmp (ptr, "FUJIFILM", 8)) {
         GST_MEMDUMP_OBJECT (avi, "fujifim tag", ptr, 48);
 
         ptr += 10;
         left -= 10;
         sub_size = 0;
-        while (ptr[sub_size] && sub_size < left)
+        while (sub_size < left && ptr[sub_size])
           sub_size++;
 
         if (avi->globaltags == NULL)
@@ -3851,21 +3869,28 @@
         parse_tag_value (avi, avi->globaltags, GST_TAG_DEVICE_MODEL, ptr,
             sub_size);
 
-        while (ptr[sub_size] == '\0' && sub_size < left)
+        while (sub_size < left && ptr[sub_size] == '\0')
           sub_size++;
 
         ptr += sub_size;
         left -= sub_size;
         sub_size = 0;
-        while (ptr[sub_size] && sub_size < left)
+        while (sub_size < left && ptr[sub_size])
           sub_size++;
-        if (ptr[4] == ':')
-          ptr[4] = '-';
-        if (ptr[7] == ':')
-          ptr[7] = '-';
 
-        parse_tag_value (avi, avi->globaltags, GST_TAG_DATE_TIME, ptr,
-            sub_size);
+        if (sub_size >= 8) {
+          guint8 *ptr_dup = g_memdup2 (ptr, sub_size);
+
+          if (ptr_dup[4] == ':')
+            ptr_dup[4] = '-';
+          if (ptr_dup[7] == ':')
+            ptr_dup[7] = '-';
+
+          parse_tag_value (avi, avi->globaltags, GST_TAG_DATE_TIME, ptr_dup,
+              sub_size);
+
+          g_free (ptr_dup);
+        }
       }
     }
   }
@@ -3887,7 +3912,7 @@
     GstTagList ** _taglist)
 {
   GstMapInfo info;
-  guint8 *ptr;
+  const guint8 *ptr;
   gsize left;
   guint tsize;
   guint32 tag;
@@ -3956,19 +3981,32 @@
               type = GST_TAG_ENCODER;
               break;
             case 0x13:         /* CreationDate */
-              type = GST_TAG_DATE_TIME;
-              if (left > 7) {
-                if (ptr[4] == ':')
-                  ptr[4] = '-';
-                if (ptr[7] == ':')
-                  ptr[7] = '-';
+            {
+              type = NULL;
+
+              if (left > 7 && ptr[0] != '\0') {
+                guint8 *ptr_dup = g_memdup2 (ptr, sub_size);
+
+                if (ptr_dup[4] == ':')
+                  ptr_dup[4] = '-';
+                if (ptr_dup[7] == ':')
+                  ptr_dup[7] = '-';
+
+                GST_DEBUG_OBJECT (avi, "mapped tag %u to tag %s", sub_tag,
+                    GST_TAG_DATE_TIME);
+
+                parse_tag_value (avi, taglist, GST_TAG_DATE_TIME, ptr_dup,
+                    sub_size);
+
+                g_free (ptr_dup);
               }
               break;
+            }
             default:
               type = NULL;
               break;
           }
-          if (type != NULL && ptr[0] != '\0') {
+          if (type != NULL && left > 0 && ptr[0] != '\0') {
             GST_DEBUG_OBJECT (avi, "mapped tag %u to tag %s", sub_tag, type);
 
             parse_tag_value (avi, taglist, type, ptr, sub_size);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/matroska/matroska-ids.c 
new/gst-plugins-good-1.28.6/gst/matroska/matroska-ids.c
--- old/gst-plugins-good-1.28.5/gst/matroska/matroska-ids.c     2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/matroska/matroska-ids.c     2026-08-05 
13:59:39.000000000 +0200
@@ -275,8 +275,9 @@
 {
   GstBufferList *list = NULL;
   GstBuffer *hdr;
-  guint8 *pdata = codec_data;
-  guint len, off;
+  const guint8 *pdata = codec_data;
+  gsize off;
+  guint len;
 
   GST_MEMDUMP ("flac codec data", codec_data, codec_data_size);
 
@@ -299,14 +300,14 @@
   /* skip fLaC marker */
   off = 4;
 
-  while (off < codec_data_size - 3) {
+  while (off < codec_data_size - 4) {
     len = GST_READ_UINT8 (pdata + off + 1) << 16;
     len |= GST_READ_UINT8 (pdata + off + 2) << 8;
     len |= GST_READ_UINT8 (pdata + off + 3);
 
     GST_DEBUG ("header packet: len=%u bytes, flags=0x%02x", len, pdata[off]);
 
-    if (off + len > codec_data_size) {
+    if (len > codec_data_size - 4 || off + len > codec_data_size - 4) {
       gst_buffer_list_unref (list);
       return NULL;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/rtp/gstrtph264depay.c 
new/gst-plugins-good-1.28.6/gst/rtp/gstrtph264depay.c
--- old/gst-plugins-good-1.28.5/gst/rtp/gstrtph264depay.c       2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/rtp/gstrtph264depay.c       2026-08-05 
13:59:39.000000000 +0200
@@ -41,12 +41,14 @@
 #define DEFAULT_ACCESS_UNIT   FALSE
 #define DEFAULT_WAIT_FOR_KEYFRAME FALSE
 #define DEFAULT_REQUEST_KEYFRAME FALSE
+#define DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE (32 * 1024 * 1024)
 
 enum
 {
   PROP_0,
   PROP_WAIT_FOR_KEYFRAME,
   PROP_REQUEST_KEYFRAME,
+  PROP_MAX_FRAGMENTATION_UNIT_SIZE,
 };
 
 
@@ -126,6 +128,9 @@
     case PROP_REQUEST_KEYFRAME:
       self->request_keyframe = g_value_get_boolean (value);
       break;
+    case PROP_MAX_FRAGMENTATION_UNIT_SIZE:
+      self->max_fragmentation_unit_size = g_value_get_uint (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -145,6 +150,9 @@
     case PROP_REQUEST_KEYFRAME:
       g_value_set_boolean (value, self->request_keyframe);
       break;
+    case PROP_MAX_FRAGMENTATION_UNIT_SIZE:
+      g_value_set_uint (value, self->max_fragmentation_unit_size);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -195,6 +203,24 @@
           DEFAULT_REQUEST_KEYFRAME,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstRtpH264Depay:max-fragmentation-unit-size:
+   *
+   * Maximum size in bytes for a fragmentation unit. Larger units
+   * will be dropped to prevent excessive memory usage.
+   *
+   * Use 0 for automatic.
+   *
+   * Since: 1.28.6
+   */
+  g_object_class_install_property (gobject_class,
+      PROP_MAX_FRAGMENTATION_UNIT_SIZE,
+      g_param_spec_uint ("max-fragmentation-unit-size",
+          "Max Fragmentation Unit Size",
+          "Maximum size in bytes for a fragmentation unit (0 = auto)", 0,
+          G_MAXUINT, DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gst_element_class_add_static_pad_template (gstelement_class,
       &gst_rtp_h264_depay_src_template);
   gst_element_class_add_static_pad_template (gstelement_class,
@@ -227,6 +253,8 @@
       (GDestroyNotify) gst_buffer_unref);
   rtph264depay->wait_for_keyframe = DEFAULT_WAIT_FOR_KEYFRAME;
   rtph264depay->request_keyframe = DEFAULT_REQUEST_KEYFRAME;
+  rtph264depay->max_fragmentation_unit_size =
+      DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE;
 }
 
 static void
@@ -1527,6 +1555,9 @@
                 "%u to %u within Fragmentation Unit. Data was lost, dropping "
                 "stored.", rtph264depay->last_fu_seqnum,
                 gst_rtp_buffer_get_seq (rtp));
+            rtph264depay->wait_start = TRUE;
+            rtph264depay->current_fu_type = 0;
+            rtph264depay->last_fu_seqnum = 0;
             gst_rtp_base_depayload_flush (depayload, FALSE);
             gst_adapter_clear (rtph264depay->adapter);
             return NULL;
@@ -1553,8 +1584,24 @@
         rtph264depay->fu_marker = marker;
 
         /* if NAL unit ends, flush the adapter */
-        if (E)
+        if (E) {
           gst_rtp_h264_finish_fragmentation_unit (rtph264depay);
+          GST_DEBUG_OBJECT (rtph264depay, "End of Fragmentation Unit");
+        } else {
+          guint limit = rtph264depay->max_fragmentation_unit_size ?
+              rtph264depay->max_fragmentation_unit_size :
+              DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE;
+          if (gst_adapter_available (rtph264depay->adapter) > limit) {
+            GST_WARNING_OBJECT (rtph264depay,
+                "Too big (> %u bytes) fragmentation unit, dropping.", limit);
+            rtph264depay->wait_start = TRUE;
+            rtph264depay->current_fu_type = 0;
+            rtph264depay->last_fu_seqnum = 0;
+            gst_rtp_base_depayload_flush (depayload, FALSE);
+            gst_adapter_clear (rtph264depay->adapter);
+            return NULL;
+          }
+        }
         break;
       }
       default:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/rtp/gstrtph264depay.h 
new/gst-plugins-good-1.28.6/gst/rtp/gstrtph264depay.h
--- old/gst-plugins-good-1.28.5/gst/rtp/gstrtph264depay.h       2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/rtp/gstrtph264depay.h       2026-08-05 
13:59:39.000000000 +0200
@@ -76,6 +76,7 @@
   gboolean request_keyframe;
   gboolean waiting_for_keyframe;
   gboolean requesting_keyframe;
+  guint max_fragmentation_unit_size;
 };
 
 struct _GstRtpH264DepayClass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/rtp/gstrtph265depay.c 
new/gst-plugins-good-1.28.6/gst/rtp/gstrtph265depay.c
--- old/gst-plugins-good-1.28.5/gst/rtp/gstrtph265depay.c       2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/rtp/gstrtph265depay.c       2026-08-05 
13:59:39.000000000 +0200
@@ -42,12 +42,14 @@
 #define DEFAULT_ACCESS_UNIT   FALSE
 #define DEFAULT_WAIT_FOR_KEYFRAME FALSE
 #define DEFAULT_REQUEST_KEYFRAME FALSE
+#define DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE (32 * 1024 * 1024)
 
 enum
 {
   PROP_0,
   PROP_WAIT_FOR_KEYFRAME,
   PROP_REQUEST_KEYFRAME,
+  PROP_MAX_FRAGMENTATION_UNIT_SIZE,
 };
 
 
@@ -143,6 +145,9 @@
     case PROP_REQUEST_KEYFRAME:
       self->request_keyframe = g_value_get_boolean (value);
       break;
+    case PROP_MAX_FRAGMENTATION_UNIT_SIZE:
+      self->max_fragmentation_unit_size = g_value_get_uint (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -162,6 +167,9 @@
     case PROP_REQUEST_KEYFRAME:
       g_value_set_boolean (value, self->request_keyframe);
       break;
+    case PROP_MAX_FRAGMENTATION_UNIT_SIZE:
+      g_value_set_uint (value, self->max_fragmentation_unit_size);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -213,6 +221,24 @@
           DEFAULT_REQUEST_KEYFRAME,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstRtpH265Depay:max-fragmentation-unit-size:
+   *
+   * Maximum size in bytes for a fragmentation unit. Larger units
+   * will be dropped to prevent excessive memory usage.
+   *
+   * Use 0 for automatic.
+   *
+   * Since: 1.28.6
+   */
+  g_object_class_install_property (gobject_class,
+      PROP_MAX_FRAGMENTATION_UNIT_SIZE,
+      g_param_spec_uint ("max-fragmentation-unit-size",
+          "Max Fragmentation Unit Size",
+          "Maximum size in bytes for a fragmentation unit (0 = auto)", 0,
+          G_MAXUINT, DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gst_element_class_add_static_pad_template (gstelement_class,
       &gst_rtp_h265_depay_src_template);
   gst_element_class_add_static_pad_template (gstelement_class,
@@ -250,6 +276,8 @@
       (GDestroyNotify) gst_buffer_unref);
   rtph265depay->wait_for_keyframe = DEFAULT_WAIT_FOR_KEYFRAME;
   rtph265depay->request_keyframe = DEFAULT_REQUEST_KEYFRAME;
+  rtph265depay->max_fragmentation_unit_size =
+      DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE;
 }
 
 static void
@@ -1688,6 +1716,9 @@
                 "%u to %u within Fragmentation Unit. Data was lost, dropping "
                 "stored.", rtph265depay->last_fu_seqnum,
                 gst_rtp_buffer_get_seq (rtp));
+            rtph265depay->wait_start = TRUE;
+            rtph265depay->current_fu_type = 0;
+            rtph265depay->last_fu_seqnum = 0;
             gst_rtp_base_depayload_flush (depayload, FALSE);
             gst_adapter_clear (rtph265depay->adapter);
             return NULL;
@@ -1720,6 +1751,20 @@
         if (E) {
           gst_rtp_h265_finish_fragmentation_unit (rtph265depay);
           GST_DEBUG_OBJECT (rtph265depay, "End of Fragmentation Unit");
+        } else {
+          guint limit = rtph265depay->max_fragmentation_unit_size ?
+              rtph265depay->max_fragmentation_unit_size :
+              DEFAULT_MAX_FRAGMENTATION_UNIT_SIZE;
+          if (gst_adapter_available (rtph265depay->adapter) > limit) {
+            GST_WARNING_OBJECT (rtph265depay,
+                "Too big (> %u bytes) fragmentation unit, dropping.", limit);
+            rtph265depay->wait_start = TRUE;
+            rtph265depay->current_fu_type = 0;
+            rtph265depay->last_fu_seqnum = 0;
+            gst_rtp_base_depayload_flush (depayload, FALSE);
+            gst_adapter_clear (rtph265depay->adapter);
+            return NULL;
+          }
         }
         break;
       }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/rtp/gstrtph265depay.h 
new/gst-plugins-good-1.28.6/gst/rtp/gstrtph265depay.h
--- old/gst-plugins-good-1.28.5/gst/rtp/gstrtph265depay.h       2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/rtp/gstrtph265depay.h       2026-08-05 
13:59:39.000000000 +0200
@@ -91,6 +91,7 @@
   gboolean request_keyframe;
   gboolean waiting_for_keyframe;
   gboolean requesting_keyframe;
+  guint max_fragmentation_unit_size;
 };
 
 struct _GstRtpH265DepayClass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/rtp/gstrtpqcelpdepay.c 
new/gst-plugins-good-1.28.6/gst/rtp/gstrtpqcelpdepay.c
--- old/gst-plugins-good-1.28.5/gst/rtp/gstrtpqcelpdepay.c      2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/rtp/gstrtpqcelpdepay.c      2026-08-05 
13:59:39.000000000 +0200
@@ -79,6 +79,8 @@
 static GstBuffer *gst_rtp_qcelp_depay_process (GstRTPBaseDepayload * depayload,
     GstRTPBuffer * rtp);
 
+static void clear_packets (GstRtpQCELPDepay * depay);
+
 #define gst_rtp_qcelp_depay_parent_class parent_class
 G_DEFINE_TYPE (GstRtpQCELPDepay, gst_rtp_qcelp_depay,
     GST_TYPE_RTP_BASE_DEPAYLOAD);
@@ -123,15 +125,9 @@
 static void
 gst_rtp_qcelp_depay_finalize (GObject * object)
 {
-  GstRtpQCELPDepay *depay;
-
-  depay = GST_RTP_QCELP_DEPAY (object);
+  GstRtpQCELPDepay *depay = GST_RTP_QCELP_DEPAY (object);
 
-  if (depay->packets != NULL) {
-    g_ptr_array_foreach (depay->packets, (GFunc) gst_buffer_unref, NULL);
-    g_ptr_array_free (depay->packets, TRUE);
-    depay->packets = NULL;
-  }
+  clear_packets (depay);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -195,6 +191,31 @@
 }
 
 static void
+unref_packet (GstBuffer * buf)
+{
+  if (buf != NULL)
+    gst_buffer_unref (buf);
+}
+
+static void
+clear_packets (GstRtpQCELPDepay * depay)
+{
+  if (!depay->packets)
+    return;
+
+  GST_DEBUG_OBJECT (depay, "clear packets");
+
+  g_ptr_array_foreach (depay->packets, (GFunc) unref_packet, NULL);
+  g_ptr_array_free (depay->packets, TRUE);
+  depay->packets = NULL;
+
+  /* and reset interleaving state */
+  depay->interleaved = FALSE;
+  depay->interleave_value = 0;
+  depay->bundling = 0;
+}
+
+static void
 flush_packets (GstRtpQCELPDepay * depay)
 {
   guint i, size;
@@ -209,11 +230,13 @@
     outbuf = g_ptr_array_index (depay->packets, i);
     g_ptr_array_index (depay->packets, i) = NULL;
 
-    gst_rtp_base_depayload_push (GST_RTP_BASE_DEPAYLOAD (depay), outbuf);
+    if (outbuf != NULL)
+      gst_rtp_base_depayload_push (GST_RTP_BASE_DEPAYLOAD (depay), outbuf);
   }
 
   /* and reset interleaving state */
   depay->interleaved = FALSE;
+  depay->interleave_value = 0;
   depay->bundling = 0;
 }
 
@@ -299,10 +322,24 @@
     if (!depay->interleaved) {
       guint size;
 
+      /* Can't start interleave handling in the middle of an interleave group 
*/
+      if (NNN != 0) {
+        GST_WARNING_OBJECT (depay,
+            "Can't start interleave group in the middle of a group");
+        return NULL;
+      }
+
       GST_DEBUG_OBJECT (depay, "starting interleaving group");
       /* bundling is not allowed to change in one interleave group */
       depay->bundling = count_packets (depay, payload, payload_len);
-      GST_DEBUG_OBJECT (depay, "got bundling of %u", depay->bundling);
+      if (depay->bundling == 0) {
+        GST_WARNING_OBJECT (depay, "Invalid zero bundling");
+        return NULL;
+      }
+
+      depay->interleave_value = LLL;
+      GST_DEBUG_OBJECT (depay, "got bundling of %u with interleave value %u",
+          depay->bundling, depay->interleave_value);
       /* we have one bundle where NNN goes from 0 to L, we don't store the 
index
        * 0 frames, so L+1 packets. Each packet has 'bundling - 1' packets */
       size = (depay->bundling - 1) * (LLL + 1);
@@ -314,6 +351,28 @@
       /* we were previously not interleaved, figure out how much space we
        * need to deinterleave */
       depay->interleaved = TRUE;
+    } else {
+      guint size;
+
+      /* Bundling is not allowed to change in an interleave group but if it 
does
+       * the erasure / discard code further below will make sure to handle this
+       * gracefully */
+
+      /* Decreasing the interleave value is allowed between interleave groups
+       * only, but increasing it is never allowed */
+      if (depay->interleave_value < LLL) {
+        goto invalid_lll;
+      } else if (depay->interleave_value > LLL) {
+        if (NNN != 0) {
+          goto invalid_nnn;
+        }
+
+        size = (depay->bundling - 1) * (LLL + 1);
+        if (depay->packets == NULL)
+          depay->packets = g_ptr_array_sized_new (size);
+        GST_DEBUG_OBJECT (depay, "resizing packet array to size %u", size);
+        g_ptr_array_set_size (depay->packets, size);
+      }
     }
   } else {
     /* we are not interleaved */
@@ -323,6 +382,7 @@
       flush_packets (depay);
     }
     depay->bundling = 0;
+    depay->interleave_value = 0;
   }
 
   index = 0;
@@ -405,24 +465,28 @@
   {
     GST_ELEMENT_WARNING (depay, STREAM, DECODE,
         (NULL), ("QCELP RTP payload too small (%d)", payload_len));
+    clear_packets (depay);
     return NULL;
   }
 invalid_lll:
   {
     GST_ELEMENT_WARNING (depay, STREAM, DECODE,
         (NULL), ("QCELP RTP invalid LLL received (%d)", LLL));
+    clear_packets (depay);
     return NULL;
   }
 invalid_nnn:
   {
     GST_ELEMENT_WARNING (depay, STREAM, DECODE,
         (NULL), ("QCELP RTP invalid NNN received (%d)", NNN));
+    clear_packets (depay);
     return NULL;
   }
 invalid_frame:
   {
     GST_ELEMENT_WARNING (depay, STREAM, DECODE,
         (NULL), ("QCELP RTP invalid frame received"));
+    clear_packets (depay);
     return NULL;
   }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/rtp/gstrtpqcelpdepay.h 
new/gst-plugins-good-1.28.6/gst/rtp/gstrtpqcelpdepay.h
--- old/gst-plugins-good-1.28.5/gst/rtp/gstrtpqcelpdepay.h      2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/rtp/gstrtpqcelpdepay.h      2026-08-05 
13:59:39.000000000 +0200
@@ -44,7 +44,7 @@
   GstRTPBaseDepayload depayload;
 
   gboolean interleaved;
-  guint bundling;
+  guint bundling, interleave_value;
   GPtrArray *packets;
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/rtpmanager/rtpsession.c 
new/gst-plugins-good-1.28.6/gst/rtpmanager/rtpsession.c
--- old/gst-plugins-good-1.28.5/gst/rtpmanager/rtpsession.c     2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/rtpmanager/rtpsession.c     2026-08-05 
13:59:39.000000000 +0200
@@ -2142,6 +2142,9 @@
   pinfo->bytes += gst_buffer_get_size (*buffer) + pinfo->header_len;
   pinfo->packets++;
 
+  pinfo->is_rtx =
+      GST_BUFFER_FLAG_IS_SET (*buffer, GST_RTP_BUFFER_FLAG_RETRANSMISSION);
+
   if (pinfo->rtp) {
     GstRTPBuffer rtp = { NULL };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/rtpmanager/rtpsource.c 
new/gst-plugins-good-1.28.6/gst/rtpmanager/rtpsource.c
--- old/gst-plugins-good-1.28.5/gst/rtpmanager/rtpsource.c      2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/rtpmanager/rtpsource.c      2026-08-05 
13:59:39.000000000 +0200
@@ -1193,33 +1193,35 @@
 #define BITRATE_INTERVAL (2 * GST_SECOND)
 
 static void
-do_bitrate_estimation (RTPSource * src, GstClockTime running_time,
+do_bitrate_estimation (RTPSource * src, GstClockTime time,
     guint64 * bytes_handled)
 {
   guint64 elapsed;
 
-  if (src->prev_rtime) {
-    elapsed = running_time - src->prev_rtime;
+  if (src->prev_time) {
+    if (time > src->prev_time) {
+      elapsed = time - src->prev_time;
 
-    if (elapsed > BITRATE_INTERVAL) {
-      guint64 rate;
+      if (elapsed > BITRATE_INTERVAL) {
+        guint64 rate;
 
-      rate = gst_util_uint64_scale (*bytes_handled, 8 * GST_SECOND, elapsed);
+        rate = gst_util_uint64_scale (*bytes_handled, 8 * GST_SECOND, elapsed);
 
-      GST_LOG ("Elapsed %" G_GUINT64_FORMAT ", bytes %" G_GUINT64_FORMAT
-          ", rate %" G_GUINT64_FORMAT, elapsed, *bytes_handled, rate);
+        GST_LOG ("Elapsed %" G_GUINT64_FORMAT ", bytes %" G_GUINT64_FORMAT
+            ", rate %" G_GUINT64_FORMAT, elapsed, *bytes_handled, rate);
 
-      if (src->bitrate == 0)
-        src->bitrate = rate;
-      else
-        src->bitrate = ((src->bitrate * 3) + rate) / 4;
+        if (src->bitrate == 0)
+          src->bitrate = rate;
+        else
+          src->bitrate = ((src->bitrate * 3) + rate) / 4;
 
-      src->prev_rtime = running_time;
-      *bytes_handled = 0;
+        src->prev_time = time;
+        *bytes_handled = 0;
+      }
     }
   } else {
     GST_LOG ("Reset bitrate measurement");
-    src->prev_rtime = running_time;
+    src->prev_time = time;
     src->bitrate = 0;
   }
 }
@@ -1504,7 +1506,9 @@
 
   running_time = pinfo->running_time;
 
-  if (GST_CLOCK_TIME_IS_VALID (running_time))
+  if (pinfo->is_rtx)
+    do_bitrate_estimation (src, pinfo->current_time, &src->bytes_sent);
+  else if (GST_CLOCK_TIME_IS_VALID (running_time))
     do_bitrate_estimation (src, running_time, &src->bytes_sent);
 
   rtptime = pinfo->rtptime;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/rtpmanager/rtpsource.h 
new/gst-plugins-good-1.28.6/gst/rtpmanager/rtpsource.h
--- old/gst-plugins-good-1.28.5/gst/rtpmanager/rtpsource.h      2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/rtpmanager/rtpsource.h      2026-08-05 
13:59:39.000000000 +0200
@@ -174,7 +174,7 @@
 
   /* for bitrate estimation */
   guint64       bitrate;
-  GstClockTime  prev_rtime;
+  GstClockTime  prev_time;
   guint64       bytes_sent;
   guint64       bytes_received;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/rtpmanager/rtpstats.h 
new/gst-plugins-good-1.28.6/gst/rtpmanager/rtpstats.h
--- old/gst-plugins-good-1.28.5/gst/rtpmanager/rtpstats.h       2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/rtpmanager/rtpstats.h       2026-08-05 
13:59:39.000000000 +0200
@@ -114,6 +114,7 @@
   guint16       header_ext_bit_pattern;
   guint8        ntp64_ext_id;
   gboolean      have_ntp64_ext;
+  gboolean      is_rtx;
 } RTPPacketInfo;
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst/y4m/gsty4mdec.c 
new/gst-plugins-good-1.28.6/gst/y4m/gsty4mdec.c
--- old/gst-plugins-good-1.28.5/gst/y4m/gsty4mdec.c     2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst/y4m/gsty4mdec.c     2026-08-05 
13:59:39.000000000 +0200
@@ -398,7 +398,11 @@
 
   /* what ever until '\n' */
   for (i = 0; i < MAX_STREAM_HEADER_LENGTH; i++) {
-    header[i] = gst_byte_reader_get_uint8_unchecked (&br);
+    if (!gst_byte_reader_get_uint8 (&br, (guint8 *) & header[i])) {
+      GST_ERROR_OBJECT (y4mdec, "Not enough data for Y4M header");
+      return FALSE;
+    }
+
     if (header[i] == '\n') {
       header[i] = 0;
       break;
@@ -426,7 +430,8 @@
     return FALSE;
   }
 
-  g_assert (mapinfo.size >= MAX_STREAM_HEADER_LENGTH);
+  if (mapinfo.size < MAX_STREAM_HEADER_LENGTH)
+    goto bail;
 
   if (!gst_y4m_dec_parse_magic (y4mdec, mapinfo.data, mapinfo.size, 
stream_hdr))
     goto bail;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/gst-plugins-good.doap 
new/gst-plugins-good-1.28.6/gst-plugins-good.doap
--- old/gst-plugins-good-1.28.5/gst-plugins-good.doap   2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/gst-plugins-good.doap   2026-08-05 
13:59:39.000000000 +0200
@@ -34,6 +34,16 @@
 
  <release>
   <Version>
+   <revision>1.28.6</revision>
+   <branch>1.28</branch>
+   <name></name>
+   <created>2026-08-05</created>
+   <file-release 
rdf:resource="https://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-1.28.6.tar.xz";
 />
+  </Version>
+ </release>
+
+ <release>
+  <Version>
    <revision>1.28.5</revision>
    <branch>1.28</branch>
    <name></name>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/meson.build 
new/gst-plugins-good-1.28.6/meson.build
--- old/gst-plugins-good-1.28.5/meson.build     2026-07-08 23:42:39.000000000 
+0200
+++ new/gst-plugins-good-1.28.6/meson.build     2026-08-05 13:59:39.000000000 
+0200
@@ -1,5 +1,5 @@
 project('gst-plugins-good', 'c',
-  version : '1.28.5',
+  version : '1.28.6',
   meson_version : '>= 1.4',
   default_options : [ 'warning_level=1',
                       'buildtype=debugoptimized',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/sys/v4l2/gstv4l2object.c 
new/gst-plugins-good-1.28.6/sys/v4l2/gstv4l2object.c
--- old/gst-plugins-good-1.28.5/sys/v4l2/gstv4l2object.c        2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/sys/v4l2/gstv4l2object.c        2026-08-05 
13:59:39.000000000 +0200
@@ -75,6 +75,7 @@
   GST_V4L2_TRANSPORT = 1u << 2,
   GST_V4L2_NO_PARSE = 1u << 3,
   GST_V4L2_BAYER = GST_V4L2_RAW | (1u << 5),
+  GST_V4L2_MPLANE = 1u << 6,
   GST_V4L2_ALL = 0xffff
 } GstV4L2FormatFlags;
 
@@ -195,16 +196,16 @@
   /* Luminance+Chrominance formats */
   {MAP_FMT (YUV410, YUV9),    KNOWN_DRM_MAP,              GST_V4L2_RAW},
   {MAP_FMT (YVU410, YVU9),    KNOWN_DRM_MAP,              GST_V4L2_RAW},
-  {MAP_FMT (YUV420M, I420),   KNOWN_DRM_MAP,              GST_V4L2_RAW},
+  {MAP_FMT (YUV420M, I420),   KNOWN_DRM_MAP,              GST_V4L2_RAW | 
GST_V4L2_MPLANE},
   {MAP_FMT (YUV420, I420),    KNOWN_DRM_MAP,              GST_V4L2_RAW},
-  {MAP_FMT (YVU420M, YV12),   KNOWN_DRM_MAP,              GST_V4L2_RAW},
+  {MAP_FMT (YVU420M, YV12),   KNOWN_DRM_MAP,              GST_V4L2_RAW | 
GST_V4L2_MPLANE},
   {MAP_FMT (YVU420, YV12),    KNOWN_DRM_MAP,              GST_V4L2_RAW},
   {MAP_FMT (YUYV, YUY2),      KNOWN_DRM_MAP,              GST_V4L2_RAW},
   {MAP_FMT (YYUV, UNKNOWN),   MAP_DRM (YVYU, LINEAR),     GST_V4L2_RAW},
   {MAP_FMT (YVYU, YVYU),      KNOWN_DRM_MAP,              GST_V4L2_RAW},
   {MAP_FMT (UYVY, UYVY),      KNOWN_DRM_MAP,              GST_V4L2_RAW},
   {MAP_FMT (VYUY, VYUY),      KNOWN_DRM_MAP,              GST_V4L2_RAW},
-  {MAP_FMT (YUV422M, Y42B),   KNOWN_DRM_MAP,              GST_V4L2_RAW},
+  {MAP_FMT (YUV422M, Y42B),   KNOWN_DRM_MAP,              GST_V4L2_RAW | 
GST_V4L2_MPLANE},
   {MAP_FMT (YUV422P, Y42B),   KNOWN_DRM_MAP,              GST_V4L2_RAW},
   {MAP_FMT (YUV411P, Y41B),   KNOWN_DRM_MAP,              GST_V4L2_RAW},
   {MAP_FMT (Y41P, UNKNOWN),   MAP_DRM (INVALID, INVALID), GST_V4L2_RAW},
@@ -216,22 +217,22 @@
   {MAP_FMT (M420, UNKNOWN),   MAP_DRM (INVALID, INVALID),  GST_V4L2_RAW},
 
   /* two planes -- one Y,         one Cr + Cb interleaved  */
-  {MAP_FMT (NV12M, NV12),                       KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
+  {MAP_FMT (NV12M, NV12),                       KNOWN_DRM_MAP,                 
     GST_V4L2_RAW | GST_V4L2_MPLANE},
   {MAP_FMT (NV12, NV12),                        KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
-  {MAP_FMT (NV12MT, NV12_64Z32),                KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
-  {MAP_FMT (NV12MT_16X16, UNKNOWN),             MAP_DRM (NV12, 
SAMSUNG_16_16_TILE), GST_V4L2_RAW},
-  {MAP_FMT (NV12_16L16, UNKNOWN),               MAP_DRM (NV12, 
SAMSUNG_16_16_TILE), GST_V4L2_RAW},
-  {MAP_FMT (NV12M_8L128, NV12_8L128),           MAP_DRM (INVALID, INVALID),    
     GST_V4L2_RAW},
-  {MAP_FMT (NV12M_10BE_8L128, NV12_10BE_8L128), MAP_DRM (INVALID, INVALID),    
     GST_V4L2_RAW},
-  {MAP_FMT (NV21M, NV21),                       KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
+  {MAP_FMT (NV12MT, NV12_64Z32),                KNOWN_DRM_MAP,                 
     GST_V4L2_RAW | GST_V4L2_MPLANE},
+  {MAP_FMT (NV12MT_16X16, UNKNOWN),             MAP_DRM (NV12, 
SAMSUNG_16_16_TILE), GST_V4L2_RAW | GST_V4L2_MPLANE},
+  {MAP_FMT (NV12_16L16, UNKNOWN),               MAP_DRM (NV12, 
SAMSUNG_16_16_TILE), GST_V4L2_RAW | GST_V4L2_MPLANE},
+  {MAP_FMT (NV12M_8L128, NV12_8L128),           MAP_DRM (INVALID, INVALID),    
     GST_V4L2_RAW | GST_V4L2_MPLANE},
+  {MAP_FMT (NV12M_10BE_8L128, NV12_10BE_8L128), MAP_DRM (INVALID, INVALID),    
     GST_V4L2_RAW | GST_V4L2_MPLANE},
+  {MAP_FMT (NV21M, NV21),                       KNOWN_DRM_MAP,                 
     GST_V4L2_RAW | GST_V4L2_MPLANE},
   {MAP_FMT (NV21, NV21),                        KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
-  {MAP_FMT (NV16M, NV16),                       KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
+  {MAP_FMT (NV16M, NV16),                       KNOWN_DRM_MAP,                 
     GST_V4L2_RAW | GST_V4L2_MPLANE},
   {MAP_FMT (NV16, NV16),                        KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
-  {MAP_FMT (NV61M, NV61),                       KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
+  {MAP_FMT (NV61M, NV61),                       KNOWN_DRM_MAP,                 
     GST_V4L2_RAW | GST_V4L2_MPLANE},
   {MAP_FMT (NV61, NV61),                        KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
   {MAP_FMT (NV24, NV24),                        KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
   {MAP_FMT (NV42, UNKNOWN),                     MAP_DRM (NV42, LINEAR),        
     GST_V4L2_RAW},
-  {MAP_FMT (MM21, NV12_16L32S),                 KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
+  {MAP_FMT (MM21, NV12_16L32S),                 KNOWN_DRM_MAP,                 
     GST_V4L2_RAW | GST_V4L2_MPLANE},
   {MAP_FMT (P010, P010_10LE),                   KNOWN_DRM_MAP,                 
     GST_V4L2_RAW},
 
   /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
@@ -1512,53 +1513,53 @@
 
 static const GstV4L2FormatDesc *
 gst_v4l2_object_get_desc_from_video_format (GstVideoFormat format,
-    const GstV4L2FormatDesc ** fallback)
+    const GstV4L2FormatDesc ** desc)
 {
   const GstV4L2FormatDesc *formats = gst_v4l2_format_desc ();
-  const GstV4L2FormatDesc *ret = NULL;
+  const GstV4L2FormatDesc *nc_desc = NULL;
   gint i;
 
-  if (fallback)
-    *fallback = NULL;
+  if (desc)
+    *desc = NULL;
 
   for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) {
     if (formats[i].gst_format == format) {
-      if (!ret)
-        ret = &formats[i];
-      else if (fallback && !*fallback)
-        *fallback = &formats[i];
+      if (!nc_desc)
+        nc_desc = &formats[i];
+      else if (desc && !*desc)
+        *desc = &formats[i];
       else
         break;
     }
   }
 
-  return ret;
+  return nc_desc;
 }
 
 static const GstV4L2FormatDesc *
 gst_v4l2_object_get_desc_from_drm_fourcc (guint32 drm_fourcc,
-    guint64 drm_modifier, const GstV4L2FormatDesc ** fallback)
+    guint64 drm_modifier, const GstV4L2FormatDesc ** desc)
 {
   const GstV4L2FormatDesc *formats = gst_v4l2_format_desc ();
-  const GstV4L2FormatDesc *ret = NULL;
+  const GstV4L2FormatDesc *nc_desc = NULL;
   gint i;
 
-  if (fallback)
-    *fallback = NULL;
+  if (desc)
+    *desc = NULL;
 
   for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) {
     if (formats[i].drm_fourcc == drm_fourcc
         && formats[i].drm_modifier == drm_modifier) {
-      if (!ret)
-        ret = &formats[i];
-      else if (fallback && !*fallback)
-        *fallback = &formats[i];
+      if (!nc_desc)
+        nc_desc = &formats[i];
+      else if (desc && !*desc)
+        *desc = &formats[i];
       else
         break;
     }
   }
 
-  return ret;
+  return nc_desc;
 }
 
 static gboolean
@@ -2033,7 +2034,7 @@
     goto invalid_format;
 
   if (g_str_equal (mimetype, "video/x-raw")) {
-    const GstV4L2FormatDesc *desc, *fallback_desc = NULL;
+    const GstV4L2FormatDesc *nc_desc, *desc = NULL;
     GstVideoFormat format = GST_VIDEO_INFO_FORMAT (&info->vinfo);
     if (format == GST_VIDEO_FORMAT_DMA_DRM) {
       const GstStructure *s = gst_caps_get_structure (caps, 0);
@@ -2043,16 +2044,16 @@
               "drm-format"), &drm_modifier);
       /* we can't support single plane fallback with opaque DRM fourcc since we
        * don't know how to extrapolate the missing strides and offsets. */
-      desc = gst_v4l2_object_get_desc_from_drm_fourcc (drm_fourcc, 
drm_modifier,
+      nc_desc =
+          gst_v4l2_object_get_desc_from_drm_fourcc (drm_fourcc, drm_modifier,
           NULL);
     } else {
-      desc =
-          gst_v4l2_object_get_desc_from_video_format (format, &fallback_desc);
+      nc_desc = gst_v4l2_object_get_desc_from_video_format (format, &desc);
     }
+    if (nc_desc)
+      fourcc_nc = nc_desc->v4l2_format;
     if (desc)
-      fourcc_nc = desc->v4l2_format;
-    if (fallback_desc)
-      fourcc = fallback_desc->v4l2_format;
+      fourcc = desc->v4l2_format;
   } else if (g_str_equal (mimetype, "video/mpegts")) {
     fourcc = V4L2_PIX_FMT_MPEG;
   } else if (g_str_equal (mimetype, "video/x-dv")) {
@@ -2156,18 +2157,14 @@
     fourcc = V4L2_PIX_FMT_PWC2;
   }
 
-  /* Prefer the non-contiguous if supported */
-  v4l2object->prefered_non_contiguous = TRUE;
-
+  /* Prefer the non-contiguous (mplane) format if the device supports it */
   if (fourcc_nc)
     fmt = gst_v4l2_object_get_format_from_fourcc (v4l2object, fourcc_nc);
   else if (fourcc == 0)
     goto unhandled_format;
 
-  if (fmt == NULL) {
+  if (fmt == NULL)
     fmt = gst_v4l2_object_get_format_from_fourcc (v4l2object, fourcc);
-    v4l2object->prefered_non_contiguous = FALSE;
-  }
 
   if (fmt == NULL)
     goto unsupported_format;
@@ -3964,9 +3961,13 @@
       n_v4l_planes = 1;
   }
 
-  /* If our preference is single plane, then set te number of plane to 1 */
-  if (!v4l2object->prefered_non_contiguous)
-    n_v4l_planes = 1;
+  /* If the selected format is not a multi-planar (mplane) format, use 1 plane 
*/
+  {
+    const GstV4L2FormatDesc *fmt_desc =
+        gst_v4l2_object_get_desc_from_v4l2fourcc (pixelformat);
+    if (!fmt_desc || !(fmt_desc->flags & GST_V4L2_MPLANE))
+      n_v4l_planes = 1;
+  }
 
   field = get_v4l2_field_for_info (&info.vinfo);
   if (field != V4L2_FIELD_NONE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/sys/v4l2/gstv4l2object.h 
new/gst-plugins-good-1.28.6/sys/v4l2/gstv4l2object.h
--- old/gst-plugins-good-1.28.5/sys/v4l2/gstv4l2object.h        2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/sys/v4l2/gstv4l2object.h        2026-08-05 
13:59:39.000000000 +0200
@@ -167,12 +167,6 @@
   /* We cache the frame duration if known */
   GstClockTime duration;
 
-  /* if the MPLANE device support both contiguous and non contiguous
-   * it allows to select which one we want. But we prefered_non_contiguous
-   * non contiguous mode.
-   */
-  gboolean prefered_non_contiguous;
-
   /* This will be set if supported in decide_allocation. It can be used to
    * calculate the minimum latency. */
   guint32 min_buffers;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/sys/ximage/gstximagesrc.h 
new/gst-plugins-good-1.28.6/sys/ximage/gstximagesrc.h
--- old/gst-plugins-good-1.28.5/sys/ximage/gstximagesrc.h       2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/sys/ximage/gstximagesrc.h       2026-08-05 
13:59:39.000000000 +0200
@@ -41,7 +41,7 @@
 typedef struct _GstXImageSrc GstXImageSrc;
 typedef struct _GstXImageSrcClass GstXImageSrcClass;
 
-GType gst_ximage_src_get_type (void) G_GNUC_CONST;
+GType gst_ximage_src_get_type (void);
 
 struct _GstXImageSrc
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.28.5/tests/check/elements/qtmux.c 
new/gst-plugins-good-1.28.6/tests/check/elements/qtmux.c
--- old/gst-plugins-good-1.28.5/tests/check/elements/qtmux.c    2026-07-08 
23:42:39.000000000 +0200
+++ new/gst-plugins-good-1.28.6/tests/check/elements/qtmux.c    2026-08-05 
13:59:39.000000000 +0200
@@ -1847,6 +1847,19 @@
   fail_unless (buf != NULL);
   gst_buffer_unref (buf);
 
+  /* Drain to EOS before teardown so releasing the request pad can't race the
+   * still-running aggregate() task. */
+  for (;;) {
+    GstEvent *event = gst_harness_pull_event (h);
+    GstEventType event_type;
+
+    fail_unless (event != NULL);
+    event_type = GST_EVENT_TYPE (event);
+    gst_event_unref (event);
+    if (event_type == GST_EVENT_EOS)
+      break;
+  }
+
   gst_harness_teardown (h);
   gst_object_unref (pad);
 }

++++++ gst-plugins-good.obsinfo ++++++
--- /var/tmp/diff_new_pack.CA7I8Y/_old  2026-08-06 16:19:45.639335004 +0200
+++ /var/tmp/diff_new_pack.CA7I8Y/_new  2026-08-06 16:19:45.655335562 +0200
@@ -1,5 +1,5 @@
 name: gst-plugins-good
-version: 1.28.5
-mtime: 1783546959
-commit: 727ceb91886862d200f423baf36cde2bb7ce5b4d
+version: 1.28.6
+mtime: 1785931179
+commit: 2d3e05cbdad68e47d645f548899b432dc9fb4473
 

Reply via email to