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