Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package gstreamer-plugins-good for
openSUSE:Factory checked in at 2026-06-13 18:46:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gstreamer-plugins-good (Old)
and /work/SRC/openSUSE:Factory/.gstreamer-plugins-good.new.1981 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gstreamer-plugins-good"
Sat Jun 13 18:46:14 2026 rev:131 rq:1359033 version:1.28.4
Changes:
--------
---
/work/SRC/openSUSE:Factory/gstreamer-plugins-good/gstreamer-plugins-good.changes
2026-05-13 17:19:00.310469612 +0200
+++
/work/SRC/openSUSE:Factory/.gstreamer-plugins-good.new.1981/gstreamer-plugins-good.changes
2026-06-13 18:47:21.093464529 +0200
@@ -1,0 +2,19 @@
+Fri Jun 12 16:14:02 UTC 2026 - Antonio Larrosa <[email protected]>
+
+- Update to version 1.28.4:
+ + matroska-mux: Write ReferenceBlock for non-keyframe video in
+ BlockGroups
+ + osxaudio: Fix stack overflow with >64ch audio devices
+ + qtdemux: parse mastering luminance as u32 instead of u16
+ + qt6: remove an unneeded QOpenGLContext->makeCurrent()
+ + rtph265depay: fix memory leak
+ + sbcparse: Add bounds checking to header parsing
+ + tests: mpegaudioparse: Fix raciness in the state change
+ handling
+ + v4l2: Fix buffer leak on qbuf failure
+ + wavpack: Various channel / channel-mask related fixes
+ + wavpackdec: Avoid integer overflow when calculating output
+ buffer size and related fixes
+ + wavpackenc fails for channels > 2
+
+-------------------------------------------------------------------
Old:
----
gst-plugins-good-1.28.3.obscpio
New:
----
gst-plugins-good-1.28.4.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ gstreamer-plugins-good.spec ++++++
--- /var/tmp/diff_new_pack.3NnkKi/_old 2026-06-13 18:47:23.497564407 +0200
+++ /var/tmp/diff_new_pack.3NnkKi/_new 2026-06-13 18:47:23.513565072 +0200
@@ -33,7 +33,7 @@
%endif
Name: gstreamer-plugins-good
-Version: 1.28.3
+Version: 1.28.4
Release: 0
Summary: GStreamer Streaming-Media Framework Plug-Ins
License: LGPL-2.1-or-later
++++++ _service ++++++
--- /var/tmp/diff_new_pack.3NnkKi/_old 2026-06-13 18:47:23.801577037 +0200
+++ /var/tmp/diff_new_pack.3NnkKi/_new 2026-06-13 18:47:23.833578367 +0200
@@ -5,7 +5,7 @@
<param
name="url">https://gitlab.freedesktop.org/gstreamer/gstreamer.git</param>
<param name="subdir">subprojects/gst-plugins-good</param>
<param name="filename">gst-plugins-good</param>
- <param name="revision">1.28.3</param>
+ <param name="revision">1.28.4</param>
<param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param>
<param name="versionrewrite-pattern">v?(.*)\+0</param>
<param name="versionrewrite-replacement">\1</param>
++++++ gst-plugins-good-1.28.3.obscpio -> gst-plugins-good-1.28.4.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/ext/qt6/qt6glrenderer.cc
new/gst-plugins-good-1.28.4/ext/qt6/qt6glrenderer.cc
--- old/gst-plugins-good-1.28.3/ext/qt6/qt6glrenderer.cc 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/ext/qt6/qt6glrenderer.cc 2026-06-12
14:19:43.000000000 +0200
@@ -489,16 +489,12 @@
/* Invalidating the renderer will cause Qt6 to clear the current
qt-tracked OpenGL context.
* We however may be using the QOpenGLContext for multiple qml6gloverlay
* elements so need to recurrent it */
- if (current_qt_context)
- g_assert (current_qt_context == m_sharedRenderData->m_context);
- else
+ if (current_qt_context != m_sharedRenderData->m_context)
m_sharedRenderData->m_context->makeCurrent(m_sharedRenderData->m_surface);
if (m_renderControl)
m_renderControl->invalidate();
- GST_ERROR ("%p %p", this, QOpenGLContext::currentContext());
-
QEventLoop loop;
if (loop.processEvents())
GST_LOG ("%p pending QEvents processed", this);
@@ -510,9 +506,6 @@
QOpenGLContext::currentContext(), m_sharedRenderData->m_context);
g_assert (QOpenGLContext::currentContext() == nullptr);
- if
(!m_sharedRenderData->m_context->makeCurrent(m_sharedRenderData->m_surface))
- g_warn_if_reached();
-
if (m_sharedRenderData)
shared_render_data_unref (m_sharedRenderData);
m_sharedRenderData = NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackcommon.c
new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackcommon.c
--- old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackcommon.c 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackcommon.c 2026-06-12
14:19:43.000000000 +0200
@@ -95,10 +95,10 @@
return TRUE;
}
-gint
+guint32
gst_wavpack_get_default_channel_mask (gint nchannels)
{
- gint channel_mask = 0;
+ guint32 channel_mask = 0;
/* Set the default channel mask for the given number of channels.
* It's the same as for WAVE_FORMAT_EXTENDED:
@@ -168,7 +168,7 @@
#define MAX_CHANNEL_POSITIONS G_N_ELEMENTS (layout_mapping)
gboolean
-gst_wavpack_get_channel_positions (gint num_channels, gint layout,
+gst_wavpack_get_channel_positions (gint num_channels, guint32 layout,
GstAudioChannelPosition * pos)
{
gint i, p;
@@ -181,54 +181,28 @@
p = 0;
for (i = 0; i < MAX_CHANNEL_POSITIONS; ++i) {
if ((layout & layout_mapping[i].ms_mask) != 0) {
- if (p >= num_channels) {
- GST_WARNING ("More bits set in the channel layout map than there "
- "are channels! Broken file");
- return FALSE;
- }
- if (layout_mapping[i].gst_pos == GST_AUDIO_CHANNEL_POSITION_INVALID) {
- GST_WARNING ("Unsupported channel position (mask 0x%08x) in channel "
- "layout map - ignoring those channels", layout_mapping[i].ms_mask);
- /* what to do? just ignore it and let downstream deal with a channel
- * layout that has INVALID positions in it for now ... */
- }
pos[p] = layout_mapping[i].gst_pos;
++p;
}
}
+ // Not all channels found, consider it unpositioned
if (p != num_channels) {
- GST_WARNING ("Only %d bits set in the channel layout map, but there are "
- "supposed to be %d channels! Broken file", p, num_channels);
+ for (i = 0; i < MIN (64, num_channels); i++)
+ pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
return FALSE;
}
return TRUE;
}
-GstAudioChannelPosition *
-gst_wavpack_get_default_channel_positions (gint nchannels)
-{
- GstAudioChannelPosition *pos = g_new (GstAudioChannelPosition, nchannels);
- gint i;
-
- if (nchannels == 1) {
- pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
- return pos;
- }
-
- for (i = 0; i < nchannels; i++)
- pos[i] = layout_mapping[i].gst_pos;
-
- return pos;
-}
-
-gint
-gst_wavpack_get_channel_mask_from_positions (GstAudioChannelPosition * pos,
- gint nchannels)
+guint32
+gst_wavpack_get_channel_mask_from_positions (const GstAudioChannelPosition *
+ pos, gint nchannels)
{
- gint channel_mask = 0;
+ guint32 channel_mask = 0;
gint i, j;
+ gint found_channels = 0;
if (nchannels == 1 && pos[0] == GST_AUDIO_CHANNEL_POSITION_MONO) {
channel_mask = 0x00000004;
@@ -241,30 +215,44 @@
for (j = 0; j < MAX_CHANNEL_POSITIONS; j++) {
if (pos[i] == layout_mapping[j].gst_pos) {
channel_mask |= layout_mapping[j].ms_mask;
+ found_channels++;
break;
}
}
}
+ // If not all channels were found consider it unpositioned
+ if (found_channels != nchannels)
+ channel_mask = 0;
+
return channel_mask;
}
gboolean
-gst_wavpack_set_channel_mapping (GstAudioChannelPosition * pos, gint nchannels,
- gint8 * channel_mapping)
+gst_wavpack_set_channel_mapping (const GstAudioChannelPosition * pos,
+ gint nchannels, gint8 * channel_mapping)
{
gint i, j;
gboolean ret = TRUE;
+ gint found_channels = 0;
for (i = 0; i < nchannels; i++) {
for (j = 0; j < MAX_CHANNEL_POSITIONS; j++) {
if (pos[i] == layout_mapping[j].gst_pos) {
channel_mapping[i] = j;
ret &= (i == j);
+ found_channels++;
break;
}
}
}
+ // If not all channels were found, don't reorder anything and consider
+ // it unpositioned
+ if (found_channels != nchannels) {
+ memset (channel_mapping, 0, MIN (64, nchannels));
+ ret = TRUE;
+ }
+
return !ret;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackcommon.h
new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackcommon.h
--- old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackcommon.h 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackcommon.h 2026-06-12
14:19:43.000000000 +0200
@@ -66,10 +66,9 @@
gboolean gst_wavpack_read_header (WavpackHeader * header, guint8 * buf);
gboolean gst_wavpack_read_metadata (GstWavpackMetadata * meta,
guint8 * header_data, guint8 ** p_data);
-gint gst_wavpack_get_default_channel_mask (gint nchannels);
-gboolean gst_wavpack_get_channel_positions (gint nchannels, gint layout,
GstAudioChannelPosition *pos);
-GstAudioChannelPosition *gst_wavpack_get_default_channel_positions (gint
nchannels);
-gint gst_wavpack_get_channel_mask_from_positions (GstAudioChannelPosition
*pos, gint nchannels);
-gboolean gst_wavpack_set_channel_mapping (GstAudioChannelPosition *pos, gint
nchannels, gint8 *channel_mapping);
+guint32 gst_wavpack_get_default_channel_mask (gint nchannels);
+gboolean gst_wavpack_get_channel_positions (gint nchannels, guint32 layout,
GstAudioChannelPosition *pos);
+guint32 gst_wavpack_get_channel_mask_from_positions (const
GstAudioChannelPosition *pos, gint nchannels);
+gboolean gst_wavpack_set_channel_mapping (const GstAudioChannelPosition *pos,
gint nchannels, gint8 *channel_mapping);
#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackdec.c
new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackdec.c
--- old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackdec.c 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackdec.c 2026-06-12
14:19:43.000000000 +0200
@@ -130,6 +130,7 @@
dec->channels = 0;
dec->channel_mask = 0;
+ dec->need_reorder = FALSE;
dec->sample_rate = 0;
dec->depth = 0;
dec->depth_shift = 0;
@@ -238,7 +239,8 @@
if (dec->channel_mask) {
if (!gst_wavpack_get_channel_positions (dec->channels,
dec->channel_mask, pos))
- GST_WARNING_OBJECT (dec, "Failed to set channel layout");
+ GST_WARNING_OBJECT (dec,
+ "Unsupported channel layout -- mapping to unpositioned channels");
}
gst_audio_info_init (&info);
@@ -249,6 +251,10 @@
gst_audio_channel_positions_to_valid_order (info.position, info.channels);
gst_audio_get_channel_reorder_map (info.channels,
info.position, pos, dec->channel_reorder_map);
+ dec->need_reorder =
+ memcmp (pos, info.position, dec->channels * sizeof (pos[0])) != 0;
+ } else {
+ dec->need_reorder = FALSE;
}
/* should always succeed */
@@ -308,10 +314,12 @@
GstBuffer *outbuf = NULL;
GstFlowReturn ret = GST_FLOW_OK;
WavpackHeader wph;
- int32_t decoded, unpacked_size;
- gint width, depth_shift, i, j, num_samples, wavpack_mode;
+ gint width, depth_shift, wavpack_mode;
gboolean mode_float;
gint32 *dec_data = NULL;
+ gsize i, j, dec_data_size, unpacked_size, num_samples;
+ uint32_t decoded;
+ guint64 offset;
guint8 *out_data;
GstMapInfo map, omap;
@@ -328,7 +336,7 @@
if (!gst_wavpack_read_header (&wph, map.data))
goto invalid_header;
- if (map.size < wph.ckSize + 4 * 1 + 4)
+ if (map.size - 4 * 1 - 4 < wph.ckSize)
goto input_not_framed;
if (!(wph.flags & INITIAL_BLOCK))
@@ -378,10 +386,17 @@
g_assert (dec->context != NULL);
/* alloc output buffer */
- dec_data = g_malloc (4 * wph.block_samples * dec->channels);
+ dec_data_size = 4;
+ if (!g_size_checked_mul (&dec_data_size, dec_data_size, wph.block_samples) ||
+ !g_size_checked_mul (&dec_data_size, dec_data_size, dec->channels))
+ goto invalid_header;
+ dec_data = g_malloc (dec_data_size);
+ offset = GST_BUFFER_OFFSET (buf);
/* decode */
decoded = WavpackUnpackSamples (dec->context, dec_data, wph.block_samples);
+ gst_buffer_unmap (buf, &map);
+ buf = NULL;
if (decoded != wph.block_samples)
goto decode_error;
@@ -393,7 +408,7 @@
outbuf = gst_audio_decoder_allocate_output_buffer (bdec, unpacked_size);
/* legacy; pass along offset, whatever that might entail */
- GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buf);
+ GST_BUFFER_OFFSET (outbuf) = offset;
gst_buffer_map (outbuf, &omap, GST_MAP_WRITE);
out_data = omap.data;
@@ -401,33 +416,76 @@
switch (width) {
case 8:{
gint8 *outbuffer = (gint8 *) out_data;
- gint *reorder_map = dec->channel_reorder_map;
- for (i = 0; i < num_samples; i += dec->channels) {
- for (j = 0; j < dec->channels; j++)
- *outbuffer++ = (gint8) (dec_data[i + reorder_map[j]]);
+ if (dec->need_reorder) {
+ const gint *reorder_map = dec->channel_reorder_map;
+
+ for (i = 0; i < num_samples; i += dec->channels) {
+ for (j = 0; j < dec->channels; j++)
+ *outbuffer++ = (gint8) (dec_data[i + reorder_map[j]]);
+ }
+ } else {
+ for (i = 0; i < num_samples; i++)
+ *outbuffer++ = (gint8) (dec_data[i]);
}
break;
}
case 16:{
gint16 *outbuffer = (gint16 *) out_data;
- gint *reorder_map = dec->channel_reorder_map;
- for (i = 0; i < num_samples; i += dec->channels) {
- for (j = 0; j < dec->channels; j++)
- *outbuffer++ = (gint16) (dec_data[i + reorder_map[j]]);
+ if (dec->need_reorder) {
+ const gint *reorder_map = dec->channel_reorder_map;
+
+ for (i = 0; i < num_samples; i += dec->channels) {
+ for (j = 0; j < dec->channels; j++)
+ *outbuffer++ = (gint16) (dec_data[i + reorder_map[j]]);
+ }
+ } else {
+ for (i = 0; i < num_samples; i++)
+ *outbuffer++ = (gint16) (dec_data[i]);
}
break;
}
case 24:{
guint8 *outbuffer = (guint8 *) out_data;
- gint *reorder_map = dec->channel_reorder_map;
- if (depth_shift) {
- for (i = 0; i < num_samples; i += dec->channels) {
- for (j = 0; j < dec->channels; j++) {
- gint32 sample =
- (gint32) (dec_data[i + reorder_map[j]]) >> depth_shift;
+ if (dec->need_reorder) {
+ const gint *reorder_map = dec->channel_reorder_map;
+
+ if (depth_shift) {
+ for (i = 0; i < num_samples; i += dec->channels) {
+ for (j = 0; j < dec->channels; j++) {
+ gint32 sample =
+ (gint32) (dec_data[i + reorder_map[j]]) >> depth_shift;
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ GST_WRITE_UINT24_LE (outbuffer, sample);
+#else
+ GST_WRITE_UINT24_BE (outbuffer, sample);
+#endif
+
+ outbuffer += 3;
+ }
+ }
+ } else {
+ for (i = 0; i < num_samples; i += dec->channels) {
+ for (j = 0; j < dec->channels; j++) {
+ gint32 sample = (gint32) (dec_data[i + reorder_map[j]]);
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ GST_WRITE_UINT24_LE (outbuffer, sample);
+#else
+ GST_WRITE_UINT24_BE (outbuffer, sample);
+#endif
+
+ outbuffer += 3;
+ }
+ }
+ }
+ } else {
+ if (depth_shift) {
+ for (i = 0; i < num_samples; i++) {
+ gint32 sample = (gint32) (dec_data[i]) >> depth_shift;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
GST_WRITE_UINT24_LE (outbuffer, sample);
@@ -437,11 +495,9 @@
outbuffer += 3;
}
- }
- } else {
- for (i = 0; i < num_samples; i += dec->channels) {
- for (j = 0; j < dec->channels; j++) {
- gint32 sample = (gint32) (dec_data[i + reorder_map[j]]);
+ } else {
+ for (i = 0; i < num_samples; i++) {
+ gint32 sample = (gint32) (dec_data[i]);
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
GST_WRITE_UINT24_LE (outbuffer, sample);
@@ -457,11 +513,17 @@
}
case 32:{
gint32 *outbuffer = (gint32 *) out_data;
- gint *reorder_map = dec->channel_reorder_map;
- for (i = 0; i < num_samples; i += dec->channels) {
- for (j = 0; j < dec->channels; j++)
- *outbuffer++ = (gint32) (dec_data[i + reorder_map[j]]);
+ if (dec->need_reorder) {
+ const gint *reorder_map = dec->channel_reorder_map;
+
+ for (i = 0; i < num_samples; i += dec->channels) {
+ for (j = 0; j < dec->channels; j++)
+ *outbuffer++ = (gint32) (dec_data[i + reorder_map[j]]);
+ }
+ } else {
+ for (i = 0; i < num_samples; i++)
+ *outbuffer++ = (gint32) (dec_data[i]);
}
break;
}
@@ -470,9 +532,6 @@
}
gst_buffer_unmap (outbuf, &omap);
- gst_buffer_unmap (buf, &map);
- buf = NULL;
-
g_free (dec_data);
ret = gst_audio_decoder_finish_frame (bdec, outbuf, 1);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackdec.h
new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackdec.h
--- old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackdec.h 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackdec.h 2026-06-12
14:19:43.000000000 +0200
@@ -51,10 +51,11 @@
gint depth, depth_shift;
gint width;
gint channels;
- gint channel_mask;
+ guint32 channel_mask;
gboolean mode_float;
gint channel_reorder_map[64];
+ gboolean need_reorder;
};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackenc.c
new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackenc.c
--- old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackenc.c 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackenc.c 2026-06-12
14:19:43.000000000 +0200
@@ -383,7 +383,7 @@
gst_wavpack_enc_set_format (GstAudioEncoder * benc, GstAudioInfo * info)
{
GstWavpackEnc *enc = GST_WAVPACK_ENC (benc);
- GstAudioChannelPosition *pos;
+ const GstAudioChannelPosition *pos;
GstAudioChannelPosition opos[64] = { GST_AUDIO_CHANNEL_POSITION_INVALID, };
GstCaps *caps;
guint64 mask = 0;
@@ -398,21 +398,24 @@
enc->float_mode = GST_AUDIO_INFO_FORMAT (info) == GST_AUDIO_FORMAT_F32;
pos = info->position;
- g_assert (pos);
- /* If one channel is NONE they'll be all undefined */
- if (pos != NULL && pos[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
- goto invalid_channels;
- }
-
- enc->channel_mask =
- gst_wavpack_get_channel_mask_from_positions (pos, enc->channels);
- enc->need_channel_remap =
- gst_wavpack_set_channel_mapping (pos, enc->channels,
- enc->channel_mapping);
+ if (pos[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
+ enc->channel_mask = 0;
+ enc->need_channel_remap = FALSE;
+ } else {
+ enc->channel_mask =
+ gst_wavpack_get_channel_mask_from_positions (pos, enc->channels);
+ if (enc->channel_mask == 0)
+ GST_WARNING_OBJECT (enc,
+ "Unsupported channel layout -- mapping to unpositioned channels");
+
+ enc->need_channel_remap =
+ gst_wavpack_set_channel_mapping (pos, enc->channels,
+ enc->channel_mapping);
- /* wavpack caps hold gst mask, not wavpack mask */
- gst_audio_channel_positions_to_mask (opos, enc->channels, FALSE, &mask);
+ /* wavpack caps hold gst mask, not wavpack mask */
+ gst_audio_channel_positions_to_mask (opos, enc->channels, FALSE, &mask);
+ }
/* set fixed src pad caps now that we know what we will get */
caps = gst_caps_new_simple ("audio/x-wavpack",
@@ -443,11 +446,6 @@
gst_caps_unref (caps);
return FALSE;
}
-invalid_channels:
- {
- GST_DEBUG_OBJECT (enc, "input has invalid channel layout");
- return FALSE;
- }
}
static void
@@ -673,7 +671,7 @@
gint nsamples)
{
gint i, j;
- gint32 tmp[8];
+ gint32 *tmp = g_newa (gint32, enc->channels);
for (i = 0; i < nsamples / enc->channels; i++) {
for (j = 0; j < enc->channels; j++) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackenc.h
new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackenc.h
--- old/gst-plugins-good-1.28.3/ext/wavpack/gstwavpackenc.h 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/ext/wavpack/gstwavpackenc.h 2026-06-12
14:19:43.000000000 +0200
@@ -55,7 +55,7 @@
gint samplerate;
gint channels;
- gint channel_mask;
+ guint32 channel_mask;
gint8 channel_mapping[64];
gboolean need_channel_remap;
gint width, depth;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-good-1.28.3/gst/audioparsers/gstsbcparse.c
new/gst-plugins-good-1.28.4/gst/audioparsers/gstsbcparse.c
--- old/gst-plugins-good-1.28.3/gst/audioparsers/gstsbcparse.c 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/gst/audioparsers/gstsbcparse.c 2026-06-12
14:19:43.000000000 +0200
@@ -76,7 +76,7 @@
static guint8 gst_sbc_calculate_crc8 (const guint8 * data, gint bits_crc);
static gsize gst_sbc_calc_framelen (guint subbands, GstSbcChannelMode ch_mode,
guint blocks, guint bitpool);
-static gsize gst_sbc_parse_header (const guint8 * data, guint * rate,
+static gsize gst_sbc_parse_header (const guint8 * data, gsize len, guint *
rate,
guint * n_blocks, GstSbcChannelMode * ch_mode,
GstSbcAllocationMethod * alloc_method, guint * n_subbands, guint *
bitpool);
@@ -196,9 +196,8 @@
gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
- g_assert (map.size >= 6);
-
- frame_len = gst_sbc_parse_header (map.data, &rate, &n_blocks, &ch_mode,
+ frame_len =
+ gst_sbc_parse_header (map.data, map.size, &rate, &n_blocks, &ch_mode,
&alloc_method, &n_subbands, &bitpool);
GST_LOG_OBJECT (parse, "frame_len: %u", (guint) frame_len);
@@ -255,8 +254,10 @@
GST_LOG_OBJECT (sbcparse, "parsing up to %d frames", max_frames);
for (i = 1; i < max_frames; ++i) {
- next_len = gst_sbc_parse_header (map.data + (i * frame_len), &rate,
- &n_blocks, &ch_mode, &alloc_method, &n_subbands, &bitpool);
+ next_len =
+ gst_sbc_parse_header (map.data + (i * frame_len),
+ map.size - (i * frame_len), &rate, &n_blocks, &ch_mode, &alloc_method,
+ &n_subbands, &bitpool);
if (next_len != frame_len || sbcparse->alloc_method != alloc_method ||
sbcparse->ch_mode != ch_mode || sbcparse->rate != rate ||
@@ -440,15 +441,17 @@
}
static gsize
-gst_sbc_parse_header (const guint8 * data, guint * rate, guint * n_blocks,
- GstSbcChannelMode * ch_mode, GstSbcAllocationMethod * alloc_method,
- guint * n_subbands, guint * bitpool)
+gst_sbc_parse_header (const guint8 * data, gsize len, guint * rate,
+ guint * n_blocks, GstSbcChannelMode * ch_mode,
+ GstSbcAllocationMethod * alloc_method, guint * n_subbands, guint * bitpool)
{
static const guint16 sbc_rates[4] = { 16000, 32000, 44100, 48000 };
static const guint8 sbc_blocks[4] = { 4, 8, 12, 16 };
guint8 crc_data[2 + 1 + 8], crc_bits, i;
- GST_MEMDUMP ("header", data, 8);
+ if (len < 7)
+ return 0;
+ GST_MEMDUMP ("header", data, 7);
if (data[0] != SBC_SYNCBYTE)
return 0;
@@ -482,6 +485,12 @@
else
crc_bits += *n_subbands * 2 * 4;
+ if (len < 1 + (crc_bits + 7) / 8 + 1) {
+ GST_LOG ("not enough header data available for CRC check, got %"
+ G_GSIZE_FORMAT ", expected %u", len, 1 + (crc_bits + 7) / 8 + 1);
+ return 0;
+ }
+
for (i = 16; i < crc_bits; i += 8) {
crc_data[i / 8] = data[1 + (i / 8) + 1];
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-good-1.28.3/gst/audioparsers/gstwavpackparse.c
new/gst-plugins-good-1.28.4/gst/audioparsers/gstwavpackparse.c
--- old/gst-plugins-good-1.28.3/gst/audioparsers/gstwavpackparse.c
2026-05-11 19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/gst/audioparsers/gstwavpackparse.c
2026-06-12 14:19:43.000000000 +0200
@@ -167,10 +167,10 @@
return TRUE;
}
-static gint
+static guint32
gst_wavpack_get_default_channel_mask (gint nchannels)
{
- gint channel_mask = 0;
+ guint32 channel_mask = 0;
/* Set the default channel mask for the given number of channels.
* It's the same as for WAVE_FORMAT_EXTENDED:
@@ -240,7 +240,7 @@
#define MAX_CHANNEL_POSITIONS G_N_ELEMENTS (layout_mapping)
static gboolean
-gst_wavpack_get_channel_positions (gint num_channels, gint layout,
+gst_wavpack_get_channel_positions (gint num_channels, guint32 layout,
GstAudioChannelPosition * pos)
{
gint i, p;
@@ -253,25 +253,15 @@
p = 0;
for (i = 0; i < MAX_CHANNEL_POSITIONS; ++i) {
if ((layout & layout_mapping[i].ms_mask) != 0) {
- if (p >= num_channels) {
- GST_WARNING ("More bits set in the channel layout map than there "
- "are channels! Broken file");
- return FALSE;
- }
- if (layout_mapping[i].gst_pos == GST_AUDIO_CHANNEL_POSITION_INVALID) {
- GST_WARNING ("Unsupported channel position (mask 0x%08x) in channel "
- "layout map - ignoring those channels", layout_mapping[i].ms_mask);
- /* what to do? just ignore it and let downstream deal with a channel
- * layout that has INVALID positions in it for now ... */
- }
pos[p] = layout_mapping[i].gst_pos;
++p;
}
}
+ // Not all channels found, consider it unpositioned
if (p != num_channels) {
- GST_WARNING ("Only %d bits set in the channel layout map, but there are "
- "supposed to be %d channels! Broken file", p, num_channels);
+ for (i = 0; i < MIN (64, num_channels); i++)
+ pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
return FALSE;
}
@@ -312,10 +302,10 @@
if (!wpi->rate)
wpi->rate = (i < G_N_ELEMENTS (sample_rates)) ? sample_rates[i] : 44100;
wpi->width = ((wph->flags & FLAG_BYTES_STORED) + 1) * 8;
- if (!wpi->channels)
+ if (!wpi->channels) {
wpi->channels = (wph->flags & FLAG_MONO_FLAG) ? 1 : 2;
- if (!wpi->channel_mask)
wpi->channel_mask = 5 - wpi->channels;
+ }
if ((wph->flags & FLAG_FLOAT_DATA) != 0)
wpi->sample_type = SAMPLE_TYPE_FLOAT;
else if ((wph->flags & FLAG_DSD_FLAG) != 0)
@@ -383,8 +373,15 @@
guint32 mask = 0;
if (size == 6 || size == 7) {
- CHECK (gst_byte_reader_get_uint16_le (&mbr, &channels));
- channels = (channels & 0xFFF) + 1;
+ guint8 c0, c1, c2;
+
+ CHECK (gst_byte_reader_get_uint8 (&mbr, &c0));
+ CHECK (gst_byte_reader_get_uint8 (&mbr, &c1));
+ CHECK (gst_byte_reader_get_uint8 (&mbr, &c2));
+
+ channels = (((guint16) c0) | (((guint16) c2 & 0xf) << 8)) + 1;
+ // max_streams = (((guint16) c1) | (((guint16) c2 & 0xf0) << 4)) + 1;
+
if (size == 6) {
CHECK (gst_byte_reader_get_uint24_le (&mbr, &mask));
} else if (size == 7) {
@@ -636,7 +633,8 @@
guint64 gmask;
if (!gst_wavpack_get_channel_positions (chans, mask, pos)) {
- GST_WARNING_OBJECT (wvparse, "Failed to determine channel layout");
+ GST_WARNING_OBJECT (wvparse,
+ "Unsupported channel layout -- mapping to unpositioned
channels");
} else {
gst_audio_channel_positions_to_mask (pos, chans, FALSE, &gmask);
if (gmask)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/gst/isomp4/qtdemux.c
new/gst-plugins-good-1.28.4/gst/isomp4/qtdemux.c
--- old/gst-plugins-good-1.28.3/gst/isomp4/qtdemux.c 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/gst/isomp4/qtdemux.c 2026-06-12
14:19:43.000000000 +0200
@@ -15438,10 +15438,10 @@
QT_UINT16 (mdcv_data + 8 + 3 * 2 * 2 + 2);
CUR_STREAM (stream)->
mastering_display_info.max_display_mastering_luminance =
- QT_UINT16 (mdcv_data + 8 + 3 * 2 * 2 + 2 * 2);
+ QT_UINT32 (mdcv_data + 8 + 3 * 2 * 2 + 2 * 2);
CUR_STREAM (stream)->
mastering_display_info.min_display_mastering_luminance =
- QT_UINT16 (mdcv_data + 8 + 3 * 2 * 2 + 2 * 2 + 4);
+ QT_UINT32 (mdcv_data + 8 + 3 * 2 * 2 + 2 * 2 + 4);
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/gst/matroska/matroska-mux.c
new/gst-plugins-good-1.28.4/gst/matroska/matroska-mux.c
--- old/gst-plugins-good-1.28.3/gst/matroska/matroska-mux.c 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/gst/matroska/matroska-mux.c 2026-06-12
14:19:43.000000000 +0200
@@ -510,6 +510,7 @@
pad->frame_duration_user = FALSE;
pad->start_ts = GST_CLOCK_TIME_NONE;
pad->end_ts = GST_CLOCK_TIME_NONE;
+ pad->last_keyframe_ts = GST_CLOCK_TIME_NONE;
pad->tags = gst_tag_list_new_empty ();
gst_tag_list_set_scope (pad->tags, GST_TAG_SCOPE_STREAM);
}
@@ -645,6 +646,7 @@
pad->start_ts = GST_CLOCK_TIME_NONE;
pad->end_ts = GST_CLOCK_TIME_NONE;
+ pad->last_keyframe_ts = GST_CLOCK_TIME_NONE;
gst_clear_tag_list (&pad->tags);
if (full) {
@@ -4068,6 +4070,7 @@
GST_LOG_OBJECT (mux, "have video keyframe, ts=%" GST_TIME_FORMAT,
GST_TIME_ARGS (buffer_timestamp));
is_video_keyframe = TRUE;
+ mux_pad->last_keyframe_ts = buffer_timestamp;
} else if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DECODE_ONLY) &&
(!strcmp (mux_pad->track->codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)
|| !strcmp (mux_pad->track->codec_id,
@@ -4276,6 +4279,24 @@
if (write_duration)
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_BLOCKDURATION,
block_duration);
+ /* Mark non-keyframe video blocks with a ReferenceBlock element so that
+ * demuxers can correctly identify them as delta units. The Matroska spec
+ * requires a ReferenceBlock in BlockGroups that are not keyframes.
+ * Note: this always references the previous keyframe, which is an
+ * approximation. For B-frames the actual reference may be a future frame,
+ * and a frame may have multiple reference frames. However, referencing the
+ * previous keyframe is sufficient to signal that decoding can start from
+ * there. */
+ if (mux_pad->track->type == GST_MATROSKA_TRACK_TYPE_VIDEO
+ && !is_video_keyframe) {
+ gint64 reference_offset =
+ gst_util_uint64_scale (mux_pad->last_keyframe_ts, 1,
+ mux->time_scale) - gst_util_uint64_scale (buffer_timestamp, 1,
+ mux->time_scale);
+ gst_ebml_write_sint (ebml, GST_MATROSKA_ID_REFERENCEBLOCK,
+ reference_offset);
+ }
+
if (!strcmp (mux_pad->track->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)
&& cmeta) {
/* Start clipping is done via header and CodecDelay */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/gst/matroska/matroska-mux.h
new/gst-plugins-good-1.28.4/gst/matroska/matroska-mux.h
--- old/gst-plugins-good-1.28.3/gst/matroska/matroska-mux.h 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/gst/matroska/matroska-mux.h 2026-06-12
14:19:43.000000000 +0200
@@ -78,6 +78,9 @@
GstClockTime start_ts;
GstClockTime end_ts; /* last timestamp + (if available) duration */
guint64 default_duration_scaled;
+
+ /* last keyframe timestamp for ReferenceBlock calculation (video only) */
+ GstClockTime last_keyframe_ts;
};
typedef struct _GstMatroskaMuxPadClass {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/gst/rtp/gstrtph265depay.c
new/gst-plugins-good-1.28.4/gst/rtp/gstrtph265depay.c
--- old/gst-plugins-good-1.28.3/gst/rtp/gstrtph265depay.c 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/gst/rtp/gstrtph265depay.c 2026-06-12
14:19:43.000000000 +0200
@@ -727,6 +727,7 @@
}
gst_caps_unref (srccaps);
+ gst_clear_caps (&old_caps);
/* Insert SPS and PPS into the stream on next opportunity */
if (rtph265depay->output_format != GST_H265_STREAM_FORMAT_HVC1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/gst-plugins-good.doap
new/gst-plugins-good-1.28.4/gst-plugins-good.doap
--- old/gst-plugins-good-1.28.3/gst-plugins-good.doap 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/gst-plugins-good.doap 2026-06-12
14:19:43.000000000 +0200
@@ -34,6 +34,16 @@
<release>
<Version>
+ <revision>1.28.4</revision>
+ <branch>1.28</branch>
+ <name></name>
+ <created>2026-06-12</created>
+ <file-release
rdf:resource="https://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-1.28.4.tar.xz"
/>
+ </Version>
+ </release>
+
+ <release>
+ <Version>
<revision>1.28.3</revision>
<branch>1.28</branch>
<name></name>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/meson.build
new/gst-plugins-good-1.28.4/meson.build
--- old/gst-plugins-good-1.28.3/meson.build 2026-05-11 19:28:12.000000000
+0200
+++ new/gst-plugins-good-1.28.4/meson.build 2026-06-12 14:19:43.000000000
+0200
@@ -1,5 +1,5 @@
project('gst-plugins-good', 'c',
- version : '1.28.3',
+ version : '1.28.4',
meson_version : '>= 1.4',
default_options : [ 'warning_level=1',
'buildtype=debugoptimized',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-good-1.28.3/sys/osxaudio/gstosxcoreaudio.c
new/gst-plugins-good-1.28.4/sys/osxaudio/gstosxcoreaudio.c
--- old/gst-plugins-good-1.28.3/sys/osxaudio/gstosxcoreaudio.c 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/sys/osxaudio/gstosxcoreaudio.c 2026-06-12
14:19:43.000000000 +0200
@@ -548,12 +548,13 @@
if (_core_audio_has_invalid_channel_labels (layout)) {
GST_DEBUG
("Invalid channel positions given by CoreAudio, setting all to
unpositioned");
+ *channels =
+ MIN (layout->mNumberChannelDescriptions, GST_OSX_AUDIO_MAX_CHANNEL);
+ *channel_mask = 0;
if (pos) {
- for (i = 0; i < layout->mNumberChannelDescriptions; ++i)
+ for (i = 0; i < *channels; ++i)
pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
}
- *channels = layout->mNumberChannelDescriptions;
- *channel_mask = 0;
return;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gst-plugins-good-1.28.3/sys/v4l2/gstv4l2bufferpool.c
new/gst-plugins-good-1.28.4/sys/v4l2/gstv4l2bufferpool.c
--- old/gst-plugins-good-1.28.3/sys/v4l2/gstv4l2bufferpool.c 2026-05-11
19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/sys/v4l2/gstv4l2bufferpool.c 2026-06-12
14:19:43.000000000 +0200
@@ -2188,8 +2188,10 @@
if ((ret =
gst_v4l2_buffer_pool_qbuf (pool, to_queue, group,
frame_number))
- != GST_FLOW_OK)
+ != GST_FLOW_OK) {
+ gst_buffer_unref (to_queue);
goto queue_failed;
+ }
/* if we are not streaming yet (this is the first buffer, start
* streaming now */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gst-plugins-good-1.28.3/tests/check/elements/mpegaudioparse.c
new/gst-plugins-good-1.28.4/tests/check/elements/mpegaudioparse.c
--- old/gst-plugins-good-1.28.3/tests/check/elements/mpegaudioparse.c
2026-05-11 19:28:12.000000000 +0200
+++ new/gst-plugins-good-1.28.4/tests/check/elements/mpegaudioparse.c
2026-06-12 14:19:43.000000000 +0200
@@ -300,10 +300,24 @@
gst_sample_unref (sample);
}
+static void
+set_to_state_and_wait (GstElement * pipeline, GstState target_state)
+{
+ GstStateChangeReturn state_ret =
+ gst_element_set_state (pipeline, target_state);
+
+ fail_unless (state_ret != GST_STATE_CHANGE_FAILURE);
+
+ 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);
+ }
+}
+
GST_START_TEST (test_parse_gapless_and_skip_padding_samples)
{
GstElement *source, *parser, *appsink, *pipeline;
- GstStateChangeReturn state_ret;
guint frame_num;
GaplessTestInfo info;
@@ -327,19 +341,11 @@
g_free (full_filename);
}
- g_object_set (G_OBJECT (appsink), "async", FALSE, "sync", FALSE,
+ g_object_set (G_OBJECT (appsink), "sync", FALSE,
"max-buffers", 1, "enable-last-sample", FALSE, "processing-deadline",
G_MAXUINT64, NULL);
- state_ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
-
- fail_unless (state_ret != GST_STATE_CHANGE_FAILURE);
-
- 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);
- }
+ set_to_state_and_wait (pipeline, GST_STATE_PLAYING);
/* Verify all frames from the test signal. */
for (frame_num = 0; frame_num < info.num_mpeg_frames; ++frame_num)
@@ -368,24 +374,18 @@
/* Seek back to the first frame. */
{
- fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
- GST_STATE_CHANGE_SUCCESS);
gst_element_seek_simple (pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH |
GST_SEEK_FLAG_KEY_UNIT, 0);
- fail_unless_equals_int (gst_element_set_state (pipeline,
GST_STATE_PLAYING),
- GST_STATE_CHANGE_SUCCESS);
+ set_to_state_and_wait (pipeline, GST_STATE_PLAYING);
check_parsed_mpeg_frame (&info, 1);
}
/* Seek to the second frame. */
{
- fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
- GST_STATE_CHANGE_SUCCESS);
gst_element_seek_simple (pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH |
GST_SEEK_FLAG_KEY_UNIT, info.first_frame_duration);
- fail_unless_equals_int (gst_element_set_state (pipeline,
GST_STATE_PLAYING),
- GST_STATE_CHANGE_SUCCESS);
+ set_to_state_and_wait (pipeline, GST_STATE_PLAYING);
check_parsed_mpeg_frame (&info, 2);
}
@@ -396,12 +396,9 @@
GstClockTime pts = info.first_frame_duration +
(info.first_padded_end_frame - 2) * info.regular_frame_duration;
- fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
- GST_STATE_CHANGE_SUCCESS);
gst_element_seek_simple (pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH |
GST_SEEK_FLAG_KEY_UNIT, pts);
- fail_unless_equals_int (gst_element_set_state (pipeline,
GST_STATE_PLAYING),
- GST_STATE_CHANGE_SUCCESS);
+ set_to_state_and_wait (pipeline, GST_STATE_PLAYING);
check_parsed_mpeg_frame (&info, info.first_padded_end_frame);
}
++++++ gst-plugins-good.obsinfo ++++++
--- /var/tmp/diff_new_pack.3NnkKi/_old 2026-06-13 18:47:28.897788760 +0200
+++ /var/tmp/diff_new_pack.3NnkKi/_new 2026-06-13 18:47:28.905789092 +0200
@@ -1,5 +1,5 @@
name: gst-plugins-good
-version: 1.28.3
-mtime: 1778520492
-commit: 62d8936e70b11a2e21ea3c68b7672b675e142945
+version: 1.28.4
+mtime: 1781266783
+commit: b46f881eaa8126eddfd21b5ae5512f8d4ff36255