Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package gstreamer-plugins-bad for 
openSUSE:Factory checked in at 2026-07-12 16:20:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gstreamer-plugins-bad (Old)
 and      /work/SRC/openSUSE:Factory/.gstreamer-plugins-bad.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gstreamer-plugins-bad"

Sun Jul 12 16:20:46 2026 rev:202 rq:1364877 version:1.28.5

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/gstreamer-plugins-bad/gstreamer-plugins-bad.changes  
    2026-06-22 18:05:25.049194931 +0200
+++ 
/work/SRC/openSUSE:Factory/.gstreamer-plugins-bad.new.1991/gstreamer-plugins-bad.changes
    2026-07-12 16:21:20.308374656 +0200
@@ -1,0 +2,61 @@
+Thu Jul  9 17:50:27 UTC 2026 - Bjørn Lie <[email protected]>
+
+- Update to version 1.28.5:
+  + amcviddec: Fix double-free happening when codec gets
+    reconfigured
+  + avtp: Correct ptime generation from avtp timestamp
+  + ccconverter: Use truncated length when converting CEA608 raw to
+    CEA708 CDP
+  + curlsmtpsink: Use the correct content-type if known
+  + d3d12: Fix command list leak
+  + dtlsconnection: Allocate large enough buffer for the peer
+    certificate subject DN
+  + h264parse: Check for enough slice header data being available
+  + h2654parse: Unset GValue in every code path
+  + h265decoder: Fix HEVC with alpha decoding
+  + h266parser: Avoid out-of-bounds read if too many exp slices are
+    signalled
+  + h266parser: Check bounds before writing to CTU entrypoint
+    array
+  + h266parser: Check aspect ratio index against lookup table
+    length
+  + h266parser: Heap-allocate parameter sets before parse to avoid
+    stack overflow
+  + h266parser: Use long bit skipping function for potentially
+    large values
+  + mpeg4videoparse: Ensure enough config data is available before
+    extracting profile/level
+  + mpegpsdemux: Release stream lock when seeking fails
+  + mpegtsmux: Always assign PTS to output buffers in CBR mode
+  + mpegtsmux: Output buffers with PCR-only bitrate-padding packets
+    have wrong PTS
+  + mxfdemux: fix essence track offsets array population
+  + netsim: Fix racy test failures
+  + pcapparse: Add missing bounds checks to ensure packets are
+    large enough
+  + pnmdec: Avoid overflows when calculating frame sizes
+  + qroverlay: Fix use after free bug
+  + rfbsrc: Use correct bpp for copying hextile data
+  + rfbsrc: Validate framebuffer update rectangles against the
+    framebuffer size
+  + rtmp2: Don't retry on G_IO_ERROR_TIMED_OUT
+  + rtmp2: Remove socket timeout after handshake completes
+  + rtpsink: fix mutex not unlocked on invalid URI in set_property
+  + tsdemux: YouTube HLS streams have intermittent corruption
+  + tsdemux: Improve PTS rollover handling in ignore-pcr mode
+  + v4l2decoder: Fix media_fd leak when video_fd open fails
+  + va: surfacecopy: get surface's image in gst_va_surface_copy
+  + va: VOBSUB: compositing error with VA decoder in NV12
+  + va: radeonsi: subtitles cause green flickering
+  + va: radeonsi: Subtitles cause green flickering with VA decoders
+  + videoparsers: Always clear LCEVC enhancement data when
+    resetting frame
+  + videoparsers: Leak of LCEVC user data
+  + vnmdec: Avoid integer overflows when rectangle positions and
+    sizes
+  + vp9parser: Check that enough data is available for parsing
+    superframe info
+  + webrtcbin: validate remote dtls certificates
+  + webrtcsdp: Fix inverted fingerprint existence logic
+
+-------------------------------------------------------------------

Old:
----
  gst-plugins-bad-1.28.4+24.obscpio

New:
----
  gst-plugins-bad-1.28.5.obscpio

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

Other differences:
------------------
++++++ gstreamer-plugins-bad.spec ++++++
--- /var/tmp/diff_new_pack.P7ZyF8/_old  2026-07-12 16:21:22.248441014 +0200
+++ /var/tmp/diff_new_pack.P7ZyF8/_new  2026-07-12 16:21:22.256441287 +0200
@@ -81,7 +81,7 @@
 %endif
 
 Name:           gstreamer-plugins-bad
-Version:        1.28.4+24
+Version:        1.28.5
 Release:        0
 Summary:        GStreamer Streaming-Media Framework Plug-Ins
 License:        LGPL-2.1-or-later

++++++ _service ++++++
--- /var/tmp/diff_new_pack.P7ZyF8/_old  2026-07-12 16:21:22.492449360 +0200
+++ /var/tmp/diff_new_pack.P7ZyF8/_new  2026-07-12 16:21:22.536450865 +0200
@@ -5,7 +5,7 @@
     <param 
name="url">https://gitlab.freedesktop.org/gstreamer/gstreamer.git</param>
     <param name="subdir">subprojects/gst-plugins-bad</param>
     <param name="filename">gst-plugins-bad</param>
-    <param name="revision">6a394d8d</param>
+    <param name="revision">1.28.5</param>
     <param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param>
     <param name="versionrewrite-pattern">v?(.*)\+0</param>
     <param name="versionrewrite-replacement">\1</param>

++++++ gst-plugins-bad-1.28.4+24.obscpio -> gst-plugins-bad-1.28.5.obscpio 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/ext/avtp/gstavtpbasedepayload.c 
new/gst-plugins-bad-1.28.5/ext/avtp/gstavtpbasedepayload.c
--- old/gst-plugins-bad-1.28.4+24/ext/avtp/gstavtpbasedepayload.c       
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/ext/avtp/gstavtpbasedepayload.c  2026-07-08 
23:42:39.000000000 +0200
@@ -246,15 +246,17 @@
   ref_low = ref & 0xFFFFFFFFULL;
   ptime = (ref & 0xFFFFFFFF00000000ULL) | tstamp;
 
-  /* If 'ptime' is less than the our reference time, it means the higher part
-   * from 'ptime' needs to be incremented by 1 in order reflect the correct
-   * presentation time.
+  /* When ever the distance between the reference time and the timestamp
+   * is greater than half the 32-bit range, we adjust the upper 32 bits
+   * of the presentation time to compensate for the rollover of the
+   * avtp or reference timestamp.
    */
-  if (tstamp < G_MAXINT32 && ref_low > G_MAXINT32)
-    ptime += G_MAXUINT32 + 1;
-
-  if (tstamp < G_MAXINT32 && ref_low > G_MAXINT32 && ptime > G_MAXUINT32)
-    ptime -= G_MAXUINT32 + 1;
+  if (tstamp < G_MAXINT32 && ref_low > G_MAXINT32
+      && ref_low - tstamp > G_MAXINT32)
+    ptime += G_GUINT64_CONSTANT (0x100000000);
+  if (tstamp > G_MAXINT32 && ref_low < G_MAXINT32
+      && tstamp - ref_low > G_MAXINT32)
+    ptime -= G_GUINT64_CONSTANT (0x100000000);
 
   GST_LOG_OBJECT (avtpbasedepayload, "AVTP presentation time %" 
GST_TIME_FORMAT,
       GST_TIME_ARGS (ptime));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/ext/curl/gstcurlsmtpsink.c 
new/gst-plugins-bad-1.28.5/ext/curl/gstcurlsmtpsink.c
--- old/gst-plugins-bad-1.28.4+24/ext/curl/gstcurlsmtpsink.c    2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/ext/curl/gstcurlsmtpsink.c       2026-07-08 
23:42:39.000000000 +0200
@@ -572,12 +572,12 @@
     return FALSE;
   }
 
-  hdrs = g_strdup_printf ("\r\n\r\n--%s\r\n"
-      "Content-Type: application/octet-stream; name=\"%s\"\r\n"
+  hdrs = g_strdup_printf ("\r\n\r\n--%s\r\n" "Content-Type: %s; 
name=\"%s\"\r\n"
       /* TODO: support for other encodings */
       "Content-Transfer-Encoding: BASE64\r\n"
       "Content-Disposition: attachment; filename=\"%s\"\r\n\r\n"
-      "\r\n", BOUNDARY_STRING, bcsink->file_name, bcsink->file_name);
+      "\r\n", BOUNDARY_STRING, sink->content_type ? sink->content_type :
+      "application/octet-stream", bcsink->file_name, bcsink->file_name);
   g_byte_array_append (sink->payload_headers, (guint8 *) hdrs, strlen (hdrs));
   g_free (hdrs);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/ext/dtls/gstdtlsconnection.c 
new/gst-plugins-bad-1.28.5/ext/dtls/gstdtlsconnection.c
--- old/gst-plugins-bad-1.28.4+24/ext/dtls/gstdtlsconnection.c  2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/ext/dtls/gstdtlsconnection.c     2026-07-08 
23:42:39.000000000 +0200
@@ -1114,16 +1114,29 @@
   } else {
     bio = BIO_new (BIO_s_mem ());
     if (bio) {
-      gchar buffer[2048];
       gint len;
+      gint read_len;
 
       len =
           X509_NAME_print_ex (bio,
           X509_get_subject_name (X509_STORE_CTX_get0_cert (x509_ctx)), 1,
           XN_FLAG_MULTILINE);
-      BIO_read (bio, buffer, len);
-      buffer[len] = '\0';
-      GST_DEBUG_OBJECT (self, "Peer certificate received:\n%s", buffer);
+
+      if (len > 0) {
+        gchar *buffer;
+
+        buffer = g_new (gchar, (gsize) len + 1);
+        read_len = BIO_read (bio, buffer, len);
+        if (read_len > 0) {
+          buffer[read_len] = '\0';
+          GST_DEBUG_OBJECT (self, "Peer certificate received:\n%s", buffer);
+        } else {
+          GST_DEBUG_OBJECT (self, "failed to read certificate subject");
+        }
+        g_free (buffer);
+      } else {
+        GST_DEBUG_OBJECT (self, "failed to read certificate subject");
+      }
       BIO_free (bio);
     } else {
       GST_DEBUG_OBJECT (self, "failed to create certificate print membio");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/ext/qroverlay/gstqroverlay.c 
new/gst-plugins-bad-1.28.5/ext/qroverlay/gstqroverlay.c
--- old/gst-plugins-bad-1.28.4+24/ext/qroverlay/gstqroverlay.c  2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/ext/qroverlay/gstqroverlay.c     2026-07-08 
23:42:39.000000000 +0200
@@ -97,7 +97,7 @@
       if (gst_structure_get_boolean (meta->structure, "keep_data", &keep_data)
           && keep_data) {
         g_free (self->data);
-        self->data = g_strdup (self->data);
+        self->data = g_strdup (data);
       }
       GST_OBJECT_UNLOCK (self);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/ext/webrtc/gstwebrtcbin.c 
new/gst-plugins-bad-1.28.5/ext/webrtc/gstwebrtcbin.c
--- old/gst-plugins-bad-1.28.4+24/ext/webrtc/gstwebrtcbin.c     2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/ext/webrtc/gstwebrtcbin.c        2026-07-08 
23:42:39.000000000 +0200
@@ -872,6 +872,28 @@
   return stream;
 }
 
+static gboolean
+match_stream_for_dtls_transport (TransportStream * trans,
+    GstWebRTCDTLSTransport * transport)
+{
+  return trans->transport == transport;
+}
+
+static TransportStream *
+_find_transport_for_dtls_transport (GstWebRTCBin * webrtc,
+    GstWebRTCDTLSTransport * transport)
+{
+  TransportStream *stream;
+
+  stream = _find_transport (webrtc, transport,
+      (FindTransportFunc) match_stream_for_dtls_transport);
+
+  GST_TRACE_OBJECT (webrtc,
+      "Found transport %" GST_PTR_FORMAT " for dtls transport %" 
GST_PTR_FORMAT,
+      stream, transport);
+
+  return stream;
+}
 
 typedef gboolean (*FindPadFunc) (GstWebRTCBinPad * p1, gconstpointer data);
 
@@ -2255,9 +2277,62 @@
 }
 
 static void
+validate_transport_fingerprint (GstWebRTCSessionDescription *
+    remote_description, TransportStream * stream)
+{
+  if (!remote_description || !stream) {
+    return;
+  }
+  // early return if the fingerprint has already been validated.
+  if (stream->receive_bin->validated_fingerprint)
+    return;
+
+  GChecksumType checksum;
+  char *fingerprint = _get_fingerprint_from_sdp_media (remote_description->sdp,
+      stream->session_id, &checksum);
+
+  if (!fingerprint)
+    return;
+
+  char *peer_pem;
+  g_object_get (stream->transport, "remote-certificate", &peer_pem, NULL);
+  if (peer_pem) {
+    char *expected_fingerprint =
+        _generate_fingerprint_from_certificate (peer_pem, checksum);
+    if (g_strcmp0 (expected_fingerprint, fingerprint) == 0) {
+      transport_receive_bin_set_data_receive_state (stream->receive_bin,
+          RECEIVE_STATE_PASS);
+      stream->receive_bin->validated_fingerprint = TRUE;
+    }
+
+    g_free (expected_fingerprint);
+    g_free (peer_pem);
+  }
+  g_free (fingerprint);
+}
+
+static void
 _on_dtls_transport_notify_state (GstWebRTCDTLSTransport * transport,
     GParamSpec * pspec, GstWebRTCBin * webrtc)
 {
+  GstWebRTCDTLSTransportState dtls_state;
+
+  g_object_get (transport, "state", &dtls_state, NULL);
+
+  if (dtls_state == GST_WEBRTC_DTLS_TRANSPORT_STATE_CONNECTED) {
+    TransportStream *stream =
+        _find_transport_for_dtls_transport (webrtc, transport);
+    GstWebRTCSessionDescription *sdp = NULL;
+
+    if (webrtc->current_remote_description) {
+      sdp = webrtc->current_remote_description;
+    } else if (webrtc->pending_remote_description) {
+      sdp = webrtc->pending_remote_description;
+    }
+
+    validate_transport_fingerprint (sdp, stream);
+  }
+
   _update_peer_connection_state (webrtc);
 }
 
@@ -6013,7 +6088,7 @@
    * the dtlssrtp elements before the ssl direction has been set which will
    * throw SSL errors */
   if (receive_state != RECEIVE_STATE_UNSET)
-    transport_receive_bin_set_receive_state (stream->receive_bin,
+    transport_receive_bin_set_dtls_receive_state (stream->receive_bin,
         receive_state);
 }
 
@@ -6153,7 +6228,7 @@
   stream->active = TRUE;
 
   receive = TRANSPORT_RECEIVE_BIN (stream->receive_bin);
-  transport_receive_bin_set_receive_state (receive, RECEIVE_STATE_PASS);
+  transport_receive_bin_set_dtls_receive_state (receive, RECEIVE_STATE_PASS);
 }
 
 static gboolean
@@ -6257,6 +6332,7 @@
 
     stream = _get_or_create_transport_stream (webrtc, transport_idx,
         _message_media_is_datachannel (sdp->sdp, transport_idx));
+    validate_transport_fingerprint (webrtc->current_remote_description, 
stream);
     if (!bundled) {
       /* When bundling, these were all set up above, but when not
        * bundling we need to do it now */
@@ -6295,7 +6371,7 @@
      * this bundle is completely inactive */
     GST_LOG_OBJECT (webrtc,
         "All mlines in bundle %u are inactive. Blocking receiver", bundle_idx);
-    transport_receive_bin_set_receive_state (bundle_stream->receive_bin,
+    transport_receive_bin_set_dtls_receive_state (bundle_stream->receive_bin,
         RECEIVE_STATE_BLOCK);
   }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/ext/webrtc/transportreceivebin.c 
new/gst-plugins-bad-1.28.5/ext/webrtc/transportreceivebin.c
--- old/gst-plugins-bad-1.28.4+24/ext/webrtc/transportreceivebin.c      
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/ext/webrtc/transportreceivebin.c 2026-07-08 
23:42:39.000000000 +0200
@@ -30,7 +30,7 @@
  * ;                                                             ;
  * ;  ,-nicesrc-, ,-capsfilter-, ,---queue---, ,-dtlssrtpdec-,   ;
  * ;  ;     src o-o sink   src o-o sink  src o-osink  rtp_srco---o rtp_src
- * ;  '---------' '------------' '-----------' ;             ;   ; 
+ * ;  '---------' '------------' '-----------' ;             ;   ;
  * ;                                           ;     rtcp_srco---o rtcp_src
  * ;                                           ;             ;   ;
  * ;                                           ;     data_srco---o data_src
@@ -109,18 +109,18 @@
 }
 
 void
-transport_receive_bin_set_receive_state (TransportReceiveBin * receive,
+transport_receive_bin_set_dtls_receive_state (TransportReceiveBin * receive,
     ReceiveState state)
 {
   GstWebRTCICEConnectionState icestate;
 
   g_mutex_lock (&receive->pad_block_lock);
-  if (receive->receive_state != state) {
+  if (receive->dtls_receive_state != state) {
     GST_DEBUG_OBJECT (receive, "Requested change of receive state to %s",
         _receive_state_to_string (state));
   }
 
-  receive->receive_state = state;
+  receive->dtls_receive_state = state;
 
   g_object_get (receive->stream->transport->transport, "state", &icestate,
       NULL);
@@ -138,17 +138,13 @@
   if (state == RECEIVE_STATE_PASS) {
     g_object_set (receive->queue, "leaky", 0, NULL);
 
-    if (receive->rtp_block)
-      _free_pad_block (receive->rtp_block);
-    receive->rtp_block = NULL;
-
-    if (receive->rtcp_block)
-      _free_pad_block (receive->rtcp_block);
-    receive->rtcp_block = NULL;
+    if (receive->input_block)
+      _free_pad_block (receive->input_block);
+    receive->input_block = NULL;
   } else {
     g_assert (state == RECEIVE_STATE_BLOCK);
     g_object_set (receive->queue, "leaky", 2, NULL);
-    if (receive->rtp_block == NULL) {
+    if (receive->input_block == NULL) {
       GstWebRTCDTLSTransport *transport;
       GstElement *dtlssrtpdec;
       GstPad *pad, *peer_pad;
@@ -158,9 +154,9 @@
         dtlssrtpdec = transport->dtlssrtpdec;
         pad = gst_element_get_static_pad (dtlssrtpdec, "sink");
         peer_pad = gst_pad_get_peer (pad);
-        receive->rtp_block =
+        receive->input_block =
             _create_pad_block (GST_ELEMENT (receive), peer_pad, 0, NULL, NULL);
-        receive->rtp_block->block_id =
+        receive->input_block->block_id =
             gst_pad_add_probe (peer_pad,
             GST_PAD_PROBE_TYPE_BLOCK |
             GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
@@ -173,11 +169,72 @@
   g_mutex_unlock (&receive->pad_block_lock);
 }
 
+void
+transport_receive_bin_set_data_receive_state (TransportReceiveBin * receive,
+    ReceiveState state)
+{
+  g_mutex_lock (&receive->pad_block_lock);
+  if (receive->data_receive_state != state) {
+    GST_DEBUG_OBJECT (receive, "Requested change of receive state to %s",
+        _receive_state_to_string (state));
+  }
+
+  receive->data_receive_state = state;
+
+  if (state == RECEIVE_STATE_PASS) {
+    if (receive->rtp_block)
+      _free_pad_block (receive->rtp_block);
+    receive->rtp_block = NULL;
+
+    if (receive->rtcp_block)
+      _free_pad_block (receive->rtcp_block);
+    receive->rtcp_block = NULL;
+
+    if (receive->data_block)
+      _free_pad_block (receive->data_block);
+    receive->data_block = NULL;
+  } else {
+    g_assert (state == RECEIVE_STATE_BLOCK);
+
+    if (receive->rtp_block == NULL) {
+      receive->rtp_block =
+          _create_pad_block (GST_ELEMENT (receive), receive->rtp_src, 0, NULL,
+          NULL);
+      receive->rtp_block->block_id =
+          gst_pad_add_probe (receive->rtp_src,
+          GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
+          (GstPadProbeCallback) pad_block, receive, NULL);
+    }
+
+    if (receive->rtcp_block == NULL) {
+      receive->rtcp_block =
+          _create_pad_block (GST_ELEMENT (receive), receive->rtcp_src, 0, NULL,
+          NULL);
+      receive->rtcp_block->block_id =
+          gst_pad_add_probe (receive->rtcp_src,
+          GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
+          (GstPadProbeCallback) pad_block, receive, NULL);
+    }
+
+    if (receive->data_block == NULL) {
+      receive->data_block =
+          _create_pad_block (GST_ELEMENT (receive), receive->data_src, 0, NULL,
+          NULL);
+      receive->data_block->block_id =
+          gst_pad_add_probe (receive->data_src,
+          GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
+          (GstPadProbeCallback) pad_block, receive, NULL);
+    }
+  }
+  g_mutex_unlock (&receive->pad_block_lock);
+}
+
 static void
 _on_notify_ice_connection_state (GstWebRTCICETransport * transport,
     GParamSpec * pspec, TransportReceiveBin * receive)
 {
-  transport_receive_bin_set_receive_state (receive, receive->receive_state);
+  transport_receive_bin_set_dtls_receive_state (receive,
+      receive->dtls_receive_state);
 }
 
 static void
@@ -245,7 +302,10 @@
       /* We want to start blocked, unless someone already switched us
        * to PASS mode. receive_state is set to BLOCKED in _init(),
        * so set up blocks with whatever the mode is now. */
-      transport_receive_bin_set_receive_state (receive, 
receive->receive_state);
+      transport_receive_bin_set_dtls_receive_state (receive,
+          receive->dtls_receive_state);
+      transport_receive_bin_set_data_receive_state (receive,
+          receive->data_receive_state);
 
       /* XXX: because nice needs the nicesrc internal main loop running in 
order
        * correctly STUN... */
@@ -271,6 +331,10 @@
       gst_element_set_locked_state (elem, FALSE);
       gst_element_set_state (elem, GST_STATE_NULL);
 
+      if (receive->input_block)
+        _free_pad_block (receive->input_block);
+      receive->input_block = NULL;
+
       if (receive->rtp_block)
         _free_pad_block (receive->rtp_block);
       receive->rtp_block = NULL;
@@ -279,6 +343,10 @@
         _free_pad_block (receive->rtcp_block);
       receive->rtcp_block = NULL;
 
+      if (receive->data_block)
+        _free_pad_block (receive->data_block);
+      receive->data_block = NULL;
+
       break;
     }
     default:
@@ -311,7 +379,7 @@
 {
   TransportReceiveBin *receive = TRANSPORT_RECEIVE_BIN (object);
   GstWebRTCDTLSTransport *transport;
-  GstPad *ghost, *pad;
+  GstPad *pad;
   GstElement *capsfilter;
   GstCaps *caps;
 
@@ -371,8 +439,8 @@
   /* expose data_src */
   pad = gst_element_request_pad_simple 
(receive->stream->transport->dtlssrtpdec,
       "data_src");
-  ghost = gst_ghost_pad_new ("data_src", pad);
-  gst_element_add_pad (GST_ELEMENT (receive), ghost);
+  receive->data_src = gst_ghost_pad_new ("data_src", pad);
+  gst_element_add_pad (GST_ELEMENT (receive), receive->data_src);
   gst_object_unref (pad);
 
   g_signal_connect_after (receive->stream->transport->transport,
@@ -416,6 +484,7 @@
 static void
 transport_receive_bin_init (TransportReceiveBin * receive)
 {
-  receive->receive_state = RECEIVE_STATE_BLOCK;
+  receive->dtls_receive_state = RECEIVE_STATE_BLOCK;
+  receive->data_receive_state = RECEIVE_STATE_BLOCK;
   g_mutex_init (&receive->pad_block_lock);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/ext/webrtc/transportreceivebin.h 
new/gst-plugins-bad-1.28.5/ext/webrtc/transportreceivebin.h
--- old/gst-plugins-bad-1.28.4+24/ext/webrtc/transportreceivebin.h      
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/ext/webrtc/transportreceivebin.h 2026-07-08 
23:42:39.000000000 +0200
@@ -45,14 +45,17 @@
   TransportStream           *stream;        /* parent transport stream */
 
   GstPad                    *rtp_src;
-  gulong                     rtp_src_probe_id;
   GstPad                    *rtcp_src;
-  gulong                     rtcp_src_probe_id;
+  GstPad                    *data_src;
+  GMutex                     pad_block_lock;
+  ReceiveState               dtls_receive_state;
+  struct pad_block          *input_block;
+  ReceiveState               data_receive_state;
   struct pad_block          *rtp_block;
   struct pad_block          *rtcp_block;
-  GMutex                     pad_block_lock;
-  ReceiveState               receive_state;
+  struct pad_block          *data_block;
   GstElement                *queue;
+  gboolean                   validated_fingerprint;
 };
 
 struct _TransportReceiveBinClass
@@ -60,7 +63,9 @@
   GstBinClass           parent_class;
 };
 
-void        transport_receive_bin_set_receive_state         
(TransportReceiveBin * receive,
+void        transport_receive_bin_set_dtls_receive_state    
(TransportReceiveBin * receive,
+                                                             ReceiveState 
state);
+void        transport_receive_bin_set_data_receive_state    
(TransportReceiveBin * receive,
                                                              ReceiveState 
state);
 
 G_END_DECLS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/ext/webrtc/utils.c 
new/gst-plugins-bad-1.28.5/ext/webrtc/utils.c
--- old/gst-plugins-bad-1.28.4+24/ext/webrtc/utils.c    2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/ext/webrtc/utils.c       2026-07-08 
23:42:39.000000000 +0200
@@ -170,6 +170,25 @@
   }
 }
 
+GChecksumType
+_g_checksum_from_webrtc_string (const char *str)
+{
+  if (g_strcmp0 (str, "sha-1") == 0) {
+    return G_CHECKSUM_SHA1;
+  } else if (g_strcmp0 (str, "sha-256") == 0) {
+    return G_CHECKSUM_SHA256;
+#ifdef G_CHECKSUM_SHA384
+  } else if (g_strcmp0 (str, "sha-284") == 0) {
+    return G_CHECKSUM_SHA384;
+#endif
+  } else if (g_strcmp0 (str, "sha-512") == 0) {
+    return G_CHECKSUM_SHA512;
+  } else {
+    g_warning ("unknown GChecksumType!");
+    return 0;
+  }
+}
+
 void
 _remove_optional_offer_fields (GstCaps * offer_caps)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/ext/webrtc/utils.h 
new/gst-plugins-bad-1.28.5/ext/webrtc/utils.h
--- old/gst-plugins-bad-1.28.4+24/ext/webrtc/utils.h    2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/ext/webrtc/utils.h       2026-07-08 
23:42:39.000000000 +0200
@@ -63,6 +63,8 @@
 G_GNUC_INTERNAL
 const gchar *           _g_checksum_to_webrtc_string (GChecksumType type);
 G_GNUC_INTERNAL
+GChecksumType           _g_checksum_from_webrtc_string (const char *str);
+G_GNUC_INTERNAL
 void                    _remove_optional_offer_fields (GstCaps *offer_caps);
 G_GNUC_INTERNAL
 GstCaps *               _rtp_caps_from_media        (const GstSDPMedia * 
media);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/ext/webrtc/webrtcsdp.c 
new/gst-plugins-bad-1.28.5/ext/webrtc/webrtcsdp.c
--- old/gst-plugins-bad-1.28.4+24/ext/webrtc/webrtcsdp.c        2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/ext/webrtc/webrtcsdp.c   2026-07-08 
23:42:39.000000000 +0200
@@ -125,8 +125,8 @@
     if (direction == GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_INACTIVE)
       continue;
 
-    if (!IS_EMPTY_SDP_ATTRIBUTE (message_fingerprint)
-        && !IS_EMPTY_SDP_ATTRIBUTE (media_fingerprint)) {
+    if (IS_EMPTY_SDP_ATTRIBUTE (message_fingerprint)
+        && IS_EMPTY_SDP_ATTRIBUTE (media_fingerprint)) {
       g_set_error (error, GST_WEBRTC_ERROR,
           GST_WEBRTC_ERROR_FINGERPRINT_FAILURE,
           "No fingerprint lines in sdp for media %u", i);
@@ -749,6 +749,52 @@
   return g_string_free (fingerprint, FALSE);
 }
 
+static char *
+parse_fingerprint (const char *fingerprint, GChecksumType * checksum)
+{
+  const char *loc = g_strstr_len (fingerprint, -1, " ");
+  if (!loc)
+    return NULL;
+
+  char *checksum_s = g_strndup (fingerprint, loc - fingerprint);
+  GChecksumType our_checksum = _g_checksum_from_webrtc_string (checksum_s);
+  g_clear_pointer (&checksum_s, g_free);
+
+  if (!our_checksum)
+    return NULL;
+
+  if (!loc || loc[0] == '\0')
+    return NULL;
+
+  *checksum = our_checksum;
+  return g_strdup (&loc[1]);
+}
+
+gchar *
+_get_fingerprint_from_sdp_media (GstSDPMessage * sdp, guint media_idx,
+    GChecksumType * checksum_type)
+{
+  {
+    /* search in the corresponding media section */
+    const GstSDPMedia *media = gst_sdp_message_get_media (sdp, media_idx);
+    const gchar *fp = gst_sdp_media_get_attribute_val (media, "fingerprint");
+    if (fp) {
+      return parse_fingerprint (fp, checksum_type);
+    }
+  }
+
+  /* then in the sdp message itself */
+  for (int i = 0; i < gst_sdp_message_attributes_len (sdp); i++) {
+    const GstSDPAttribute *attr = gst_sdp_message_get_attribute (sdp, i);
+
+    if (g_strcmp0 (attr->key, "fingerprint") == 0) {
+      return parse_fingerprint (attr->value, checksum_type);
+    }
+  }
+
+  return NULL;
+}
+
 #define DEFAULT_ICE_UFRAG_LEN 32
 #define DEFAULT_ICE_PASSWORD_LEN 32
 static const gchar *ice_credential_chars =
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/ext/webrtc/webrtcsdp.h 
new/gst-plugins-bad-1.28.5/ext/webrtc/webrtcsdp.h
--- old/gst-plugins-bad-1.28.4+24/ext/webrtc/webrtcsdp.h        2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/ext/webrtc/webrtcsdp.h   2026-07-08 
23:42:39.000000000 +0200
@@ -73,6 +73,10 @@
 gchar *                             _generate_fingerprint_from_certificate  
(gchar * certificate,
                                                                              
GChecksumType checksum_type);
 G_GNUC_INTERNAL
+gchar *                             _get_fingerprint_from_sdp_media         
(GstSDPMessage *sdp,
+                                                                             
guint media_idx,
+                                                                             
GChecksumType * checksum_type);
+G_GNUC_INTERNAL
 void                                _generate_ice_credentials               
(gchar ** ufrag,
                                                                              
gchar ** password);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst/closedcaption/ccutils.c 
new/gst-plugins-bad-1.28.5/gst/closedcaption/ccutils.c
--- old/gst-plugins-bad-1.28.4+24/gst/closedcaption/ccutils.c   2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/closedcaption/ccutils.c      2026-07-08 
23:42:39.000000000 +0200
@@ -660,6 +660,20 @@
       != 0;
   guint i;
 
+  if (cea608_1_len > MAX_CEA608_LEN) {
+    GST_WARNING_OBJECT (buf,
+        "Truncating CEA608 data for field 1 of %u bytes to %u bytes",
+        cea608_1_len, MAX_CEA608_LEN);
+    cea608_1_len = MAX_CEA608_LEN;
+  }
+
+  if (cea608_2_len > MAX_CEA608_LEN) {
+    GST_WARNING_OBJECT (buf,
+        "Truncating CEA608 data for field 2 of %u bytes to %u bytes",
+        cea608_2_len, MAX_CEA608_LEN);
+    cea608_2_len = MAX_CEA608_LEN;
+  }
+
   if (cea608_1 && cea608_1_len > 0) {
     guint out_i = 0;
     for (i = 0; i < cea608_1_len / 2; i++) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst/closedcaption/gstccconverter.c 
new/gst-plugins-bad-1.28.5/gst/closedcaption/gstccconverter.c
--- old/gst-plugins-bad-1.28.4+24/gst/closedcaption/gstccconverter.c    
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/closedcaption/gstccconverter.c       
2026-07-08 23:42:39.000000000 +0200
@@ -874,10 +874,10 @@
 
     gst_buffer_map (inbuf, &in, GST_MAP_READ);
     if (self->in_field == 0) {
-      cc_buffer_push_separated (self->cc_buffer, in.data, in.size, NULL, 0,
+      cc_buffer_push_separated (self->cc_buffer, in.data, 2 * n, NULL, 0,
           NULL, 0);
     } else {
-      cc_buffer_push_separated (self->cc_buffer, NULL, 0, in.data, in.size,
+      cc_buffer_push_separated (self->cc_buffer, NULL, 0, in.data, 2 * n,
           NULL, 0);
     }
     gst_buffer_unmap (inbuf, &in);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/gst/librfb/rfbdecoder.c 
new/gst-plugins-bad-1.28.5/gst/librfb/rfbdecoder.c
--- old/gst-plugins-bad-1.28.4+24/gst/librfb/rfbdecoder.c       2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/librfb/rfbdecoder.c  2026-07-08 
23:42:39.000000000 +0200
@@ -952,22 +952,51 @@
 {
   /* fill the whole region with the same color */
 
-  guint32 *offset;
   gint i, j;
 
   if (!rfb_decoder_clip_rectangle (decoder, &x, &y, &w, &h, NULL, NULL))
     return;
 
   for (i = 0; i < h; i++) {
-    offset =
-        (guint32 *) (decoder->frame + ((x + (y +
-                    i) * decoder->rect_width)) * decoder->bytespp);
+    guint8 *offset =
+        decoder->frame + ((x + (y +
+                i) * decoder->rect_width)) * decoder->bytespp;
+
     for (j = 0; j < w; j++) {
-      *(offset++) = color;
+      switch (decoder->bytespp) {
+        case 1:
+          *(guint8 *) offset = (guint8) color;
+          break;
+        case 2:
+          *(guint16 *) offset = (guint16) color;
+          break;
+        case 4:
+          *(guint32 *) offset = color;
+          break;
+        default:
+          /* reject unsupported format */
+          return;
+      }
+      offset += decoder->bytespp;
     }
   }
 }
 
+static inline guint32
+rfb_decoder_get_pixel (RfbDecoder * decoder, const guint8 * data)
+{
+  switch (decoder->bytespp) {
+    case 1:
+      return RFB_GET_UINT8 (data);
+    case 2:
+      return GUINT16_SWAP_LE_BE (RFB_GET_UINT16 (data));
+    case 4:
+      return GUINT32_SWAP_LE_BE (RFB_GET_UINT32 (data));
+    default:
+      return 0;
+  }
+}
+
 static gboolean
 rfb_decoder_rre_encoding (RfbDecoder * decoder, gint start_x, gint start_y,
     gint rect_w, gint rect_h)
@@ -979,7 +1008,7 @@
     return FALSE;
 
   number_of_rectangles = RFB_GET_UINT32 (decoder->data);
-  color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data + 4)));
+  color = rfb_decoder_get_pixel (decoder, decoder->data + 4);
 
   GST_DEBUG ("number of rectangles :%d", number_of_rectangles);
 
@@ -991,7 +1020,7 @@
     if (!rfb_decoder_read (decoder, decoder->bytespp + 8))
       return FALSE;
 
-    color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
+    color = rfb_decoder_get_pixel (decoder, decoder->data);
     x = RFB_GET_UINT16 (decoder->data + decoder->bytespp);
     y = RFB_GET_UINT16 (decoder->data + decoder->bytespp + 2);
     w = RFB_GET_UINT16 (decoder->data + decoder->bytespp + 4);
@@ -1015,7 +1044,7 @@
     return FALSE;
 
   number_of_rectangles = RFB_GET_UINT32 (decoder->data);
-  color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data + 4)));
+  color = rfb_decoder_get_pixel (decoder, decoder->data + 4);
 
   GST_DEBUG ("number of rectangles :%d", number_of_rectangles);
 
@@ -1027,7 +1056,7 @@
     if (!rfb_decoder_read (decoder, decoder->bytespp + 4))
       return FALSE;
 
-    color = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
+    color = rfb_decoder_get_pixel (decoder, decoder->data);
     x = RFB_GET_UINT8 (decoder->data + decoder->bytespp);
     y = RFB_GET_UINT8 (decoder->data + decoder->bytespp + 1);
     w = RFB_GET_UINT8 (decoder->data + decoder->bytespp + 2);
@@ -1077,7 +1106,7 @@
         if (!rfb_decoder_read (decoder, decoder->bytespp))
           return FALSE;
 
-        background = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
+        background = rfb_decoder_get_pixel (decoder, decoder->data);
       }
       rfb_decoder_fill_rectangle (decoder, x, y,
           (x <= x_max_16 ? 16 : x_end), (y <= y_max_16 ? 16 : y_end),
@@ -1087,7 +1116,7 @@
         if (!rfb_decoder_read (decoder, decoder->bytespp))
           return FALSE;
 
-        foreground = GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data)));
+        foreground = rfb_decoder_get_pixel (decoder, decoder->data);
       }
 
       if (subencoding & SUBENCODING_ANYSUBRECTS) {
@@ -1106,8 +1135,7 @@
           return FALSE;
 
         while (nr_subrect--) {
-          foreground =
-              GUINT32_SWAP_LE_BE ((RFB_GET_UINT32 (decoder->data + offset)));
+          foreground = rfb_decoder_get_pixel (decoder, decoder->data + offset);
           offset += decoder->bytespp;
           xy = RFB_GET_UINT8 (decoder->data + offset++);
           wh = RFB_GET_UINT8 (decoder->data + offset++);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst/mpegtsdemux/mpegtspacketizer.c 
new/gst-plugins-bad-1.28.5/gst/mpegtsdemux/mpegtspacketizer.c
--- old/gst-plugins-bad-1.28.4+24/gst/mpegtsdemux/mpegtspacketizer.c    
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/mpegtsdemux/mpegtspacketizer.c       
2026-07-08 23:42:39.000000000 +0200
@@ -2292,21 +2292,48 @@
   pcrtable = get_pcr_table (packetizer, pcr_pid);
 
   if (pcr_pid == 0x1fff && GST_CLOCK_TIME_IS_VALID (packetizer->last_in_time)) 
{
+    /* pcr_pid = 0x1fff means no PCR table, so figure things out from PTSes */
     if (!GST_CLOCK_TIME_IS_VALID (pcrtable->base_time)) {
+      /* Take the first base time we see as a reference */
       pcrtable->base_time = packetizer->last_in_time;
       pcrtable->base_pcrtime = pts;
     } else if (check_diff) {
-      /* Handle discont and wraparound */
+      /* Handle discont and wraparound:
+       * The wraparound handling code assumes that the PCR gets updated 
regularly for
+       * being able to detect wraparounds. With ignore-pcr=true, or with no 
PCR track,
+       * that is not the case and it would stay initialized at 1h forever.
+       * 
+       * To avoid this problem, update the fake PCR whenever the PTS advanced 
by more
+       * than 5s, and also detect wraparounds in these fake PCRs.
+       */
       guint64 tmp_pts = pts + pcrtable->pcroffset + packetizer->extra_shift;
-      if (pcrtable->base_pcrtime < tmp_pts
-          && tmp_pts - pcrtable->base_pcrtime >= 5 * GST_SECOND) {
+      gint64 pcr_pts_diff = tmp_pts - pcrtable->base_pcrtime;
+
+      if (pcrtable->base_pcrtime < tmp_pts &&
+          pcr_pts_diff >= 5 * GST_SECOND &&
+          pcr_pts_diff < PCR_GST_MAX_VALUE / 2 /* Ignore wrap-under */ ) {
         guint64 diff = tmp_pts - pcrtable->base_pcrtime - 2 * GST_SECOND;
 
         pcrtable->base_time += diff;
         pcrtable->base_pcrtime += diff;
+        GST_DEBUG ("base_pcrtime now %" GST_TIMEP_FORMAT " to catch up to PTS 
%"
+            GST_TIMEP_FORMAT, &pcrtable->base_pcrtime, &tmp_pts);
       } else if (pcrtable->base_pcrtime > tmp_pts
           && pcrtable->base_pcrtime - tmp_pts > PCR_GST_MAX_VALUE / 2) {
+        GST_DEBUG ("Incrementing PCR offset for wraparound. base_pcrtime %"
+            GST_TIMEP_FORMAT " adjusted PTS %" GST_TIMEP_FORMAT,
+            &pcrtable->base_pcrtime, &tmp_pts);
         pcrtable->pcroffset += PCR_GST_MAX_VALUE;
+      } else if (pcrtable->base_pcrtime < tmp_pts
+          && tmp_pts - pcrtable->base_pcrtime > PCR_GST_MAX_VALUE / 2) {
+        /* This can happen when we get an out-of-order PTS that steps backward 
to before the
+         * previous rollover. The epoch can flip-flop a bit as we cross over, 
but settles
+         * once every stream advances enough */
+        GST_DEBUG
+            ("Decrementing PCR offset for backward PTS step. base_pcrtime %"
+            GST_TIMEP_FORMAT " adjusted PTS %" GST_TIMEP_FORMAT,
+            &pcrtable->base_pcrtime, &tmp_pts);
+        pcrtable->pcroffset -= PCR_GST_MAX_VALUE;
       }
     }
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst/mpegtsmux/tsmux/tsmux.c 
new/gst-plugins-bad-1.28.5/gst/mpegtsmux/tsmux/tsmux.c
--- old/gst-plugins-bad-1.28.4+24/gst/mpegtsmux/tsmux/tsmux.c   2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/mpegtsmux/tsmux/tsmux.c      2026-07-08 
23:42:39.000000000 +0200
@@ -880,14 +880,14 @@
     return TRUE;
   }
 
-  if (mux->bitrate && do_pcr_checks) {
+  if (mux->bitrate) {
     GST_BUFFER_PTS (buf) =
         gst_util_uint64_scale (mux->n_bytes * 8, GST_SECOND, mux->bitrate);
 
     /* Check and insert a PCR observation for each program if needed,
      * but only for programs that have written their SI at least once,
      * so the stream starts with PAT/PMT */
-    if (mux->first_pcr_ts != G_MININT64) {
+    if (do_pcr_checks && mux->first_pcr_ts != G_MININT64) {
       GList *cur;
 
       for (cur = mux->programs; cur; cur = cur->next) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/gst/pnm/gstpnmdec.c 
new/gst-plugins-bad-1.28.5/gst/pnm/gstpnmdec.c
--- old/gst-plugins-bad-1.28.4+24/gst/pnm/gstpnmdec.c   2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/pnm/gstpnmdec.c      2026-07-08 
23:42:39.000000000 +0200
@@ -140,7 +140,10 @@
       if (pnmdec->mngr.info.encoding == GST_PNM_ENCODING_ASCII) {
         return GST_FLOW_ERROR;
       }
-      pnmdec->size = pnmdec->mngr.info.width * pnmdec->mngr.info.height * 1;
+      if (!g_uint_checked_mul (&pnmdec->size, pnmdec->mngr.info.width,
+              pnmdec->mngr.info.height)) {
+        return GST_FLOW_NOT_NEGOTIATED;
+      }
       fmt = GST_VIDEO_FORMAT_GRAY8;
       break;
     case GST_PNM_TYPE_GRAYMAP:
@@ -150,7 +153,11 @@
         GstStructure *peerstruct;
         const gchar *fmtstr;
 
-        pnmdec->size = pnmdec->mngr.info.width * pnmdec->mngr.info.height * 2;
+        if (!g_uint_checked_mul (&pnmdec->size, pnmdec->mngr.info.width,
+                pnmdec->mngr.info.height)
+            || !g_uint_checked_mul (&pnmdec->size, pnmdec->size, 2)) {
+          return GST_FLOW_NOT_NEGOTIATED;
+        }
         /* perform some basic negotiation to resolve which endianness,
          * if any, is supported by the component downstream. Query
          * the peer caps, intersecting with our preferred caps
@@ -180,14 +187,24 @@
         }
         gst_caps_unref (peercaps);
       } else {
-        pnmdec->size = pnmdec->mngr.info.width * pnmdec->mngr.info.height * 1;
+        if (!g_uint_checked_mul (&pnmdec->size, pnmdec->mngr.info.width,
+                pnmdec->mngr.info.height)) {
+          return GST_FLOW_NOT_NEGOTIATED;
+        }
         fmt = GST_VIDEO_FORMAT_GRAY8;
       }
       break;
     case GST_PNM_TYPE_PIXMAP:
-      pnmdec->size = pnmdec->mngr.info.width * pnmdec->mngr.info.height * 3;
+      if (!g_uint_checked_mul (&pnmdec->size, pnmdec->mngr.info.width,
+              pnmdec->mngr.info.height)
+          || !g_uint_checked_mul (&pnmdec->size, pnmdec->size, 3)) {
+        return GST_FLOW_NOT_NEGOTIATED;
+      }
       fmt = GST_VIDEO_FORMAT_RGB;
       break;
+    case GST_PNM_TYPE_UNKNOWN:
+      fmt = GST_VIDEO_FORMAT_UNKNOWN;
+      break;
   }
 
   if (fmt == GST_VIDEO_FORMAT_UNKNOWN)
@@ -200,7 +217,7 @@
       pnmdec->mngr.info.width, pnmdec->mngr.info.height, pnmdec->input_state);
   gst_video_codec_state_unref (output_state);
 
-  if (gst_video_decoder_negotiate (decoder) == FALSE)
+  if (!gst_video_decoder_negotiate (decoder))
     return GST_FLOW_NOT_NEGOTIATED;
 
   return GST_FLOW_OK;
@@ -211,7 +228,10 @@
 {
   GstPnmdec *pnmdec = (GstPnmdec *) decoder;
 
-  gst_pnmdec_negotiate (decoder);
+  if (pnmdec->mngr.info.type != GST_PNM_TYPE_UNKNOWN) {
+    if (gst_pnmdec_negotiate (decoder) != GST_FLOW_OK)
+      return FALSE;
+  }
 
   if (pnmdec->input_state)
     gst_video_codec_state_unref (pnmdec->input_state);
@@ -230,10 +250,8 @@
     pnmdec->input_state = NULL;
   }
 
-  if (pnmdec->buf) {
-    gst_buffer_unref (pnmdec->buf);
-    pnmdec->buf = NULL;
-  }
+  gst_pnmdec_flush (pnmdec);
+
   return TRUE;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/gst/pnm/gstpnmutils.h 
new/gst-plugins-bad-1.28.5/gst/pnm/gstpnmutils.h
--- old/gst-plugins-bad-1.28.4+24/gst/pnm/gstpnmutils.h 2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/pnm/gstpnmutils.h    2026-07-08 
23:42:39.000000000 +0200
@@ -42,6 +42,7 @@
 
 typedef enum
 {
+  GST_PNM_TYPE_UNKNOWN = 0,
   GST_PNM_TYPE_BITMAP = 1,
   GST_PNM_TYPE_GRAYMAP = 2,
   GST_PNM_TYPE_PIXMAP = 3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/gst/rtp/gstrtpsink.c 
new/gst-plugins-bad-1.28.5/gst/rtp/gstrtpsink.c
--- old/gst-plugins-bad-1.28.4+24/gst/rtp/gstrtpsink.c  2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/rtp/gstrtpsink.c     2026-07-08 
23:42:39.000000000 +0200
@@ -106,11 +106,12 @@
     case PROP_URI:{
       GstUri *uri = NULL;
 
-      GST_RTP_SINK_LOCK (object);
       uri = gst_uri_from_string (g_value_get_string (value));
       if (uri == NULL)
         break;
 
+      GST_RTP_SINK_LOCK (object);
+
       if (self->uri)
         gst_uri_unref (self->uri);
       self->uri = uri;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gsth264parse.c 
new/gst-plugins-bad-1.28.5/gst/videoparsers/gsth264parse.c
--- old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gsth264parse.c       
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/videoparsers/gsth264parse.c  2026-07-08 
23:42:39.000000000 +0200
@@ -214,7 +214,7 @@
 
   gst_video_clear_user_data_unregistered (&h264parse->user_data_unregistered,
       TRUE);
-  gst_video_clear_user_data (&h264parse->user_data, TRUE);
+  gst_video_clear_user_data (&h264parse->user_data);
 
   g_object_unref (h264parse->frame_out);
 
@@ -243,7 +243,7 @@
   h264parse->have_pps_in_frame = FALSE;
   h264parse->have_aud_in_frame = FALSE;
   gst_adapter_clear (h264parse->frame_out);
-  gst_video_clear_user_data (&h264parse->user_data, FALSE);
+  gst_video_clear_user_data (&h264parse->user_data);
   gst_video_clear_user_data_unregistered (&h264parse->user_data_unregistered,
       FALSE);
 }
@@ -1106,7 +1106,8 @@
       h264parse->picture_start = TRUE;
 
       /* don't need to parse the whole slice (header) here */
-      if (*(nalu->data + nalu->offset + nalu->header_bytes) & 0x80) {
+      if (nalu->size > nalu->header_bytes &&
+          *(nalu->data + nalu->offset + nalu->header_bytes) & 0x80) {
         /* means first_mb_in_slice == 0 */
         /* real frame data */
         GST_DEBUG_OBJECT (h264parse, "first_mb_in_slice = 0");
@@ -1927,9 +1928,10 @@
       g_value_unset (&value);
     }
     gst_caps_set_value (caps, "profile", &compat_profiles);
-    g_value_unset (&compat_profiles);
   }
 
+  g_value_unset (&compat_profiles);
+
   return caps;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gsth265parse.c 
new/gst-plugins-bad-1.28.5/gst/videoparsers/gsth265parse.c
--- old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gsth265parse.c       
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/videoparsers/gsth265parse.c  2026-07-08 
23:42:39.000000000 +0200
@@ -215,7 +215,7 @@
   h265parse->layer_id = 0;
   h265parse->temporal_id_plus1 = 0;
   gst_adapter_clear (h265parse->frame_out);
-  gst_video_clear_user_data (&h265parse->user_data, FALSE);
+  gst_video_clear_user_data (&h265parse->user_data);
   gst_video_clear_user_data_unregistered (&h265parse->user_data_unregistered,
       FALSE);
 }
@@ -2074,9 +2074,10 @@
     }
 
     gst_caps_set_value (caps, "profile", &compat_profiles);
-    g_value_unset (&compat_profiles);
   }
 
+  g_value_unset (&compat_profiles);
+
   return caps;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gstmpeg4videoparse.c 
new/gst-plugins-bad-1.28.5/gst/videoparsers/gstmpeg4videoparse.c
--- old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gstmpeg4videoparse.c 
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/videoparsers/gstmpeg4videoparse.c    
2026-07-08 23:42:39.000000000 +0200
@@ -362,10 +362,17 @@
     case GST_MPEG4_VISUAL_OBJ_SEQ_START:
       GST_LOG_OBJECT (mp4vparse, "Visual Sequence Start");
       mp4vparse->config_found = TRUE;
-      mp4vparse->profile = gst_codec_utils_mpeg4video_get_profile (packet->data
-          + packet->offset + 1, packet->offset);
-      mp4vparse->level = gst_codec_utils_mpeg4video_get_level (packet->data
-          + packet->offset + 1, packet->offset);
+      if (packet->size > 1) {
+        mp4vparse->profile =
+            gst_codec_utils_mpeg4video_get_profile (packet->data +
+            packet->offset + 1, packet->size - 1);
+        mp4vparse->level =
+            gst_codec_utils_mpeg4video_get_level (packet->data +
+            packet->offset + 1, packet->size - 1);
+      } else {
+        GST_WARNING_OBJECT (mp4vparse,
+            "VOS packet too short to extract profile/level");
+      }
       break;
     case GST_MPEG4_VISUAL_OBJ:
       GST_LOG_OBJECT (mp4vparse, "Visual Object");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gstmpegvideoparse.c 
new/gst-plugins-bad-1.28.5/gst/videoparsers/gstmpegvideoparse.c
--- old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gstmpegvideoparse.c  
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/videoparsers/gstmpegvideoparse.c     
2026-07-08 23:42:39.000000000 +0200
@@ -196,7 +196,7 @@
   mpvparse->ext_count = 0;
   mpvparse->slice_count = 0;
   mpvparse->slice_offset = 0;
-  gst_video_clear_user_data (&mpvparse->user_data, FALSE);
+  gst_video_clear_user_data (&mpvparse->user_data);
 }
 
 static void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gstvideoparseutils.c 
new/gst-plugins-bad-1.28.5/gst/videoparsers/gstvideoparseutils.c
--- old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gstvideoparseutils.c 
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/videoparsers/gstvideoparseutils.c    
2026-07-08 23:42:39.000000000 +0200
@@ -479,13 +479,12 @@
  * Clears the user data, resetting it for the next frame
  */
 void
-gst_video_clear_user_data (GstVideoParseUserData * user_data, gboolean free)
+gst_video_clear_user_data (GstVideoParseUserData * user_data)
 {
   user_data->closedcaptions_size = 0;
   user_data->bar_data_size = 0;
   user_data->active_format_flag = 0;
-  if (free)
-    g_clear_pointer (&user_data->lcevc_enhancement_data, gst_buffer_unref);
+  g_clear_pointer (&user_data->lcevc_enhancement_data, gst_buffer_unref);
 }
 
 /*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gstvideoparseutils.h 
new/gst-plugins-bad-1.28.5/gst/videoparsers/gstvideoparseutils.h
--- old/gst-plugins-bad-1.28.4+24/gst/videoparsers/gstvideoparseutils.h 
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst/videoparsers/gstvideoparseutils.h    
2026-07-08 23:42:39.000000000 +0200
@@ -207,8 +207,7 @@
                                GstVideoParseUserData * user_data,
                                GstBuffer             * buf);
 
-void gst_video_clear_user_data (GstVideoParseUserData * user_data,
-                                gboolean                free);
+void gst_video_clear_user_data (GstVideoParseUserData * user_data);
 
 
 void gst_video_parse_user_data_unregistered (GstElement                        
* elt,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst-libs/gst/codecparsers/gsth266parser.c 
new/gst-plugins-bad-1.28.5/gst-libs/gst/codecparsers/gsth266parser.c
--- old/gst-plugins-bad-1.28.4+24/gst-libs/gst/codecparsers/gsth266parser.c     
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst-libs/gst/codecparsers/gsth266parser.c        
2026-07-08 23:42:39.000000000 +0200
@@ -360,7 +360,8 @@
     }
 
     /* skip the reserved zero bits */
-    if (!nal_reader_skip (nr, num_additional_bits - num_additional_bits_used))
+    if (!nal_reader_skip_long (nr,
+            num_additional_bits - num_additional_bits_used))
       goto error;
   }
 
@@ -486,9 +487,13 @@
       READ_UINT16 (nr, vui->sar_height, 16);
       vui->par_n = vui->sar_width;
       vui->par_d = vui->sar_height;
-    } else {
+    } else if (vui->aspect_ratio_idc <= 16) {
       vui->par_n = aspect_ratios[vui->aspect_ratio_idc].par_n;
       vui->par_d = aspect_ratios[vui->aspect_ratio_idc].par_d;
+    } else {
+      GST_WARNING ("Invalid bitstream: aspect_ratio_idc set "
+          "to value %d (must be 0-16 or %d)",
+          vui->aspect_ratio_idc, EXTENDED_SAR);
     }
   } else {
     vui->aspect_ratio_constant_flag = 0;
@@ -2168,30 +2173,39 @@
 GstH266ParserResult
 gst_h266_parser_parse_nal (GstH266Parser * parser, GstH266NalUnit * nalu)
 {
-  GstH266VPS vps;
-  GstH266SPS sps;
-  GstH266PPS pps;
-  GstH266APS aps;
+  GstH266ParserResult res = GST_H266_PARSER_OK;
 
   switch (nalu->type) {
-    case GST_H266_NAL_VPS:
-      return gst_h266_parser_parse_vps (parser, nalu, &vps);
+    case GST_H266_NAL_VPS:{
+      GstH266VPS *vps = g_new (GstH266VPS, 1);
+      res = gst_h266_parser_parse_vps (parser, nalu, vps);
+      g_free (vps);
       break;
-    case GST_H266_NAL_SPS:
-      return gst_h266_parser_parse_sps (parser, nalu, &sps);
+    }
+    case GST_H266_NAL_SPS:{
+      GstH266SPS *sps = g_new (GstH266SPS, 1);
+      res = gst_h266_parser_parse_sps (parser, nalu, sps);
+      g_free (sps);
       break;
-    case GST_H266_NAL_PPS:
-      return gst_h266_parser_parse_pps (parser, nalu, &pps);
+    }
+    case GST_H266_NAL_PPS:{
+      GstH266PPS *pps = g_new (GstH266PPS, 1);
+      res = gst_h266_parser_parse_pps (parser, nalu, pps);
+      g_free (pps);
       break;
+    }
     case GST_H266_NAL_PREFIX_APS:
-    case GST_H266_NAL_SUFFIX_APS:
-      return gst_h266_parser_parse_aps (parser, nalu, &aps);
+    case GST_H266_NAL_SUFFIX_APS:{
+      GstH266APS *aps = g_new (GstH266APS, 1);
+      res = gst_h266_parser_parse_aps (parser, nalu, aps);
+      g_free (aps);
       break;
+    }
     default:
       break;
   }
 
-  return GST_H266_PARSER_OK;
+  return res;
 }
 
 /**
@@ -3760,9 +3774,15 @@
           } else {              /* tile contains multi slices */
             guint16 slice_height_in_ctus;
 
+            if (pps->num_exp_slices_in_tile[i] > GST_H266_MAX_TILE_ROWS) {
+              GST_WARNING ("Too many exp slices %d",
+                  pps->num_exp_slices_in_tile[i]);
+              goto error;
+            }
+
             for (j = 0; j < pps->num_exp_slices_in_tile[i]; j++) {
               if (i + j >= pps->num_slices_in_pic_minus1) {
-                GST_WARNING ("Too may slices %d", i + j + 1);
+                GST_WARNING ("Too many slices %d", i + j + 1);
                 goto error;
               }
 
@@ -3786,7 +3806,7 @@
             /* Assign the remaining CTBs to slices */
             while (remaining_height_in_ctbs_y > uniform_slice_height) {
               if (i + j > pps->num_slices_in_pic_minus1) {
-                GST_WARNING ("Too may slices %d", i + j + 1);
+                GST_WARNING ("Too many slices %d", i + j + 1);
                 goto error;
               }
 
@@ -3802,7 +3822,7 @@
 
             if (remaining_height_in_ctbs_y > 0) {
               if (i + j > pps->num_slices_in_pic_minus1) {
-                GST_WARNING ("Too may slices %d", i + j + 1);
+                GST_WARNING ("Too many slices %d", i + j + 1);
                 goto error;
               }
 
@@ -5972,15 +5992,15 @@
           parser->ctb_to_tile_col_bd[pre_ctb_addr_x]
           || (ctb_addr_y != pre_ctb_addr_y
               && sps->entropy_coding_sync_enabled_flag)) {
+        if (sh->num_entry_points >= GST_H266_MAX_ENTRY_POINTS) {
+          GST_WARNING ("Too many entry points: %d.", sh->num_entry_points);
+          goto error;
+        }
         sh->entry_point_start_ctu[sh->num_entry_points] = i;
         sh->num_entry_points++;
       }
     }
 
-    if (sh->num_entry_points > GST_H266_MAX_ENTRY_POINTS) {
-      GST_WARNING ("Too many entry points: %d.", sh->num_entry_points);
-      goto error;
-    }
     if (sh->num_entry_points > 0) {
       READ_UE_MAX (&nr, sh->entry_offset_len_minus1, 31);
       for (i = 0; i < sh->num_entry_points; i++) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst-libs/gst/codecparsers/gstvp9parser.c 
new/gst-plugins-bad-1.28.5/gst-libs/gst/codecparsers/gstvp9parser.c
--- old/gst-plugins-bad-1.28.4+24/gst-libs/gst/codecparsers/gstvp9parser.c      
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst-libs/gst/codecparsers/gstvp9parser.c 
2026-07-08 23:42:39.000000000 +0200
@@ -874,6 +874,9 @@
       superframe_info->frames_in_superframe *
       superframe_info->bytes_per_framesize;
 
+  if (size < superframe_info->superframe_index_size)
+    goto error;
+
   gst_bit_reader_init (ibr,
       data + size - superframe_info->superframe_index_size,
       superframe_info->superframe_index_size);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst-libs/gst/codecs/gsth265decoder.c 
new/gst-plugins-bad-1.28.5/gst-libs/gst/codecs/gsth265decoder.c
--- old/gst-plugins-bad-1.28.4+24/gst-libs/gst/codecs/gsth265decoder.c  
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst-libs/gst/codecs/gsth265decoder.c     
2026-07-08 23:42:39.000000000 +0200
@@ -990,6 +990,18 @@
   GST_LOG_OBJECT (self, "Parsed nal type: %d, offset %d, size %d",
       nalu->type, nalu->offset, nalu->size);
 
+  if (nalu->layer_id != 0) {
+    /* 7.4.2.1
+     * decoders conforming to a profile specified in Annex A and not
+     * supporting the independent non-base layer decoding (INBLD) capability
+     * specified in Annex F shall ignore (i.e., remove from the bitstream
+     * and discard) all NAL units with values of nuh_layer_id not equal to 0
+     */
+    GST_LOG_OBJECT (self, "Skip nalu type %d with layer id %d",
+        nalu->type, nalu->layer_id);
+    return GST_H265_PARSER_OK;
+  }
+
   memset (&decoder_nalu, 0, sizeof (GstH265DecoderNalUnit));
   decoder_nalu.nalu_type = nalu->type;
 
@@ -1181,6 +1193,18 @@
     for (j = 0; j < array->nalu->len; j++) {
       GstH265NalUnit *nalu = &g_array_index (array->nalu, GstH265NalUnit, j);
 
+      if (nalu->layer_id != 0) {
+        /* 7.4.2.1
+         * decoders conforming to a profile specified in Annex A and not
+         * supporting the independent non-base layer decoding (INBLD) 
capability
+         * specified in Annex F shall ignore (i.e., remove from the bitstream
+         * and discard) all NAL units with values of nuh_layer_id not equal to 0
+         */
+        GST_DEBUG_OBJECT (self, "Skip nalu type %d with layer id %d",
+            nalu->type, nalu->layer_id);
+        continue;
+      }
+
       switch (nalu->type) {
         case GST_H265_NAL_VPS:
           pres = gst_h265_parser_parse_vps (parser, nalu, &vps);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst-libs/gst/d3d12/gstd3d12device.cpp 
new/gst-plugins-bad-1.28.5/gst-libs/gst/d3d12/gstd3d12device.cpp
--- old/gst-plugins-bad-1.28.4+24/gst-libs/gst/d3d12/gstd3d12device.cpp 
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst-libs/gst/d3d12/gstd3d12device.cpp    
2026-07-08 23:42:39.000000000 +0200
@@ -2481,6 +2481,8 @@
   cl_base = gst_d3d12_cmd_list_get_handle (gst_cl);
   cl_base.As (&cl);
 
+  gst_d3d12_fence_data_push (fence_data, FENCE_NOTIFY_MINI_OBJECT (gst_cl));
+
   cl->CopyResource (index_buf, index_upload);
   index_buf->AddRef ();
   gst_d3d12_fence_data_push (fence_data, FENCE_NOTIFY_COM (index_buf));
@@ -2578,6 +2580,7 @@
             IID_PPV_ARGS (&gamma_dec_resource));
         if (!gst_d3d12_result (hr, device)) {
           GST_ERROR_OBJECT (device, "Couldn't create LUT texture");
+          gst_d3d12_fence_data_unref (fence_data);
           return hr;
         }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/gst-libs/gst/va/gstvasurfacecopy.c 
new/gst-plugins-bad-1.28.5/gst-libs/gst/va/gstvasurfacecopy.c
--- old/gst-plugins-bad-1.28.4+24/gst-libs/gst/va/gstvasurfacecopy.c    
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst-libs/gst/va/gstvasurfacecopy.c       
2026-07-08 23:42:39.000000000 +0200
@@ -93,6 +93,7 @@
 {
   VAImage image = {.image_id = VA_INVALID_ID, };
   gboolean ret;
+  const gboolean derived = FALSE;
 
   g_return_val_if_fail (self && GST_IS_VA_DISPLAY (self->display), FALSE);
 
@@ -103,9 +104,16 @@
 
   /* TODO: Add the VPP copy. */
 
-  if (!va_ensure_image (self->display, src, &self->info, &image, FALSE))
+  /* TODO: we could change to use derived after
+   * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42345 */
+  if (!va_ensure_image (self->display, src, &self->info, &image, derived))
     return FALSE;
 
+  if (!derived) {
+    if (!va_get_image (self->display, src, &image))
+      return FALSE;
+  }
+
   if ((ret = va_put_image (self->display, dst, &image)))
     GST_LOG ("shallow copy of %#x to %#x", src, dst);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/gst-plugins-bad.doap 
new/gst-plugins-bad-1.28.5/gst-plugins-bad.doap
--- old/gst-plugins-bad-1.28.4+24/gst-plugins-bad.doap  2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/gst-plugins-bad.doap     2026-07-08 
23:42:39.000000000 +0200
@@ -35,6 +35,16 @@
 
  <release>
   <Version>
+   <revision>1.28.5</revision>
+   <branch>1.28</branch>
+   <name></name>
+   <created>2026-07-08</created>
+   <file-release 
rdf:resource="https://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad-1.28.5.tar.xz";
 />
+  </Version>
+ </release>
+
+ <release>
+  <Version>
    <revision>1.28.4</revision>
    <branch>1.28</branch>
    <name></name>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-bad-1.28.4+24/meson.build 
new/gst-plugins-bad-1.28.5/meson.build
--- old/gst-plugins-bad-1.28.4+24/meson.build   2026-06-19 10:13:39.000000000 
+0200
+++ new/gst-plugins-bad-1.28.5/meson.build      2026-07-08 23:42:39.000000000 
+0200
@@ -1,5 +1,5 @@
 project('gst-plugins-bad', 'c', 'cpp',
-  version : '1.28.4.1',
+  version : '1.28.5',
   meson_version : '>= 1.4',
   default_options : [ 'warning_level=1',
                       'buildtype=debugoptimized',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/sys/androidmedia/gstamcvideodec.c 
new/gst-plugins-bad-1.28.5/sys/androidmedia/gstamcvideodec.c
--- old/gst-plugins-bad-1.28.4+24/sys/androidmedia/gstamcvideodec.c     
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/sys/androidmedia/gstamcvideodec.c        
2026-07-08 23:42:39.000000000 +0200
@@ -1793,7 +1793,7 @@
   self->draining = FALSE;
   g_cond_broadcast (&self->drain_cond);
   g_mutex_unlock (&self->drain_lock);
-  g_free (self->codec_data);
+  g_clear_pointer (&self->codec_data, g_free);
   self->codec_data_size = 0;
   if (self->input_state)
     gst_video_codec_state_unref (self->input_state);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/sys/v4l2codecs/gstv4l2decoder.c 
new/gst-plugins-bad-1.28.5/sys/v4l2codecs/gstv4l2decoder.c
--- old/gst-plugins-bad-1.28.4+24/sys/v4l2codecs/gstv4l2decoder.c       
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/sys/v4l2codecs/gstv4l2decoder.c  2026-07-08 
23:42:39.000000000 +0200
@@ -203,6 +203,7 @@
   if (self->video_fd < 0) {
     GST_ERROR_OBJECT (self, "Failed to open '%s': %s",
         self->video_device, g_strerror (errno));
+    gst_v4l2_decoder_close (self);
     return FALSE;
   }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/tests/check/elements/mpegtsdemux.c 
new/gst-plugins-bad-1.28.5/tests/check/elements/mpegtsdemux.c
--- old/gst-plugins-bad-1.28.4+24/tests/check/elements/mpegtsdemux.c    
2026-06-19 10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/tests/check/elements/mpegtsdemux.c       
2026-07-08 23:42:39.000000000 +0200
@@ -19,6 +19,7 @@
  */
 
 #include <gst/gst.h>
+#include <gst/base/gstbasesrc.h>
 #include <gst/check/gstcheck.h>
 #include <gst/check/gstharness.h>
 
@@ -377,6 +378,138 @@
 
 GST_END_TEST;
 
+static void
+handoff_cb (GstElement * fakesink, GstBuffer * buffer, GstPad * pad,
+    GstClockTime * last_ts)
+{
+  GST_LOG ("Buffer %" GST_PTR_FORMAT, buffer);
+
+  /* Just check that the buffer PTS is within 0.1 seconds of the previous
+   * and no gap is introduced at rollover. PTS can go backward too, so
+   * allow for that by checking absolute TS */
+  GstClockTime pts = GST_BUFFER_PTS (buffer);
+
+  if (GST_CLOCK_TIME_IS_VALID (pts)) {
+    if (GST_CLOCK_TIME_IS_VALID (*last_ts)) {
+      GstClockTime pts_diff = ABS (GST_CLOCK_DIFF (*last_ts, pts));
+      GST_LOG ("PTS %" GST_TIMEP_FORMAT " prev %" GST_TIMEP_FORMAT " diff %"
+          GST_TIMEP_FORMAT, &pts, last_ts, &pts_diff);
+      fail_if (pts_diff > 100 * GST_MSECOND);
+    }
+    *last_ts = pts;
+  }
+}
+
+static void
+demux_pad_added (GstElement * demux, GstPad * srcpad, GstElement * pipeline)
+{
+  (void) demux;
+
+  GstCaps *caps = gst_pad_get_current_caps (srcpad);
+  fail_unless (caps != NULL);
+  gst_caps_unref (caps);
+
+  GstElement *sink = gst_bin_get_by_name (GST_BIN (pipeline), "fakesink");
+  fail_if (sink == NULL);
+  GstPad *target = gst_element_get_static_pad (sink, "sink");
+  fail_if (target == NULL);
+
+  GstPadLinkReturn ret = gst_pad_link (srcpad, target);
+  fail_unless (ret == GST_PAD_LINK_OK || ret == GST_PAD_LINK_WAS_LINKED);
+
+  gst_object_unref (target);
+  gst_object_unref (sink);
+}
+
+GST_START_TEST (test_tsdemux_ignore_pcr_rollover)
+{
+  GstClockTime last_ts = GST_CLOCK_TIME_NONE;
+
+  gchar *filepath =
+      g_build_filename (GST_TEST_FILES_PATH, "test_pcr_rollover.ts", NULL);
+  if (!g_file_test (filepath, G_FILE_TEST_EXISTS)) {
+    GST_INFO ("Skipping test, missing file: %s", filepath);
+    g_free (filepath);
+    return;
+  }
+  GST_LOG ("processing file '%s'", filepath);
+
+  char *data;
+  gsize datalen;
+
+  if (!g_file_get_contents (filepath, &data, &datalen, NULL)) {
+    ck_abort_msg ("Failed to read file contents from %s", filepath);
+    g_free (filepath);
+    return;
+  }
+
+  /* We'll send the entire file as a single zero-timestamp
+   * buffer */
+  GstBuffer *buf = gst_buffer_new_wrapped (data, datalen);
+  GST_BUFFER_PTS (buf) = 0;
+
+  GstElement *pipeline = gst_pipeline_new ("pipeline");
+  fail_unless (pipeline != NULL, "Failed to create pipeline!");
+
+  GstBus *bus = gst_element_get_bus (pipeline);
+
+  GstElement *src = gst_element_factory_make ("appsrc", "src");
+  fail_unless (src != NULL, "Failed to create 'appsrc' element!");
+  g_object_set (src, "format", GST_FORMAT_TIME, NULL);
+
+  GstElement *demux = gst_element_factory_make ("tsdemux", "tsdemux");
+  fail_unless (demux != NULL, "Failed to create 'tsdemux' element!");
+  g_object_set (demux, "ignore-pcr", TRUE, NULL);
+  g_signal_connect (demux, "pad-added", G_CALLBACK (demux_pad_added), 
pipeline);
+
+  GstElement *sink = gst_element_factory_make ("fakesink", "fakesink");
+  fail_unless (sink != NULL, "Failed to create 'fakesink' element!");
+
+  g_object_set (sink, "signal-handoffs", TRUE, NULL);
+  g_signal_connect (sink, "handoff", G_CALLBACK (handoff_cb), &last_ts);
+
+  gst_bin_add_many (GST_BIN (pipeline), src, demux, sink, NULL);
+
+  fail_unless (gst_element_link (src, demux));
+
+  GstStateChangeReturn state_ret =
+      gst_element_set_state (pipeline, GST_STATE_PAUSED);
+  fail_unless (state_ret != GST_STATE_CHANGE_FAILURE);
+
+  GstFlowReturn flowret = GST_FLOW_OK;
+  g_signal_emit_by_name (src, "push-buffer", buf, &flowret);
+  fail_unless (flowret == GST_FLOW_OK);
+  gst_buffer_unref (buf);
+
+  g_signal_emit_by_name (src, "end-of-stream", &flowret);
+  fail_unless (flowret == GST_FLOW_OK);
+
+  if (state_ret == GST_STATE_CHANGE_ASYNC) {
+    GST_LOG ("waiting for pipeline to reach PAUSED state");
+    state_ret = gst_element_get_state (pipeline, NULL, NULL, -1);
+    fail_unless_equals_int (state_ret, GST_STATE_CHANGE_SUCCESS);
+  }
+
+  state_ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+  fail_unless (state_ret != GST_STATE_CHANGE_FAILURE);
+
+  GstMessage *msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, 
-1);
+  fail_unless (msg != NULL, "Expected EOS message on bus!");
+  fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
+
+  gst_message_unref (msg);
+
+  fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
+      GST_STATE_CHANGE_SUCCESS);
+
+  gst_object_unref (bus);
+  gst_object_unref (pipeline);
+
+  g_free (filepath);
+}
+
+GST_END_TEST;
+
 static Suite *
 mpegtsdemux_suite (void)
 {
@@ -394,6 +527,7 @@
   tc = tcase_create ("tsdemux");
   suite_add_tcase (s, tc);
   tcase_add_test (tc, test_tsdemux_simple);
+  tcase_add_test (tc, test_tsdemux_ignore_pcr_rollover);
 
   return s;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-bad-1.28.4+24/tests/check/elements/netsim.c 
new/gst-plugins-bad-1.28.5/tests/check/elements/netsim.c
--- old/gst-plugins-bad-1.28.4+24/tests/check/elements/netsim.c 2026-06-19 
10:13:39.000000000 +0200
+++ new/gst-plugins-bad-1.28.5/tests/check/elements/netsim.c    2026-07-08 
23:42:39.000000000 +0200
@@ -9,6 +9,15 @@
   GstHarnessThread *state, *push;
   GstSegment segment;
 
+  gst_check_add_log_filter ("GStreamer", G_LOG_LEVEL_WARNING,
+      g_regex_new ("Got data flow before (stream-start|segment) event",
+          (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL),
+      NULL, NULL, NULL);
+  gst_check_add_log_filter ("GStreamer", G_LOG_LEVEL_WARNING,
+      g_regex_new ("Sticky event misordering",
+          (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL),
+      NULL, NULL, NULL);
+
   gst_segment_init (&segment, GST_FORMAT_TIME);
   state = gst_harness_stress_statechange_start (h);
   push = gst_harness_stress_push_buffer_start (h, caps, &segment, buf);
@@ -33,6 +42,15 @@
   GstHarnessThread *state, *push;
   GstSegment segment;
 
+  gst_check_add_log_filter ("GStreamer", G_LOG_LEVEL_WARNING,
+      g_regex_new ("Got data flow before (stream-start|segment) event",
+          (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL),
+      NULL, NULL, NULL);
+  gst_check_add_log_filter ("GStreamer", G_LOG_LEVEL_WARNING,
+      g_regex_new ("Sticky event misordering",
+          (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL),
+      NULL, NULL, NULL);
+
   gst_harness_set_src_caps (h, gst_caps_ref (caps));
   buf = gst_harness_create_buffer (h, 100);
   gst_segment_init (&segment, GST_FORMAT_TIME);
Binary files old/gst-plugins-bad-1.28.4+24/tests/files/test_pcr_rollover.ts and 
new/gst-plugins-bad-1.28.5/tests/files/test_pcr_rollover.ts differ

++++++ gst-plugins-bad.obsinfo ++++++
--- /var/tmp/diff_new_pack.P7ZyF8/_old  2026-07-12 16:21:28.740660113 +0200
+++ /var/tmp/diff_new_pack.P7ZyF8/_new  2026-07-12 16:21:28.744660247 +0200
@@ -1,5 +1,5 @@
 name: gst-plugins-bad
-version: 1.28.4+24
-mtime: 1781856819
-commit: 6a394d8df25c2440430b1d3ce6cdfb6434fd9b76
+version: 1.28.5
+mtime: 1783546959
+commit: 727ceb91886862d200f423baf36cde2bb7ce5b4d
 

Reply via email to