Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package gstreamer-plugins-base for 
openSUSE:Factory checked in at 2026-05-13 17:18:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gstreamer-plugins-base (Old)
 and      /work/SRC/openSUSE:Factory/.gstreamer-plugins-base.new.1966 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gstreamer-plugins-base"

Wed May 13 17:18:37 2026 rev:130 rq:1352701 version:1.28.3

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/gstreamer-plugins-base/gstreamer-plugins-base.changes
    2026-04-15 16:04:49.291617826 +0200
+++ 
/work/SRC/openSUSE:Factory/.gstreamer-plugins-base.new.1966/gstreamer-plugins-base.changes
  2026-05-13 17:18:47.253924123 +0200
@@ -1,0 +2,40 @@
+Tue May 12 06:57:38 UTC 2026 - Bjørn Lie <[email protected]>
+
+- Update to version 1.28.3:
+  + appsink, appsrc: Allow passing NULL callbacks
+  + appsrc: Fix dropped counting with bufferlist
+  + audioaggregator:
+    - Don't drop pending input buffers on sinkpads on srcpad caps
+      changes
+    - Don't reset samples_per_buffer unless sample rate /
+      output-buffer-duration has changed
+    - Don't try converting buffers on caps changes if impossible
+  + audioresample: Fix extra samples produced at speech-to-silence
+    transitions
+  + audio-resampler-neon: fix Thumb encoding and use Clang O2
+    calculation for strides
+  + audio sounds strange on release 1.28.2 for armv7hf
+  + decodebin2: fix leak of endpads list on shutdown while exposing
+  + discoverer: Take the DISCO_LOCK while parsing stream topology
+  + exiftag: Use a hashtable instead of a linked list for storing
+    the pending tags
+  + gl: add GBRA swizzle support
+  + id3v2:
+    - Add input validation and refactor id3v2_ununsync_data
+    - Check valid frame sizes more
+  + opengl: Fix glcolorconvert vertical flip issue on crop
+  + glcolorconvert: GBRA input hits unreachable swizzle path
+  + subparse / samiparse: Various robustness fixes and minor other
+    fixes
+  + subparse:
+    - Fix memory leakage for text colour and background colour
+    - O(N^2) complexity in SAMI parser causes timeout with crafted
+      large input
+  + tag:
+    - Prevent ubsan and wrong fraction usage
+    - Off-by-one checking for id3v2 unnsync tag parsing
+  + video: add precondition check on dma helpers
+  + videodmabufpool: Break ref cycle between the pool and its
+    thread
+
+-------------------------------------------------------------------

Old:
----
  gst-plugins-base-1.28.2.obscpio

New:
----
  gst-plugins-base-1.28.3.obscpio

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

Other differences:
------------------
++++++ gstreamer-plugins-base.spec ++++++
--- /var/tmp/diff_new_pack.5tPLVQ/_old  2026-05-13 17:18:48.041957046 +0200
+++ /var/tmp/diff_new_pack.5tPLVQ/_new  2026-05-13 17:18:48.041957046 +0200
@@ -20,7 +20,7 @@
 %define gst_branch 1.0
 %define gstreamer_req_version %(echo %{version} | sed -e "s/+.*//")
 Name:           gstreamer-plugins-base
-Version:        1.28.2
+Version:        1.28.3
 Release:        0
 Summary:        GStreamer Streaming-Media Framework Plug-Ins
 License:        GPL-2.0-or-later AND LGPL-2.1-or-later

++++++ _service ++++++
--- /var/tmp/diff_new_pack.5tPLVQ/_old  2026-05-13 17:18:48.137961057 +0200
+++ /var/tmp/diff_new_pack.5tPLVQ/_new  2026-05-13 17:18:48.141961224 +0200
@@ -5,7 +5,7 @@
     <param 
name="url">https://gitlab.freedesktop.org/gstreamer/gstreamer.git</param>
     <param name="subdir">subprojects/gst-plugins-base</param>
     <param name="filename">gst-plugins-base</param>
-    <param name="revision">1.28.2</param>
+    <param name="revision">1.28.3</param>
     <param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param>
     <param name="versionrewrite-pattern">v?(.*)\+0</param>
     <param name="versionrewrite-replacement">\1</param>

++++++ gst-plugins-base-1.28.2.obscpio -> gst-plugins-base-1.28.3.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-base-1.28.2/ext/gl/gstglimagesink.c 
new/gst-plugins-base-1.28.3/ext/gl/gstglimagesink.c
--- old/gst-plugins-base-1.28.2/ext/gl/gstglimagesink.c 2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/ext/gl/gstglimagesink.c 2026-05-11 
19:28:12.000000000 +0200
@@ -2493,12 +2493,14 @@
       float scale_x = display_width / padded_width;
       float scale_y = display_height / padded_height;
 
-      GLfloat crop_vertices[] = {
-        1.0f, 1.0f, 0.0f, scale_x, 0.0f,
-        -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-        -1.0f, -1.0f, 0.0f, 0.0f, scale_y,
-        1.0f, -1.0f, 0.0f, scale_x, scale_y,
-      };
+      GLfloat crop_vertices[20];
+      memcpy (crop_vertices, vertices, sizeof (crop_vertices));
+
+      for (int i = 0; i < 4; i++) {
+        crop_vertices[i * 5 + 3] *= scale_x;    // U
+        crop_vertices[i * 5 + 4] *= scale_y;    // V
+      }
+
       gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat),
           crop_vertices, GL_STATIC_DRAW);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/gst/audioresample/gstaudioresample.c 
new/gst-plugins-base-1.28.3/gst/audioresample/gstaudioresample.c
--- old/gst-plugins-base-1.28.2/gst/audioresample/gstaudioresample.c    
2026-04-07 21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst/audioresample/gstaudioresample.c    
2026-05-11 19:28:12.000000000 +0200
@@ -783,7 +783,7 @@
       else
         zeros_to_push = in_len;
 
-      gst_audio_resample_push_drain (resample, zeros_to_push);
+      gst_audio_resample_dump_drain (resample, zeros_to_push);
       in_len -= zeros_to_push;
       resample->num_gap_samples += zeros_to_push;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-base-1.28.2/gst/playback/gstdecodebin2.c 
new/gst-plugins-base-1.28.3/gst/playback/gstdecodebin2.c
--- old/gst-plugins-base-1.28.2/gst/playback/gstdecodebin2.c    2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst/playback/gstdecodebin2.c    2026-05-11 
19:28:12.000000000 +0200
@@ -4810,6 +4810,7 @@
   /* Don't add pads if we are shutting down */
   DYN_LOCK (dbin);
   if (G_UNLIKELY (dbin->shutdown)) {
+    g_list_free_full (endpads, gst_object_unref);
     GST_WARNING_OBJECT (dbin, "Currently, shutting down, aborting exposing");
     DYN_UNLOCK (dbin);
     return FALSE;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-base-1.28.2/gst/subparse/gstsubparse.c 
new/gst-plugins-base-1.28.3/gst/subparse/gstsubparse.c
--- old/gst-plugins-base-1.28.2/gst/subparse/gstsubparse.c      2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst/subparse/gstsubparse.c      2026-05-11 
19:28:12.000000000 +0200
@@ -1631,16 +1631,9 @@
 xml_text (GMarkupParseContext * context,
     const gchar * text, gsize text_len, gpointer user_data, GError ** error)
 {
-  gchar **accum = (gchar **) user_data;
-  gchar *concat;
+  GString *accum = user_data;
 
-  if (*accum) {
-    concat = g_strconcat (*accum, text, NULL);
-    g_free (*accum);
-    *accum = concat;
-  } else {
-    *accum = g_strdup (text);
-  }
+  g_string_append_len (accum, text, text_len);
 }
 
 static gchar *
@@ -1648,10 +1641,10 @@
 {
   GMarkupParser parser = { 0, };
   GMarkupParseContext *context;
-  gchar *accum = NULL;
+  GString *accum = g_string_new (NULL);
 
   parser.text = xml_text;
-  context = g_markup_parse_context_new (&parser, 0, &accum, NULL);
+  context = g_markup_parse_context_new (&parser, 0, accum, NULL);
 
   g_markup_parse_context_parse (context, "<root>", 6, NULL);
   g_markup_parse_context_parse (context, markup, strlen (markup), error);
@@ -1665,10 +1658,10 @@
 
 done:
   g_markup_parse_context_free (context);
-  return accum;
+  return accum ? g_string_free (accum, FALSE) : NULL;
 
 error:
-  g_free (accum);
+  g_string_free (accum, TRUE);
   accum = NULL;
   goto done;
 }
@@ -1811,6 +1804,7 @@
         } else {
           GST_WARNING_OBJECT (self, "Failed to strip pango markup: %s",
               error->message);
+          g_clear_error (&error);
         }
       }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-base-1.28.2/gst/subparse/qttextparse.c 
new/gst-plugins-base-1.28.3/gst/subparse/qttextparse.c
--- old/gst-plugins-base-1.28.2/gst/subparse/qttextparse.c      2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst/subparse/qttextparse.c      2026-05-11 
19:28:12.000000000 +0200
@@ -229,6 +229,7 @@
 
   } else if (strncmp (line + *index, "textColor", 9) == 0) {
     if (read_color (line + *index + 9, &r, &g, &b)) {
+      g_free (context->fg_color);
       context->fg_color = make_color (r, g, b);
       GST_DEBUG ("Setting qttext fg color to %s", context->fg_color);
     } else {
@@ -238,6 +239,7 @@
 
   } else if (strncmp (line + *index, "backColor", 9) == 0) {
     if (read_color (line + *index + 9, &r, &g, &b)) {
+      g_free (context->bg_color);
       context->bg_color = make_color (r, g, b);
       GST_DEBUG ("Setting qttext bg color to %s", context->bg_color);
     } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-base-1.28.2/gst/subparse/samiparse.c 
new/gst-plugins-base-1.28.3/gst/subparse/samiparse.c
--- old/gst-plugins-base-1.28.2/gst/subparse/samiparse.c        2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst/subparse/samiparse.c        2026-05-11 
19:28:12.000000000 +0200
@@ -56,9 +56,9 @@
 
 struct _HtmlParser
 {
-  void (*start_element) (HtmlContext * ctx,
+  gboolean (*start_element) (HtmlContext * ctx,
       const gchar * name, const gchar ** attr, gpointer user_data);
-  void (*end_element) (HtmlContext * ctx,
+  gboolean (*end_element) (HtmlContext * ctx,
       const gchar * name, gpointer user_data);
   void (*text) (HtmlContext * ctx,
       const gchar * text, gsize text_len, gpointer user_data);
@@ -468,7 +468,26 @@
   return next;
 }
 
-static void
+static gboolean
+is_valid_attribute_name (const char *name)
+{
+  const gchar *p = name;
+
+  while (*p) {
+    /* stop on =, attribute value starts here */
+    if (*p == '=')
+      break;
+
+    /* this is stricter than required by the spec */
+    if (!g_ascii_isalnum (*p))
+      return FALSE;
+    p++;
+  }
+
+  return TRUE;
+}
+
+static gboolean
 html_context_handle_element (HtmlContext * ctxt,
     const gchar * string, gboolean must_close)
 {
@@ -504,6 +523,12 @@
       g_free (attr_name);
       break;
     }
+    if (!is_valid_attribute_name (attr_name)) {
+      g_free (attr_name);
+      g_strfreev (attrs);
+      g_free (name);
+      return FALSE;
+    }
     next = string_token (next + 1, " ", &attr_value);
 
     /* strip " or ' from attribute value */
@@ -523,17 +548,47 @@
     attrs[i + 1] = attr_value;
   }
 
-  ctxt->parser->start_element (ctxt, name,
-      (const gchar **) attrs, ctxt->user_data);
+  if (!ctxt->parser->start_element (ctxt, name,
+          (const gchar **) attrs, ctxt->user_data)) {
+    g_strfreev (attrs);
+    g_free (name);
+
+    return FALSE;
+  }
   if (must_close) {
-    ctxt->parser->end_element (ctxt, name, ctxt->user_data);
+    if (!ctxt->parser->end_element (ctxt, name, ctxt->user_data)) {
+      g_strfreev (attrs);
+      g_free (name);
+
+      return FALSE;
+    }
   }
   g_strfreev (attrs);
   g_free (name);
+
+  return TRUE;
 }
 
-static void
-html_context_parse (HtmlContext * ctxt, gchar * text, gsize text_len)
+static gboolean
+is_valid_element_name (const char *name)
+{
+  const gchar *p = name;
+
+  while (*p) {
+    /* stop on space, afterwards attributes start */
+    if (*p == ' ')
+      break;
+
+    if (!g_ascii_isalnum (*p))
+      return FALSE;
+    p++;
+  }
+
+  return TRUE;
+}
+
+static gboolean
+html_context_parse (HtmlContext * ctxt, const gchar * text, gsize text_len)
 {
   const gchar *next = NULL;
 
@@ -545,21 +600,44 @@
       /* find <blahblah> */
       if (!strchr (next, '>')) {
         /* no tag end point. buffer will be process in next time */
-        return;
+        return TRUE;
       }
 
       next = string_token (next, ">", &element);
       next++;
-      if (g_str_has_suffix (element, "/")) {
+      if (g_str_has_prefix (element, "<!")) {
+        /* skip comments, DOCTYPE, [CDATA or similar tags */
+      } else if (g_str_has_suffix (element, "/")) {
         /* handle <blah/> */
         element[strlen (element) - 1] = '\0';
-        html_context_handle_element (ctxt, element + 1, TRUE);
+        if (!is_valid_element_name (element + 1)) {
+          g_free (element);
+          goto error;
+        }
+        if (!html_context_handle_element (ctxt, element + 1, TRUE)) {
+          g_free (element);
+          goto error;
+        }
       } else if (element[1] == '/') {
         /* handle </blah> */
-        ctxt->parser->end_element (ctxt, element + 2, ctxt->user_data);
+        if (!is_valid_element_name (element + 2)) {
+          g_free (element);
+          goto error;
+        }
+        if (!ctxt->parser->end_element (ctxt, element + 2, ctxt->user_data)) {
+          g_free (element);
+          goto error;
+        }
       } else {
         /* handle <blah> */
-        html_context_handle_element (ctxt, element + 1, FALSE);
+        if (!is_valid_element_name (element + 1)) {
+          g_free (element);
+          goto error;
+        }
+        if (!html_context_handle_element (ctxt, element + 1, FALSE)) {
+          g_free (element);
+          goto error;
+        }
       }
       g_free (element);
     } else if (strchr (next, '<')) {
@@ -572,17 +650,20 @@
       g_free (text);
 
     } else {
-      gchar *text = (gchar *) next;
+      gchar *text = g_strdup (next);
       gsize length;
       text = g_strstrip (text);
       length = strlen (text);
       ctxt->parser->text (ctxt, text, length, ctxt->user_data);
       ctxt->buf = g_string_assign (ctxt->buf, "");
-      return;
+      g_free (text);
+      return TRUE;
     }
   }
 
-  g_assert_not_reached ();
+error:
+  g_string_truncate (ctxt->buf, 0);
+  return FALSE;
 }
 
 static gchar *
@@ -708,8 +789,7 @@
           gchar *r;
 
           /* check if it looks like hex */
-          if (strtol ((const char *) value, &r, 16) >= 0 &&
-              ((gchar *) r == (value + 6) && len == 6)) {
+          if (strtol (value, &r, 16) >= 0 && (len == 6 && r == (value + 6))) {
             sharp = "#";
           }
         }
@@ -743,7 +823,7 @@
   }
 }
 
-static void
+static gboolean
 handle_start_element (HtmlContext * ctx, const gchar * name,
     const char **atts, gpointer user_data)
 {
@@ -751,6 +831,10 @@
 
   GST_LOG ("name:%s", name);
 
+  /* Don't allow nesting by more than 64 levels to avoid DoS */
+  if (sctx->state->len > 64)
+    return FALSE;
+
   if (!g_ascii_strcasecmp ("sync", name)) {
     handle_start_sync (sctx, atts);
     sctx->in_sync = TRUE;
@@ -772,9 +856,11 @@
     sami_context_push_state (sctx, ITALIC_TAG);
   } else if (!g_ascii_strcasecmp ("p", name)) {
   }
+
+  return TRUE;
 }
 
-static void
+static gboolean
 handle_end_element (HtmlContext * ctx, const char *name, gpointer user_data)
 {
   GstSamiContext *sctx = (GstSamiContext *) user_data;
@@ -804,6 +890,8 @@
   } else if (!g_ascii_strcasecmp ("i", name)) {
     sami_context_pop_state (sctx, ITALIC_TAG);
   }
+
+  return TRUE;
 }
 
 static void
@@ -880,6 +968,8 @@
     context->in_sync = FALSE;
     context->time1 = 0;
     context->time2 = 0;
+
+    g_string_truncate (context->htmlctxt->buf, 0);
   }
 }
 
@@ -888,12 +978,18 @@
 {
   gchar *ret = NULL;
   GstSamiContext *context = (GstSamiContext *) state->user_data;
+  gboolean success;
 
   gchar *unescaped = unescape_string (line);
-  html_context_parse (context->htmlctxt, (gchar *) unescaped,
-      strlen (unescaped));
+  success =
+      html_context_parse (context->htmlctxt, unescaped, strlen (unescaped));
   g_free (unescaped);
 
+  if (!success) {
+    sami_context_reset (state);
+    return NULL;
+  }
+
   if (context->has_result) {
     if (context->rubybuf->len) {
       g_string_append_c (context->rubybuf, '\n');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/gst-libs/gst/app/gstappsink.c 
new/gst-plugins-base-1.28.3/gst-libs/gst/app/gstappsink.c
--- old/gst-plugins-base-1.28.2/gst-libs/gst/app/gstappsink.c   2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/app/gstappsink.c   2026-05-11 
19:28:12.000000000 +0200
@@ -2561,7 +2561,7 @@
 /**
  * gst_app_sink_set_callbacks: (skip)
  * @appsink: a #GstAppSink
- * @callbacks: the callbacks
+ * @callbacks: (nullable): the callbacks
  * @user_data: a user_data argument for the callbacks
  * @notify: a destroy notify function
  *
@@ -2575,6 +2575,8 @@
  * Before 1.16.3 it was not possible to change the callbacks in a thread-safe
  * way.
  *
+ * Since 1.28.3 it is allowed to set the @callbacks to %NULL to unset them.
+ *
  * Note that gst_app_sink_set_callbacks() and
  * gst_app_sink_set_simple_callbacks() are mutually exclusive and setting one
  * will unset the other.
@@ -2588,7 +2590,6 @@
   GstAppSinkPrivate *priv;
 
   g_return_if_fail (GST_IS_APP_SINK (appsink));
-  g_return_if_fail (callbacks != NULL);
 
   priv = appsink->priv;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-base-1.28.2/gst-libs/gst/app/gstappsrc.c 
new/gst-plugins-base-1.28.3/gst-libs/gst/app/gstappsrc.c
--- old/gst-plugins-base-1.28.2/gst-libs/gst/app/gstappsrc.c    2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/app/gstappsrc.c    2026-05-11 
19:28:12.000000000 +0200
@@ -2645,7 +2645,7 @@
         gst_app_src_update_queued_pop (appsrc, item, FALSE);
 
         if (GST_IS_BUFFER_LIST (item))
-          priv->dropped += gst_buffer_list_length (buflist);
+          priv->dropped += gst_buffer_list_length ((GstBufferList *) item);
         else
           priv->dropped += 1;
         gst_mini_object_unref (item);
@@ -3001,7 +3001,7 @@
 /**
  * gst_app_src_set_callbacks: (skip)
  * @appsrc: a #GstAppSrc
- * @callbacks: the callbacks
+ * @callbacks: (nullable): the callbacks
  * @user_data: a user_data argument for the callbacks
  * @notify: a destroy notify function
  *
@@ -3015,6 +3015,12 @@
  *
  * Before 1.16.3 it was not possible to change the callbacks in a thread-safe
  * way.
+ *
+ * Since 1.28.3 it is allowed to set the @callbacks to %NULL to unset them.
+ *
+ * Note that gst_app_src_set_callbacks() and
+ * gst_app_src_set_simple_callbacks() are mutually exclusive and setting one
+ * will unset the other.
  */
 void
 gst_app_src_set_callbacks (GstAppSrc * appsrc,
@@ -3025,7 +3031,6 @@
   GstAppSrcPrivate *priv;
 
   g_return_if_fail (GST_IS_APP_SRC (appsrc));
-  g_return_if_fail (callbacks != NULL);
 
   priv = appsrc->priv;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/gst-libs/gst/audio/audio-resampler-neon.h 
new/gst-plugins-base-1.28.3/gst-libs/gst/audio/audio-resampler-neon.h
--- old/gst-plugins-base-1.28.2/gst-libs/gst/audio/audio-resampler-neon.h       
2026-04-07 21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/audio/audio-resampler-neon.h       
2026-05-11 19:28:12.000000000 +0200
@@ -132,11 +132,12 @@
                   "      beq 2f\n"
                   "1:"
                   "      vld1.16 {d16, d17}, [%[b]]!\n"
-                  "      add r8, %[b], %[bstride]\n"
+                  "      add.w r8, %[b], %[bstride]\n"
                   "      vld1.16 {d18, d19}, [r8]!\n"
-                  "      add r8, r8, %[bstride]\n"
+                  "      add.w r8, %[b], %[bstride], lsl #1\n"
                   "      vld1.16 {d20, d21}, [r8]!\n"
-                  "      add r8, r8, %[bstride]\n"
+                  "      add.w r8, %[bstride], %[bstride], lsl #1\n"
+                  "      add r8, r8, %[b]\n"
                   "      vld1.16 {d22, d23}, [r8]!\n"
                   "      vld1.16 {d24, d25}, [%[a]]!\n"
                   "      subs %[len], %[len], #8\n"
@@ -212,11 +213,12 @@
                   "      vld4.16 {d24[], d25[], d26[], d27[]}, [%[ic]]\n"
                   "1:"
                   "      vld1.16 {d16, d17}, [%[a]]!\n"
-                  "      add r8, %[a], %[astride]\n"
+                  "      add.w r8, %[a], %[astride]\n"
                   "      vld1.16 {d18, d19}, [r8]!\n"
-                  "      add r8, r8, %[astride]\n"
+                  "      add.w r8, %[a], %[astride], lsl #1\n"
                   "      vld1.16 {d20, d21}, [r8]!\n"
-                  "      add r8, r8, %[astride]\n"
+                  "      add.w r8, %[astride], %[astride], lsl #1\n"
+                  "      add r8, r8, %[a]\n"
                   "      vld1.16 {d22, d23}, [r8]!\n"
                   "      subs %[len], %[len], #8\n"
                   "      vmull.s16 q0, d16, d24\n"
@@ -337,11 +339,12 @@
                   "      beq 2f\n"
                   "1:"
                   "      vld1.32 {d16, d17}, [%[b]]!\n"
-                  "      add r8, %[b], %[bstride]\n"
+                  "      add.w r8, %[b], %[bstride]\n"
                   "      vld1.32 {d18, d19}, [r8]!\n"
-                  "      add r8, r8, %[bstride]\n"
+                  "      add.w r8, %[b], %[bstride], lsl #1\n"
                   "      vld1.32 {d20, d21}, [r8]!\n"
-                  "      add r8, r8, %[bstride]\n"
+                  "      add.w r8, %[bstride], %[bstride], lsl #1\n"
+                  "      add r8, r8, %[b]\n"
                   "      vld1.32 {d22, d23}, [r8]!\n"
                   "      vld1.32 {d24, d25}, [%[a]]!\n"
                   "      subs %[len], %[len], #4\n"
@@ -422,12 +425,13 @@
                   "      vld4.32 {d24[], d25[], d26[], d27[]}, [%[ic]]!\n"
                   "1:"
                   "      vld1.32 {d16, d17}, [%[a]]!\n"
-                  "      add r8, %[a], %[astride]\n"
+                  "      add.w r8, %[a], %[astride]\n"
                   "      vld1.32 {d18, d19}, [r8]!\n"
-                  "      add r8, r8, %[astride]\n"
+                  "      add.w r8, %[a], %[astride], lsl #1\n"
                   "      vld1.32 {d20, d21}, [r8]!\n"
                   "      add r8, r8, %[astride]\n"
-                  "      vld1.32 {d22, d23}, [r8]!\n"
+                  "      add.w r8, %[astride], %[astride], lsl #1\n"
+                  "      add r8, r8, %[a]\n"
                   "      subs %[len], %[len], #4\n"
                   "      vmull.s32 q0, d16, d24\n"
                   "      vmull.s32 q1, d17, d24\n"
@@ -542,11 +546,11 @@
                   "      vld1.32 {q8}, [%[b]]!\n"
                   "      add r8, %[b], %[bstride]\n"
                   "      vld1.32 {q9}, [r8]!\n"
-                  "      add r8, r8, %[bstride]\n"
+                  "      add.w r8, %[b], %[bstride], lsl #1\n"
                   "      vld1.32 {q10}, [r8]!\n"
-                  "      add r8, r8, %[bstride]\n"
+                  "      add.w r8, %[bstride], %[bstride], lsl #1\n"
+                  "      add r8, r8, %[b]\n"
                   "      vld1.32 {q11}, [r8]!\n"
-                  "      add r8, r8, %[bstride]\n"
                   "      vld1.32 {q12}, [%[a]]!\n"
                   "      subs %[len], %[len], #4\n"
                   "      vmla.f32 q0, q8, q12\n"
@@ -618,11 +622,12 @@
                   "      vmov.32 d31, d30\n"
                   "1:"
                   "      vld1.32 {q8}, [%[a]]!\n"
-                  "      add r8, %[a], %[astride]\n"
+                  "      add.w r8, %[a], %[astride]\n"
                   "      vld1.32 {q9}, [r8]!\n"
-                  "      add r8, r8, %[astride]\n"
+                  "      add.w r8, %[a], %[astride], lsl #1\n"
                   "      vld1.32 {q10}, [r8]!\n"
-                  "      add r8, r8, %[astride]\n"
+                  "      add.w r8, %[astride], %[astride], lsl #1\n"
+                  "      add r8, r8, %[a]\n"
                   "      vld1.32 {q11}, [r8]!\n"
                   "      subs %[len], %[len], #4\n"
                   "      vmul.f32 q0, q8, q12\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/gst-libs/gst/audio/gstaudioaggregator.c 
new/gst-plugins-base-1.28.3/gst-libs/gst/audio/gstaudioaggregator.c
--- old/gst-plugins-base-1.28.2/gst-libs/gst/audio/gstaudioaggregator.c 
2026-04-07 21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/audio/gstaudioaggregator.c 
2026-05-11 19:28:12.000000000 +0200
@@ -632,11 +632,6 @@
       aagg->priv->output_buffer_duration_d);
 
   gst_aggregator_set_latency (GST_AGGREGATOR (aagg), latency, latency);
-
-  GST_OBJECT_LOCK (aagg);
-  /* Force recalculating in aggregate */
-  aagg->priv->samples_per_buffer = 0;
-  GST_OBJECT_UNLOCK (aagg);
 }
 
 
@@ -811,6 +806,11 @@
           g_value_get_uint64 (value));
       g_object_notify (object, "output-buffer-duration-fraction");
       gst_audio_aggregator_recalculate_latency (aagg);
+
+      GST_OBJECT_LOCK (aagg);
+      /* Force recalculating in aggregate */
+      aagg->priv->samples_per_buffer = 0;
+      GST_OBJECT_UNLOCK (aagg);
       break;
     case PROP_ALIGNMENT_THRESHOLD:
       aagg->priv->alignment_threshold = g_value_get_uint64 (value);
@@ -825,6 +825,11 @@
           gst_value_get_fraction_denominator (value);
       g_object_notify (object, "output-buffer-duration");
       gst_audio_aggregator_recalculate_latency (aagg);
+
+      GST_OBJECT_LOCK (aagg);
+      /* Force recalculating in aggregate */
+      aagg->priv->samples_per_buffer = 0;
+      GST_OBJECT_UNLOCK (aagg);
       break;
     case PROP_IGNORE_INACTIVE_PADS:
       gst_aggregator_set_ignore_inactive_pads (GST_AGGREGATOR (object),
@@ -1229,12 +1234,20 @@
     /* If we currently were mixing a buffer, we need to convert it to the new
      * format */
     if (aaggpad->priv->buffer) {
-      GstBuffer *new_converted_buffer =
-          gst_audio_aggregator_convert_buffer (aagg, GST_PAD (aaggpad),
-          old_info, new_info, aaggpad->priv->buffer);
-      gst_buffer_replace (&aaggpad->priv->buffer, new_converted_buffer);
-      if (new_converted_buffer)
-        gst_buffer_unref (new_converted_buffer);
+      if (klass->convert_buffer) {
+        GstBuffer *new_converted_buffer =
+            gst_audio_aggregator_convert_buffer (aagg, GST_PAD (aaggpad),
+            old_info, new_info, aaggpad->priv->buffer);
+        gst_buffer_unref (aaggpad->priv->buffer);
+        aaggpad->priv->buffer = new_converted_buffer;
+        if (!new_converted_buffer) {
+          GST_WARNING_OBJECT (aaggpad,
+              "Caps have changed and have a current buffer but conversion 
failed -- dropping");
+        }
+      } else {
+        // Otherwise the buffer is simply kept and used for further output. The
+        // subclass must be able to handle it correctly despite srcpad caps 
changes.
+      }
     }
   }
 
@@ -1267,8 +1280,11 @@
     GST_INFO_OBJECT (aagg, "setting caps to %" GST_PTR_FORMAT, caps);
     gst_caps_replace (&aagg->current_caps, caps);
 
-    if (old_info.rate != info.rate)
+    if (old_info.rate != info.rate) {
+      /* Force recalculating in aggregate */
       aagg->priv->offset = -1;
+      aagg->priv->samples_per_buffer = 0;
+    }
 
     memcpy (&srcpad->info, &info, sizeof (info));
 
@@ -1283,22 +1299,27 @@
               srcpad));
 
     if (aagg->priv->current_buffer) {
-      GstBuffer *converted;
+      if (srcpad_klass->convert_buffer) {
+        GstBuffer *converted;
 
-      converted =
-          gst_audio_aggregator_convert_buffer (aagg, agg->srcpad, &old_info,
-          &info, aagg->priv->current_buffer);
-      gst_buffer_unref (aagg->priv->current_buffer);
-      aagg->priv->current_buffer = converted;
-      if (!converted) {
-        GST_OBJECT_UNLOCK (aagg);
-        GST_AUDIO_AGGREGATOR_UNLOCK (aagg);
-        return FALSE;
+        converted =
+            gst_audio_aggregator_convert_buffer (aagg, agg->srcpad, &old_info,
+            &info, aagg->priv->current_buffer);
+        gst_buffer_unref (aagg->priv->current_buffer);
+        aagg->priv->current_buffer = converted;
+        if (!converted) {
+          GST_WARNING_OBJECT (aagg,
+              "Caps have changed and have a current buffer but conversion 
failed -- dropping");
+          GST_OBJECT_UNLOCK (aagg);
+          GST_AUDIO_AGGREGATOR_UNLOCK (aagg);
+          return FALSE;
+        }
+      } else {
+        GST_WARNING_OBJECT (aagg,
+            "Caps have changed and have a current buffer but can't convert -- 
dropping");
+        gst_clear_buffer (&aagg->priv->current_buffer);
       }
     }
-
-    /* Force recalculating in aggregate */
-    aagg->priv->samples_per_buffer = 0;
   }
 
   GST_OBJECT_UNLOCK (aagg);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/gst-libs/gst/gl/gstglcolorconvert.c 
new/gst-plugins-base-1.28.3/gst-libs/gst/gl/gstglcolorconvert.c
--- old/gst-plugins-base-1.28.2/gst-libs/gst/gl/gstglcolorconvert.c     
2026-04-07 21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/gl/gstglcolorconvert.c     
2026-05-11 19:28:12.000000000 +0200
@@ -2269,15 +2269,9 @@
       reorder[3] = 2;
       break;
     case GST_VIDEO_FORMAT_GBR:
-      if (input) {
-        reorder[0] = 2;
-        reorder[1] = 0;
-        reorder[2] = 1;
-      } else {
-        reorder[0] = 0;
-        reorder[1] = 1;
-        reorder[2] = 2;
-      }
+      reorder[0] = 2;
+      reorder[1] = 0;
+      reorder[2] = 1;
       reorder[3] = 3;
       break;
     default:
@@ -3440,12 +3434,14 @@
     float scale_x = display_width / padded_width;
     float scale_y = display_height / padded_height;
 
-    GLfloat crop_vertices[] = {
-      1.0f, 1.0f, 0.0f, scale_x, 0.0f,
-      -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-      -1.0f, -1.0f, 0.0f, 0.0f, scale_y,
-      1.0f, -1.0f, 0.0f, scale_x, scale_y,
-    };
+    GLfloat crop_vertices[20];
+    memcpy (crop_vertices, vertices, sizeof (crop_vertices));
+
+    for (int i = 0; i < 4; i++) {
+      crop_vertices[i * 5 + 3] *= scale_x;      // U
+      crop_vertices[i * 5 + 4] *= scale_y;      // V
+    }
+
     gl->BindBuffer (GL_ARRAY_BUFFER, convert->priv->vertex_buffer);
     gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat),
         crop_vertices, GL_STATIC_DRAW);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/gst-libs/gst/gl/gstglformat.c 
new/gst-plugins-base-1.28.3/gst-libs/gst/gl/gstglformat.c
--- old/gst-plugins-base-1.28.2/gst-libs/gst/gl/gstglformat.c   2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/gl/gstglformat.c   2026-05-11 
19:28:12.000000000 +0200
@@ -584,6 +584,12 @@
     case GST_VIDEO_FORMAT_RGBP:
       get_single_planar_format_gl_swizzle_order (GST_VIDEO_FORMAT_RGB, 
swizzle);
       return TRUE;
+    case GST_VIDEO_FORMAT_GBRA:
+      swizzle[0] = 2;
+      swizzle[1] = 0;
+      swizzle[2] = 1;
+      swizzle[3] = 3;
+      return TRUE;
     case GST_VIDEO_FORMAT_AV12:
     case GST_VIDEO_FORMAT_NV12:
     case GST_VIDEO_FORMAT_NV16:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/gst-libs/gst/pbutils/gstdiscoverer.c 
new/gst-plugins-base-1.28.3/gst-libs/gst/pbutils/gstdiscoverer.c
--- old/gst-plugins-base-1.28.2/gst-libs/gst/pbutils/gstdiscoverer.c    
2026-04-07 21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/pbutils/gstdiscoverer.c    
2026-05-11 19:28:12.000000000 +0200
@@ -1504,6 +1504,7 @@
     else
       dc->priv->current_info->live = TRUE;
 
+    DISCO_LOCK (dc);
     if (dc->priv->current_topology) {
       dc->priv->current_info_stream_count = 1;
       dc->priv->current_info->stream_info = parse_stream_topology (dc,
@@ -1511,6 +1512,7 @@
       if (dc->priv->current_info->stream_info)
         dc->priv->current_info->stream_info->stream_number = 0;
     }
+    DISCO_UNLOCK (dc);
 
     /*
      * Images need some special handling. They do not have a duration, have
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/gst-libs/gst/tag/gstexiftag.c 
new/gst-plugins-base-1.28.3/gst-libs/gst/tag/gstexiftag.c
--- old/gst-plugins-base-1.28.2/gst-libs/gst/tag/gstexiftag.c   2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/tag/gstexiftag.c   2026-05-11 
19:28:12.000000000 +0200
@@ -256,7 +256,7 @@
   gint byte_order;
 
   /* tags waiting for their complementary tags */
-  GSList *pending_tags;
+  GHashTable *pending_tags;
 };
 
 EXIF_SERIALIZATION_DESERIALIZATION_FUNC (aperture_value);
@@ -489,7 +489,8 @@
   reader->buffer = buf;
   reader->base_offset = base_offset;
   reader->byte_order = byte_order;
-  reader->pending_tags = NULL;
+  reader->pending_tags = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+      NULL, (GDestroyNotify) g_free);
   if (reader->byte_order != G_LITTLE_ENDIAN &&
       reader->byte_order != G_BIG_ENDIAN) {
     GST_WARNING ("Unexpected byte order %d, using system default: %d",
@@ -506,35 +507,23 @@
   copy = g_new (GstExifTagData, 1);
   memcpy (copy, data, sizeof (GstExifTagData));
 
-  reader->pending_tags = g_slist_prepend (reader->pending_tags, copy);
+  g_hash_table_insert (reader->pending_tags, GUINT_TO_POINTER (data->tag),
+      copy);
 }
 
 static GstExifTagData *
 gst_exif_reader_get_pending_tag (GstExifReader * reader, gint tagid)
 {
-  GSList *walker;
-
-  for (walker = reader->pending_tags; walker; walker = g_slist_next (walker)) {
-    GstExifTagData *data = (GstExifTagData *) walker->data;
-    if (data->tag == tagid)
-      return data;
-  }
-
-  return NULL;
+  return g_hash_table_lookup (reader->pending_tags, GUINT_TO_POINTER (tagid));
 }
 
 static GstTagList *
 gst_exif_reader_reset (GstExifReader * reader, gboolean return_taglist)
 {
   GstTagList *ret = NULL;
-  GSList *walker;
-
-  for (walker = reader->pending_tags; walker; walker = g_slist_next (walker)) {
-    GstExifTagData *data = (GstExifTagData *) walker->data;
 
-    g_free (data);
-  }
-  g_slist_free (reader->pending_tags);
+  g_hash_table_unref (reader->pending_tags);
+  reader->pending_tags = NULL;
 
   if (return_taglist) {
     ret = reader->taglist;
@@ -1874,12 +1863,12 @@
 
   /* check if the pending tags have something that can still be added */
   {
-    GSList *walker;
-    GstExifTagData *data;
+    GHashTableIter iter;
+    gpointer key, value;
 
-    for (walker = exif_reader->pending_tags; walker;
-        walker = g_slist_next (walker)) {
-      data = (GstExifTagData *) walker->data;
+    g_hash_table_iter_init (&iter, exif_reader->pending_tags);
+    while (g_hash_table_iter_next (&iter, &key, &value)) {
+      GstExifTagData *data = value;
       switch (data->tag) {
         case EXIF_TAG_XRESOLUTION:
           parse_exif_rational_tag (exif_reader, GST_TAG_IMAGE_HORIZONTAL_PPI,
@@ -2321,6 +2310,11 @@
       exiftag->gst_tag, degrees_n, degrees_d, minutes_n, minutes_d,
       seconds_n, seconds_d);
 
+  if (degrees_d == 0 || minutes_d == 0 || seconds_d == 0) {
+    GST_WARNING ("Zero denominator in geo coordinate fractions");
+    gst_buffer_unmap (exif_reader->buffer, &info);
+    return ret;
+  }
   gst_util_fraction_to_double (degrees_n, degrees_d, &degrees);
   gst_util_fraction_to_double (minutes_n, minutes_d, &minutes);
   gst_util_fraction_to_double (seconds_n, seconds_d, &seconds);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-base-1.28.2/gst-libs/gst/tag/id3v2.c 
new/gst-plugins-base-1.28.3/gst-libs/gst/tag/id3v2.c
--- old/gst-plugins-base-1.28.2/gst-libs/gst/tag/id3v2.c        2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/tag/id3v2.c        2026-05-11 
19:28:12.000000000 +0200
@@ -75,7 +75,7 @@
         "- using the actual value instead");
     result = 0;
     for (i = 0; i <= size; i++) {
-      result |= data[i] << ((size - i) * 8);
+      result |= ((guint32) data[i]) << ((size - i) * 8);
     }
   }
 #endif
@@ -121,7 +121,7 @@
 
   /* Expand the read size to include a footer if there is one */
   if ((flags & ID3V2_HDR_FLAG_FOOTER))
-    result += 10;
+    result += ID3V2_FOOTER_SIZE;
 
   GST_DEBUG ("ID3v2 tag, size: %u bytes", result);
 
@@ -148,31 +148,45 @@
   }
 }
 
+/*
+ * id3v2_ununsync_data:
+ * @unsync_data: Input unsynchronized data
+ * @size: Input data size, updated to output size on return
+ *
+ * Removes unsynchronisation from ID3v2 data by replacing 0xff 0x00 sequences
+ * with 0xff bytes. This is necessary when ID3v2 tags use data 
unsynchronisation
+ * to prevent accidental detection of 0xff 0x00 sync bytes.
+ *
+ * Returns: Newly allocated ununsync'd data, or NULL on error. The caller is
+ * responsible for freeing the returned buffer.  On error, @size is set to 0.
+ */
 guint8 *
 id3v2_ununsync_data (const guint8 * unsync_data, guint32 * size)
 {
-  const guint8 *end;
-  guint8 *out, *uu;
-  guint out_size;
-
-  uu = out = g_malloc (*size);
-
-  for (end = unsync_data + *size; unsync_data < end - 1; ++unsync_data, ++uu) {
-    *uu = *unsync_data;
-    if (G_UNLIKELY (*unsync_data == 0xff && *(unsync_data + 1) == 0x00))
-      ++unsync_data;
-  }
+  gsize in_pos, out_pos;
+  guint8 *out;
 
-  /* take care of last byte (if last two bytes weren't 0xff 0x00) */
-  if (unsync_data < end) {
-    *uu = *unsync_data;
-    ++uu;
+  g_return_val_if_fail (unsync_data != NULL, NULL);
+  g_return_val_if_fail (size != NULL, NULL);
+  g_return_val_if_fail (*size != 0, NULL);
+
+  out = g_malloc (*size);
+  /* Replace any 0xff 0x00 sequence by 0xff */
+  for (in_pos = 0, out_pos = 0; in_pos < *size;) {
+    if ((*size - in_pos > 1) && unsync_data[in_pos] == 0xff
+        && unsync_data[in_pos + 1] == 0x00) {
+      out[out_pos++] = unsync_data[in_pos++];
+      /* Skip escape 0x00 byte */
+      in_pos += 1;
+    } else {
+      out[out_pos++] = unsync_data[in_pos++];
+    }
   }
 
-  out_size = uu - out;
-  GST_DEBUG ("size after un-unsyncing: %u (before: %u)", out_size, *size);
+  GST_DEBUG ("size after un-unsyncing: %" G_GSIZE_FORMAT " (before: %u)",
+      out_pos, *size);
 
-  *size = out_size;
+  *size = out_pos;
   return out;
 }
 
@@ -201,7 +215,7 @@
   read_size = gst_tag_get_id3v2_tag_size (buffer);
 
   /* Ignore tag if it has no frames attached, but skip the header then */
-  if (read_size < ID3V2_HDR_SIZE)
+  if (read_size <= ID3V2_HDR_SIZE)
     return NULL;
 
   gst_buffer_map (buffer, &info, GST_MAP_READ);
@@ -225,6 +239,9 @@
   /* This shouldn't really happen! Caller should have checked first */
   if (info.size < read_size)
     goto not_enough_data;
+  if (flags & ID3V2_HDR_FLAG_FOOTER
+      && read_size <= (ID3V2_HDR_SIZE + ID3V2_FOOTER_SIZE))
+    goto invalid_tag_size;
 
   GST_DEBUG ("Reading ID3v2 tag with revision 2.%d.%d of size %u", version >> 
8,
       version & 0xff, read_size);
@@ -239,9 +256,8 @@
   work.hdr.frame_data = info.data + ID3V2_HDR_SIZE;
 
   if (flags & ID3V2_HDR_FLAG_FOOTER) {
-    if (read_size < ID3V2_HDR_SIZE + 10)
-      goto not_enough_data;     /* Invalid frame size */
-    work.hdr.frame_data_size = read_size - ID3V2_HDR_SIZE - 10;
+    g_assert (read_size >= (ID3V2_HDR_SIZE + ID3V2_FOOTER_SIZE));       /* 
checked above */
+    work.hdr.frame_data_size = read_size - ID3V2_HDR_SIZE - ID3V2_FOOTER_SIZE;
   } else {
     g_assert (read_size >= ID3V2_HDR_SIZE);     /* checked above */
     work.hdr.frame_data_size = read_size - ID3V2_HDR_SIZE;
@@ -275,6 +291,12 @@
     gst_buffer_unmap (buffer, &info);
     return NULL;
   }
+invalid_tag_size:
+  {
+    GST_WARNING ("ID3v2 tag is too small to contain any frames");
+    gst_buffer_unmap (buffer, &info);
+    return NULL;
+  }
 not_enough_data:
   {
     GST_DEBUG
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-base-1.28.2/gst-libs/gst/tag/id3v2.h 
new/gst-plugins-base-1.28.3/gst-libs/gst/tag/id3v2.h
--- old/gst-plugins-base-1.28.2/gst-libs/gst/tag/id3v2.h        2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/tag/id3v2.h        2026-05-11 
19:28:12.000000000 +0200
@@ -26,6 +26,7 @@
 
 #define ID3V2_MARK_SIZE 3
 #define ID3V2_HDR_SIZE GST_TAG_ID3V2_HEADER_SIZE
+#define ID3V2_FOOTER_SIZE GST_TAG_ID3V2_HEADER_SIZE
 
 /* From id3v2.c */
 guint id3v2_read_synch_uint (const guint8 * data, guint size);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/gst-libs/gst/video/gstvideodmabufpool.c 
new/gst-plugins-base-1.28.3/gst-libs/gst/video/gstvideodmabufpool.c
--- old/gst-plugins-base-1.28.2/gst-libs/gst/video/gstvideodmabufpool.c 
2026-04-07 21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/video/gstvideodmabufpool.c 
2026-05-11 19:28:12.000000000 +0200
@@ -209,8 +209,6 @@
   g_main_loop_unref (loop);
   g_main_context_unref (context);
 
-  gst_object_unref (self);
-
   return NULL;
 }
 
@@ -228,7 +226,7 @@
 
   self->thread =
       g_thread_new ("video-dmabuf-pool-source-loop", dmabuf_source_thread,
-      g_object_ref (self));
+      self);
 
   GST_OBJECT_UNLOCK (self);
   return
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/gst-libs/gst/video/video-info-dma.c 
new/gst-plugins-base-1.28.3/gst-libs/gst/video/video-info-dma.c
--- old/gst-plugins-base-1.28.2/gst-libs/gst/video/video-info-dma.c     
2026-04-07 21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-libs/gst/video/video-info-dma.c     
2026-05-11 19:28:12.000000000 +0200
@@ -141,7 +141,7 @@
 {
   GstStructure *structure;
 
-  g_return_val_if_fail (caps != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
 
   if (!gst_caps_is_fixed (caps))
     return FALSE;
@@ -231,7 +231,7 @@
   gboolean ret;
 
   g_return_val_if_fail (drm_info != NULL, FALSE);
-  g_return_val_if_fail (caps != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
 
   if (!gst_video_is_dma_drm_caps (caps))
     return FALSE;
@@ -303,7 +303,7 @@
 {
   GstVideoInfoDmaDrm *ret;
 
-  g_return_val_if_fail (caps != NULL, NULL);
+  g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
 
   if (!gst_video_is_dma_drm_caps (caps))
     return NULL;
@@ -646,6 +646,8 @@
 {
   guint i;
 
+  g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 
DRM_FORMAT_INVALID);
+
   for (i = 0; i < G_N_ELEMENTS (format_map); i++) {
     if (format_map[i].format == format) {
       if (modifier)
@@ -677,6 +679,8 @@
 {
   guint i;
 
+  g_return_val_if_fail (fourcc != DRM_FORMAT_INVALID, 
GST_VIDEO_FORMAT_UNKNOWN);
+
   for (i = 0; i < G_N_ELEMENTS (format_map); i++) {
     if (format_map[i].fourcc == fourcc)
       return format_map[i].format;
@@ -705,6 +709,10 @@
 {
   guint i;
 
+  g_return_val_if_fail (fourcc != DRM_FORMAT_INVALID, 
GST_VIDEO_FORMAT_UNKNOWN);
+  g_return_val_if_fail (modifier != DRM_FORMAT_MOD_INVALID,
+      GST_VIDEO_FORMAT_UNKNOWN);
+
   for (i = 0; i < G_N_ELEMENTS (format_map); i++) {
     if (format_map[i].fourcc == fourcc && format_map[i].modifier == modifier)
       return format_map[i].format;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-base-1.28.2/gst-plugins-base.doap 
new/gst-plugins-base-1.28.3/gst-plugins-base.doap
--- old/gst-plugins-base-1.28.2/gst-plugins-base.doap   2026-04-07 
21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/gst-plugins-base.doap   2026-05-11 
19:28:12.000000000 +0200
@@ -36,6 +36,16 @@
 
  <release>
   <Version>
+   <revision>1.28.3</revision>
+   <branch>1.28</branch>
+   <name></name>
+   <created>2026-05-11</created>
+   <file-release 
rdf:resource="https://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-1.28.3.tar.xz";
 />
+  </Version>
+ </release>
+
+ <release>
+  <Version>
    <revision>1.28.2</revision>
    <branch>1.28</branch>
    <name></name>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-base-1.28.2/meson.build 
new/gst-plugins-base-1.28.3/meson.build
--- old/gst-plugins-base-1.28.2/meson.build     2026-04-07 21:02:23.000000000 
+0200
+++ new/gst-plugins-base-1.28.3/meson.build     2026-05-11 19:28:12.000000000 
+0200
@@ -1,8 +1,9 @@
 project('gst-plugins-base', 'c',
-  version : '1.28.2',
+  version : '1.28.3',
   meson_version : '>= 1.4',
   default_options : [ 'warning_level=1',
-                      'buildtype=debugoptimized' ])
+                      'buildtype=debugoptimized',
+                      'c_std=gnu11,c11' ])
 
 gst_version = meson.project_version()
 version_arr = gst_version.split('.')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/tests/check/elements/audioresample.c 
new/gst-plugins-base-1.28.3/tests/check/elements/audioresample.c
--- old/gst-plugins-base-1.28.2/tests/check/elements/audioresample.c    
2026-04-07 21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/tests/check/elements/audioresample.c    
2026-05-11 19:28:12.000000000 +0200
@@ -25,6 +25,7 @@
 #endif
 
 #include <gst/check/gstcheck.h>
+#include <gst/check/gstharness.h>
 
 #include <gst/audio/audio.h>
 
@@ -1255,6 +1256,125 @@
 
 GST_END_TEST;
 
+/* Test that audioresample does not produce extra output buffers when
+ * receiving GAP-flagged silence buffers (as generated by audiorate to
+ * fill timestamp gaps).
+ *
+ * Harness: audioresample only (8kHz S16LE -> 16kHz S16LE)
+ * Input simulates audiorate output:
+ *   #1  160 samples  pts  0ms
+ *   #2  160 samples  pts 20ms
+ *   #3  160 samples  pts 40ms
+ *   #4  160 samples  pts 60ms
+ *   #5 1120 samples  pts 80ms  GAP      (audiorate-generated silence)
+ *   #6  160 samples  pts 220ms
+ *
+ * Expected output (6 buffers at 16kHz):
+ *   #1  255 samples  pts  0ms           (resampler latency eats 65 samples)
+ *   #2  320 samples  pts 15.9375ms
+ *   #3  320 samples  pts 35.9375ms
+ *   #4  320 samples  pts 55.9375ms
+ *   #5       GAP     pts 75.9375ms      dur 132.0625ms
+ *   #6  320 samples  pts 208ms
+ *
+ * Before the fix, push_drain() in the GAP path produced a 7th buffer
+ * with ~128 extra samples from the FIR filter tail.
+ */
+GST_START_TEST (test_gap_no_extra_samples)
+{
+  GstHarness *h;
+  GstBuffer *buf;
+  GstMapInfo map;
+  guint64 offset = 0;
+  gint i, n_bufs;
+  const gint bpf_in = 2;        /* S16LE mono */
+  const gint bpf_out = 2;
+
+  const struct
+  {
+    gsize samples;
+    GstClockTime pts;
+    GstClockTime duration;
+    gboolean is_gap;
+  } input[] = {
+    {160, 0, 20 * GST_MSECOND, FALSE},
+    {160, 20 * GST_MSECOND, 20 * GST_MSECOND, FALSE},
+    {160, 40 * GST_MSECOND, 20 * GST_MSECOND, FALSE},
+    {160, 60 * GST_MSECOND, 20 * GST_MSECOND, FALSE},
+    {1120, 80 * GST_MSECOND, 140 * GST_MSECOND, TRUE},
+    {160, 220 * GST_MSECOND, 20 * GST_MSECOND, FALSE},
+  };
+
+  const struct
+  {
+    gsize samples;              /* 0 = skip size check (GAP buffers) */
+    GstClockTime pts;
+    GstClockTime duration;
+    gboolean is_gap;
+  } expected[] = {
+    {255, 0, 15937500, FALSE},
+    {320, 15937500, 20 * GST_MSECOND, FALSE},
+    {320, 35937500, 20 * GST_MSECOND, FALSE},
+    {320, 55937500, 20 * GST_MSECOND, FALSE},
+    {0, 75937500, 132062500, TRUE},
+    {320, 208 * GST_MSECOND, 20 * GST_MSECOND, FALSE},
+  };
+
+  h = gst_harness_new ("audioresample");
+
+  gst_harness_set_src_caps_str (h,
+      "audio/x-raw, format=" GST_AUDIO_NE (S16) ", "
+      "rate=8000, channels=1, layout=interleaved");
+  gst_harness_set_sink_caps_str (h,
+      "audio/x-raw, format=" GST_AUDIO_NE (S16) ", "
+      "rate=16000, channels=1, layout=interleaved");
+
+  /* Push input buffers simulating audiorate output */
+  for (i = 0; i < G_N_ELEMENTS (input); i++) {
+    buf = gst_buffer_new_and_alloc (input[i].samples * bpf_in);
+    gst_buffer_map (buf, &map, GST_MAP_WRITE);
+    memset (map.data, 0, map.size);
+    gst_buffer_unmap (buf, &map);
+    GST_BUFFER_PTS (buf) = input[i].pts;
+    GST_BUFFER_DURATION (buf) = input[i].duration;
+    GST_BUFFER_OFFSET (buf) = offset;
+    offset += input[i].samples;
+    GST_BUFFER_OFFSET_END (buf) = offset;
+    if (input[i].is_gap)
+      GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_GAP);
+    gst_harness_push (h, buf);
+  }
+
+  /* Verify exact number of output buffers */
+  n_bufs = gst_harness_buffers_received (h);
+  fail_unless_equals_int (n_bufs, G_N_ELEMENTS (expected));
+
+  /* Verify each output buffer */
+  for (i = 0; i < n_bufs; i++) {
+    buf = gst_harness_pull (h);
+    fail_unless (buf != NULL);
+
+    if (expected[i].samples > 0)
+      fail_unless_equals_int (gst_buffer_get_size (buf),
+          expected[i].samples * bpf_out);
+    fail_unless_equals_uint64 (GST_BUFFER_PTS (buf), expected[i].pts);
+    fail_unless_equals_uint64 (GST_BUFFER_DURATION (buf), 
expected[i].duration);
+
+    if (expected[i].is_gap)
+      fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP),
+          "buffer %d should have GAP flag", i);
+    else
+      fail_if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP),
+          "buffer %d should not have GAP flag", i);
+
+    gst_buffer_unref (buf);
+  }
+
+  gst_harness_teardown (h);
+}
+
+GST_END_TEST;
+
 static Suite *
 audioresample_suite (void)
 {
@@ -1270,6 +1390,7 @@
   tcase_add_test (tc_chain, test_live_switch_downstream);
   tcase_add_test (tc_chain, test_timestamp_drift);
   tcase_add_test (tc_chain, test_fft);
+  tcase_add_test (tc_chain, test_gap_no_extra_samples);
 
 #ifndef GST_DISABLE_PARSE
   tcase_set_timeout (tc_chain, 360);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-base-1.28.2/tests/check/libs/gstglcolorconvert.c 
new/gst-plugins-base-1.28.3/tests/check/libs/gstglcolorconvert.c
--- old/gst-plugins-base-1.28.2/tests/check/libs/gstglcolorconvert.c    
2026-04-07 21:02:23.000000000 +0200
+++ new/gst-plugins-base-1.28.3/tests/check/libs/gstglcolorconvert.c    
2026-05-11 19:28:12.000000000 +0200
@@ -27,6 +27,14 @@
 #include <gst/gl/gl.h>
 #include <gst/gl/gstglfuncs.h>
 
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
+#if defined(__APPLE__) && TARGET_OS_OSX
+#include <gst/gstmacos.h>
+#endif
+
 #include <stdio.h>
 
 static GstGLDisplay *display;
@@ -54,6 +62,14 @@
 static const gchar bgrx_reorder_data[] = { 0x72, 0x24, 0x49, IGNORE_MAGIC };
 static const gchar abgr_reorder_data[] = { 0xff, 0x72, 0x24, 0x49 };
 static const gchar xbgr_reorder_data[] = { IGNORE_MAGIC, 0x72, 0x24, 0x49 };
+static const gchar planar_r_data[] =
+    { 0x49, IGNORE_MAGIC, IGNORE_MAGIC, IGNORE_MAGIC };
+static const gchar planar_g_data[] =
+    { 0x24, IGNORE_MAGIC, IGNORE_MAGIC, IGNORE_MAGIC };
+static const gchar planar_b_data[] =
+    { 0x72, IGNORE_MAGIC, IGNORE_MAGIC, IGNORE_MAGIC };
+static const gchar planar_a_data[] =
+    { 0xff, IGNORE_MAGIC, IGNORE_MAGIC, IGNORE_MAGIC };
 
 static TestFrame test_rgba_reorder[] = {
   {1, 1, GST_VIDEO_FORMAT_RGBA, {(gchar *) & rgba_reorder_data}},
@@ -68,6 +84,22 @@
   {1, 1, GST_VIDEO_FORMAT_BGR, {(gchar *) & bgr_reorder_data}},
 };
 
+static TestFrame test_planar_rgb_reorder[] = {
+  {1, 1, GST_VIDEO_FORMAT_RGBA, {(gchar *) & rgba_reorder_data}},
+  {1, 1, GST_VIDEO_FORMAT_GBR,
+        {(gchar *) planar_g_data, (gchar *) planar_b_data,
+          (gchar *) planar_r_data}},
+  {1, 1, GST_VIDEO_FORMAT_GBRA,
+        {(gchar *) planar_g_data, (gchar *) planar_b_data,
+          (gchar *) planar_r_data, (gchar *) planar_a_data}},
+  {1, 1, GST_VIDEO_FORMAT_RGBP,
+        {(gchar *) planar_r_data, (gchar *) planar_g_data,
+          (gchar *) planar_b_data}},
+  {1, 1, GST_VIDEO_FORMAT_BGRP,
+        {(gchar *) planar_b_data, (gchar *) planar_g_data,
+          (gchar *) planar_r_data}},
+};
+
 #ifndef GST_CAPS_FEATURE_MEMORY_DMABUF
 #define GST_CAPS_FEATURE_MEMORY_DMABUF "memory:DMABuf"
 #endif
@@ -159,7 +191,6 @@
     gint in_width = frames[i].width;
     gint in_height = frames[i].height;
     GstVideoFormat in_v_format = frames[i].v_format;
-    GstVideoFrame in_frame;
     GstCaps *in_caps;
 
     gst_video_info_set_format (&in_info, in_v_format, in_width, in_height);
@@ -183,23 +214,41 @@
 
       mem = gst_gl_base_memory_alloc (base_mem_alloc,
           (GstGLAllocationParams *) params);
+      fail_unless (mem != NULL && gst_is_gl_memory (GST_MEMORY_CAST (mem)),
+          "failed to create GstGLMemory for %s plane %d with GL format 0x%x",
+          gst_video_format_to_string (in_v_format), j, tex_format);
       gst_buffer_append_memory (inbuf, GST_MEMORY_CAST (mem));
 
       gst_gl_allocation_params_free ((GstGLAllocationParams *) params);
     }
 
-    fail_unless (gst_video_frame_map (&in_frame, &in_info, inbuf,
-            GST_MAP_READ));
+    fail_unless_equals_int (gst_buffer_n_memory (inbuf),
+        GST_VIDEO_INFO_N_PLANES (&in_info));
 
-    /* sanity check that the correct values were wrapped */
+    /* Avoid gst_video_frame_map() here: without GstVideoMeta it maps the
+     * whole writable buffer and can replace per-plane memories with one merged
+     * memory, changing the GL input layout this test is exercising. */
     for (j = 0; j < GST_VIDEO_INFO_N_PLANES (&in_info); j++) {
+      GstMemory *mem = gst_buffer_peek_memory (inbuf, j);
+      GstMapInfo map;
       int plane_size = _video_info_plane_size (&in_info, j);
+
+      fail_unless (gst_memory_map (mem, &map, GST_MAP_READ),
+          "failed to map %s input plane %d",
+          gst_video_format_to_string (in_v_format), j);
       for (k = 0; k < plane_size; k++) {
         if (frames[i].data[j][k] != IGNORE_MAGIC)
-          fail_unless (((gchar *) in_frame.data[j])[k] == 
frames[i].data[j][k]);
+          fail_unless (((gchar *) map.data)[k] == frames[i].data[j][k],
+              "%s input mismatch at plane %d offset %d: expected 0x%02x, got 
0x%02x",
+              gst_video_format_to_string (in_v_format), j, k,
+              (guint8) frames[i].data[j][k], (guint8) ((gchar *) map.data)[k]);
       }
+      gst_memory_unmap (mem, &map);
     }
 
+    fail_unless_equals_int (gst_buffer_n_memory (inbuf),
+        GST_VIDEO_INFO_N_PLANES (&in_info));
+
     for (j = 0; j < size; j++) {
       GstBuffer *outbuf;
       GstVideoInfo out_info;
@@ -230,6 +279,9 @@
         const gchar *out_str = gst_video_format_to_string (out_v_format);
         GST_WARNING ("failed to convert from %s to %s", in_str, out_str);
       }
+      fail_unless (outbuf != NULL, "failed to convert from %s to %s",
+          gst_video_format_to_string (in_v_format),
+          gst_video_format_to_string (out_v_format));
 
       fail_unless (gst_video_frame_map (&out_frame, &out_info, outbuf,
               GST_MAP_READ));
@@ -242,7 +294,11 @@
         for (l = 0; l < plane_size; l++) {
           gchar out_pixel = ((gchar *) out_frame.data[k])[l];
           if (out_data[k][l] != IGNORE_MAGIC && out_pixel != IGNORE_MAGIC)
-            fail_unless (out_pixel == out_data[k][l]);
+            fail_unless (out_pixel == out_data[k][l],
+                "%s to %s mismatch at plane %d offset %d: expected 0x%02x, got 
0x%02x",
+                gst_video_format_to_string (in_v_format),
+                gst_video_format_to_string (out_v_format), k, l,
+                (guint8) out_data[k][l], (guint8) out_pixel);
           /* FIXME: check alpha clobbering */
         }
       }
@@ -253,7 +309,6 @@
     }
 
     gst_caps_unref (in_caps);
-    gst_video_frame_unmap (&in_frame);
     gst_buffer_unref (inbuf);
 
     fail_unless_equals_int (ref_count, 0);
@@ -275,6 +330,14 @@
 
 GST_END_TEST;
 
+GST_START_TEST (test_planar_rgb_reorder_buffer)
+{
+  check_conversion (test_planar_rgb_reorder,
+      G_N_ELEMENTS (test_planar_rgb_reorder));
+}
+
+GST_END_TEST;
+
 GST_START_TEST (test_passthrough)
 {
   guint formats_size = G_N_ELEMENTS (test_passthrough_formats);
@@ -410,17 +473,29 @@
 
 GST_START_TEST (test_meta)
 {
+  GstElementFactory *textoverlay_factory;
+  GError *error = NULL;
+  GstElement *pipeline;
+
+  textoverlay_factory = gst_element_factory_find ("textoverlay");
+  if (textoverlay_factory == NULL) {
+    GST_INFO ("Skipping meta test: textoverlay missing");
+    return;
+  }
+  gst_object_unref (textoverlay_factory);
+
   gst_meta_register_custom_simple ("test-glcolorconvert");
 
-  GstElement *pipeline = gst_parse_launch ("videotestsrc "
+  pipeline = gst_parse_launch ("videotestsrc "
       "! video/x-raw,format=YUY2 "
       "! glupload "
       "! textoverlay text=Hello ! textoverlay text=World "
       "! glcolorconvert name=convert "
       "! video/x-raw(ANY),format=RGBA "
-      "! gloverlaycompositor name=comp ! gldownload ! fakesink",
-      NULL);
-  fail_unless (pipeline != NULL);
+      "! gloverlaycompositor name=comp ! gldownload ! fakesink", &error);
+  fail_unless (pipeline != NULL, "Failed to parse pipeline: %s",
+      error ? error->message : "unknown error");
+  g_clear_error (&error);
 
   /* Check buffer before and after glcolorconvert */
   GstElement *conv = gst_bin_get_by_name (GST_BIN (pipeline), "convert");
@@ -450,7 +525,8 @@
   /* Wait for preroll */
   GstState state;
   gst_element_set_state (pipeline, GST_STATE_PAUSED);
-  gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
+  fail_unless_equals_int (gst_element_get_state (pipeline, &state, NULL,
+          GST_SECOND * 10), GST_STATE_CHANGE_SUCCESS);
   fail_unless (state == GST_STATE_PAUSED);
 
   /* Teardown */
@@ -468,6 +544,7 @@
   suite_add_tcase (s, tc_chain);
   tcase_add_checked_fixture (tc_chain, setup, teardown);
   tcase_add_test (tc_chain, test_reorder_buffer);
+  tcase_add_test (tc_chain, test_planar_rgb_reorder_buffer);
   tcase_add_test (tc_chain, test_meta);
   tcase_add_test (tc_chain, test_passthrough);
   /* FIXME add YUV <--> RGB conversion tests */
@@ -475,4 +552,21 @@
   return s;
 }
 
+#if defined(__APPLE__) && TARGET_OS_OSX
+static int
+run_tests (void)
+{
+  Suite *s = gst_gl_color_convert_suite ();
+
+  return gst_check_run_suite_nofork (s, "gst_gl_color_convert", __FILE__);
+}
+
+int
+main (int argc, char **argv)
+{
+  gst_check_init (&argc, &argv);
+  return gst_macos_main_simple ((GstMainFuncSimple) run_tests, NULL);
+}
+#else
 GST_CHECK_MAIN (gst_gl_color_convert);
+#endif

++++++ gst-plugins-base.obsinfo ++++++
--- /var/tmp/diff_new_pack.5tPLVQ/_old  2026-05-13 17:18:49.738027906 +0200
+++ /var/tmp/diff_new_pack.5tPLVQ/_new  2026-05-13 17:18:49.746028240 +0200
@@ -1,5 +1,5 @@
 name: gst-plugins-base
-version: 1.28.2
-mtime: 1775588543
-commit: 43421c2a5b8ac5cceb52b11749df40301e1de5c0
+version: 1.28.3
+mtime: 1778520492
+commit: 62d8936e70b11a2e21ea3c68b7672b675e142945
 

Reply via email to