Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package gstreamer for openSUSE:Factory checked in at 2026-09-11 19:00:31 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/gstreamer (Old) and /work/SRC/openSUSE:Factory/.gstreamer.new.1265 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gstreamer" Fri Sep 11 19:00:31 2026 rev:126 rq:1376925 version:1.28.7 Changes: -------- --- /work/SRC/openSUSE:Factory/gstreamer/gstreamer.changes 2026-08-06 16:19:27.390698353 +0200 +++ /work/SRC/openSUSE:Factory/.gstreamer.new.1265/gstreamer.changes 2026-09-11 19:01:04.954996372 +0200 @@ -1,0 +2,37 @@ +Tue Sep 8 06:46:28 UTC 2026 - Bjørn Lie <[email protected]> + +- Update to version 1.28.7: + + Highlighted bugfixes: + - Various security fixes and playback fixes + - appsrc EOS handling regression fix for applications pushing + EOS into a blocked appsrc + - glcolorconvert fixes for older OpenGL/GLSL versions + - mxfdemux: Fix keyframe detection regression and possible + artefacts after seeking + - QML6 GL Overlay output texture lifetime handling fixes + - opencv: Add support for building against OpenCV 5 + - hip: Add missing API version suffix in HIP support library + filename and fix hipcc detection on Windows with HIP SDK 7.x + - analytics: fix classes off-by-one in ssdtensordec leading to + mislabelling of objects in the examples + - isobmff: Fix min_display_mastering_luminance in mdcv box + - rtpbin2: rtprecv: limit the number of remote sources being + tracked + - st2038anc: parity bit handling fixes for ST 291 ADF words + - video converter and videoconvertscale fixes + - mpegdemux: restore gap event sending in MPEG-PS demuxer + - typefinding: fix typefinding regressions for ogg and text + files + - Fix x264enc high bit depth support in binary packages + - Various bug fixes, build fixes, memory leak fixes, and other + stability and reliability improvements + + gstreamer: + - cpuid: Clean up NEON and ASIMD getauxval detection + port + Orc's elf_aux_info support + - dataurisrc: Fix empty payloads and unsupported charset + conversion + - pipeline: Avoid lock inversion when handling + GST_MESSAGE_RESET_TIME + - validate: Use a single value type in configs lists + +------------------------------------------------------------------- Old: ---- gstreamer-1.28.6.obscpio New: ---- gstreamer-1.28.7.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ gstreamer.spec ++++++ --- /var/tmp/diff_new_pack.Y57pUO/_old 2026-09-11 19:01:06.390056178 +0200 +++ /var/tmp/diff_new_pack.Y57pUO/_new 2026-09-11 19:01:06.392056261 +0200 @@ -19,7 +19,7 @@ %define gst_branch 1.0 Name: gstreamer -Version: 1.28.6 +Version: 1.28.7 Release: 0 Summary: Streaming-Media Framework Runtime License: LGPL-2.1-or-later ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Y57pUO/_old 2026-09-11 19:01:06.434058012 +0200 +++ /var/tmp/diff_new_pack.Y57pUO/_new 2026-09-11 19:01:06.439058220 +0200 @@ -5,7 +5,7 @@ <param name="url">https://gitlab.freedesktop.org/gstreamer/gstreamer.git</param> <param name="subdir">subprojects/gstreamer</param> <param name="filename">gstreamer</param> - <param name="revision">1.28.6</param> + <param name="revision">1.28.7</param> <param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param> <param name="versionrewrite-pattern">v?(.*)\+0</param> <param name="versionrewrite-replacement">\1</param> ++++++ gstreamer-1.28.6.obscpio -> gstreamer-1.28.7.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.6/gst/gstcpuid.c new/gstreamer-1.28.7/gst/gstcpuid.c --- old/gstreamer-1.28.6/gst/gstcpuid.c 2026-08-05 13:59:39.000000000 +0200 +++ new/gstreamer-1.28.7/gst/gstcpuid.c 2026-09-07 21:11:13.000000000 +0200 @@ -15,6 +15,10 @@ * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "gstcpuid.h" // define G_ALWAYS_INLINE to force MSVC to get rid of the interstitial @@ -39,7 +43,12 @@ #if defined(__linux__) && defined(__ARM_ARCH) #include <asm/hwcap.h> +#endif +#if defined(__linux__) || defined(HAVE_ELF_AUX_INFO) #include <sys/auxv.h> +#endif + +#if defined(GST_CPUID_CHECK_ARM) #if defined(__aarch64__) #ifndef HWCAP_ASIMD #define HWCAP_ASIMD (1 << 1) @@ -157,16 +166,26 @@ // See https://gitlab.freedesktop.org/gstreamer/orc/-/commit/7a60e2074d425b7ad1192ff48ac87af4246a04c4 cpuid.neon = TRUE; cpuid.neon64 = TRUE; -#elif defined(__ARM_ARCH) - // If Linux, rely on getauxval; otherwise search Arm macros - // https://developer.arm.com/documentation/dui0774/b/other-compiler-specific-features/predefined-macros +#elif defined(GST_CPUID_CHECK_ARM) + // If Linux, rely on getauxval; otherwise try elf_aux_info #if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 18) #if defined(__aarch64__) cpuid.neon = (getauxval (AT_HWCAP) & HWCAP_ASIMD) != 0 ? TRUE : FALSE; #else cpuid.neon = (getauxval (AT_HWCAP) & HWCAP_NEON) != 0 ? TRUE : FALSE; #endif -#elif defined(__ARM_NEON) || defined(__aarch64__) +#elif defined(HAVE_ELF_AUX_INFO) + unsigned long auxv = 0; + elf_aux_info (AT_HWCAP, &auxv, sizeof (auxv)); +#if defined(__aarch64__) + cpuid.neon = (auxv & HWCAP_ASIMD) != 0 ? TRUE : FALSE; +#else + cpuid.neon = (auxv & HWCAP_NEON) != 0 ? TRUE : FALSE; +#endif +#elif defined(__ARM_NEON) || defined (__aarch64__) + // If enabled unconditionally by compiler, use it + // https://support.arm.com/documentation/102474/0100/Fundamentals-of-Armv8-Neon-technology + // https://developer.arm.com/documentation/dui0774/b/other-compiler-specific-features/predefined-macros cpuid.neon = TRUE; #endif #if defined(__aarch64__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.6/gst/gstpipeline.c new/gstreamer-1.28.7/gst/gstpipeline.c --- old/gstreamer-1.28.6/gst/gstpipeline.c 2026-08-05 13:59:39.000000000 +0200 +++ new/gstreamer-1.28.7/gst/gstpipeline.c 2026-09-07 21:11:13.000000000 +0200 @@ -394,6 +394,105 @@ GST_OBJECT_UNLOCK (element); } +static gboolean +pipeline_update_clock_and_base_time (GstPipeline * pipeline) +{ + GstElement *element = GST_ELEMENT_CAST (pipeline); + GstClockTime now, start_time, last_start_time, delay; + gboolean update_clock; + GstClock *cur_clock; + + GST_DEBUG_OBJECT (element, "selecting clock and base_time"); + + GST_OBJECT_LOCK (element); + cur_clock = element->clock; + if (cur_clock) + gst_object_ref (cur_clock); + /* get the desired running_time of the first buffer aka the start_time */ + start_time = GST_ELEMENT_START_TIME (pipeline); + last_start_time = pipeline->priv->last_start_time; + pipeline->priv->last_start_time = start_time; + /* see if we need to update the clock */ + update_clock = pipeline->priv->update_clock; + pipeline->priv->update_clock = FALSE; + delay = pipeline->delay; + GST_OBJECT_UNLOCK (element); + + /* running time changed, either with a PAUSED or a flush, we need to check + * if there is a new clock & update the base time */ + /* only do this for top-level, however */ + if (GST_OBJECT_PARENT (element) == NULL && + (update_clock || last_start_time != start_time)) { + GstClock *clock = NULL; + GST_DEBUG_OBJECT (pipeline, "Need to update start_time"); + + /* when going to PLAYING, select a clock when needed. If we just got + * flushed, we don't reselect the clock. */ + if (update_clock) { + GST_DEBUG_OBJECT (pipeline, "Need to update clock."); + clock = gst_element_provide_clock (element); + } else { + GST_DEBUG_OBJECT (pipeline, + "Don't need to update clock, using old clock."); + /* only try to ref if cur_clock is not NULL */ + if (cur_clock) + clock = gst_object_ref (cur_clock); + } + + if (clock) { + now = gst_clock_get_time (clock); + } else { + GST_DEBUG_OBJECT (pipeline, "no clock, using base time of NONE"); + now = GST_CLOCK_TIME_NONE; + } + + if (clock != cur_clock) { + /* now distribute the clock (which could be NULL). If some + * element refuses the clock, this will return FALSE and + * we effectively fail the state change. */ + if (!gst_element_set_clock (element, clock)) { + /* selected clock was not accepted by some element */ + GST_ELEMENT_ERROR (pipeline, CORE, CLOCK, + (_("Selected clock cannot be used in pipeline.")), + ("Pipeline cannot operate with selected clock")); + GST_DEBUG_OBJECT (pipeline, + "Pipeline cannot operate with selected clock %p", clock); + gst_clear_object (&clock); + gst_clear_object (&cur_clock); + return FALSE; + } + + /* if we selected and distributed a new clock, let the app + * know about it */ + gst_element_post_message (element, + gst_message_new_new_clock (GST_OBJECT_CAST (element), clock)); + } + + gst_clear_object (&clock); + + if (start_time != GST_CLOCK_TIME_NONE && now != GST_CLOCK_TIME_NONE) { + GstClockTime new_base_time = now - start_time + delay; + GST_DEBUG_OBJECT (element, + "start_time=%" GST_TIME_FORMAT ", now=%" GST_TIME_FORMAT + ", base_time %" GST_TIME_FORMAT, + GST_TIME_ARGS (start_time), GST_TIME_ARGS (now), + GST_TIME_ARGS (new_base_time)); + + gst_element_set_base_time (element, new_base_time); + } else { + GST_DEBUG_OBJECT (pipeline, + "NOT adjusting base_time because start_time is NONE"); + } + } else { + GST_DEBUG_OBJECT (pipeline, + "NOT adjusting base_time because we selected one before"); + } + + gst_clear_object (&cur_clock); + + return TRUE; +} + /* MT safe */ static GstStateChangeReturn gst_pipeline_change_state (GstElement * element, GstStateChange transition) @@ -425,100 +524,9 @@ reset_start_time (pipeline, 0); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - { - GstClockTime now, start_time, last_start_time, delay; - gboolean update_clock; - GstClock *cur_clock; - - GST_DEBUG_OBJECT (element, "selecting clock and base_time"); - - GST_OBJECT_LOCK (element); - cur_clock = element->clock; - if (cur_clock) - gst_object_ref (cur_clock); - /* get the desired running_time of the first buffer aka the start_time */ - start_time = GST_ELEMENT_START_TIME (pipeline); - last_start_time = pipeline->priv->last_start_time; - pipeline->priv->last_start_time = start_time; - /* see if we need to update the clock */ - update_clock = pipeline->priv->update_clock; - pipeline->priv->update_clock = FALSE; - delay = pipeline->delay; - GST_OBJECT_UNLOCK (element); - - /* running time changed, either with a PAUSED or a flush, we need to check - * if there is a new clock & update the base time */ - /* only do this for top-level, however */ - if (GST_OBJECT_PARENT (element) == NULL && - (update_clock || last_start_time != start_time)) { - GstClock *clock = NULL; - GST_DEBUG_OBJECT (pipeline, "Need to update start_time"); - - /* when going to PLAYING, select a clock when needed. If we just got - * flushed, we don't reselect the clock. */ - if (update_clock) { - GST_DEBUG_OBJECT (pipeline, "Need to update clock."); - clock = gst_element_provide_clock (element); - } else { - GST_DEBUG_OBJECT (pipeline, - "Don't need to update clock, using old clock."); - /* only try to ref if cur_clock is not NULL */ - if (cur_clock) - clock = gst_object_ref (cur_clock); - } - - if (clock) { - now = gst_clock_get_time (clock); - } else { - GST_DEBUG_OBJECT (pipeline, "no clock, using base time of NONE"); - now = GST_CLOCK_TIME_NONE; - } - - if (clock != cur_clock) { - /* now distribute the clock (which could be NULL). If some - * element refuses the clock, this will return FALSE and - * we effectively fail the state change. */ - if (!gst_element_set_clock (element, clock)) { - /* selected clock was not accepted by some element */ - GST_ELEMENT_ERROR (pipeline, CORE, CLOCK, - (_("Selected clock cannot be used in pipeline.")), - ("Pipeline cannot operate with selected clock")); - GST_DEBUG_OBJECT (pipeline, - "Pipeline cannot operate with selected clock %p", clock); - gst_clear_object (&clock); - gst_clear_object (&cur_clock); - return GST_STATE_CHANGE_FAILURE; - } - - /* if we selected and distributed a new clock, let the app - * know about it */ - gst_element_post_message (element, - gst_message_new_new_clock (GST_OBJECT_CAST (element), clock)); - } - - gst_clear_object (&clock); - - if (start_time != GST_CLOCK_TIME_NONE && now != GST_CLOCK_TIME_NONE) { - GstClockTime new_base_time = now - start_time + delay; - GST_DEBUG_OBJECT (element, - "start_time=%" GST_TIME_FORMAT ", now=%" GST_TIME_FORMAT - ", base_time %" GST_TIME_FORMAT, - GST_TIME_ARGS (start_time), GST_TIME_ARGS (now), - GST_TIME_ARGS (new_base_time)); - - gst_element_set_base_time (element, new_base_time); - } else { - GST_DEBUG_OBJECT (pipeline, - "NOT adjusting base_time because start_time is NONE"); - } - } else { - GST_DEBUG_OBJECT (pipeline, - "NOT adjusting base_time because we selected one before"); - } - - gst_clear_object (&cur_clock); + if (!pipeline_update_clock_and_base_time (pipeline)) + return GST_STATE_CHANGE_FAILURE; break; - } case GST_STATE_CHANGE_PLAYING_TO_PAUSED: { /* we take a start_time snapshot before calling the children state changes @@ -633,8 +641,7 @@ /* If we are live, sample a new base_time immediately */ if (is_live && GST_STATE_TARGET (pipeline) == GST_STATE_PLAYING) { - gst_pipeline_change_state (GST_ELEMENT (pipeline), - GST_STATE_CHANGE_PAUSED_TO_PLAYING); + pipeline_update_clock_and_base_time (pipeline); } break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.6/gstreamer.doap new/gstreamer-1.28.7/gstreamer.doap --- old/gstreamer-1.28.6/gstreamer.doap 2026-08-05 13:59:39.000000000 +0200 +++ new/gstreamer-1.28.7/gstreamer.doap 2026-09-07 21:11:13.000000000 +0200 @@ -40,6 +40,16 @@ <release> <Version> + <revision>1.28.7</revision> + <branch>1.28</branch> + <name></name> + <created>2026-09-07</created> + <file-release rdf:resource="https://gstreamer.freedesktop.org/src/gstreamer/gstreamer-1.28.7.tar.xz" /> + </Version> + </release> + + <release> + <Version> <revision>1.28.6</revision> <branch>1.28</branch> <name></name> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.6/libs/gst/base/gsttypefindhelper.c new/gstreamer-1.28.7/libs/gst/base/gsttypefindhelper.c --- old/gstreamer-1.28.6/libs/gst/base/gsttypefindhelper.c 2026-08-05 13:59:39.000000000 +0200 +++ new/gstreamer-1.28.7/libs/gst/base/gsttypefindhelper.c 2026-09-07 21:11:13.000000000 +0200 @@ -964,6 +964,10 @@ factory = GST_TYPE_FIND_FACTORY (l->data); + /* we only want to check those factories without a function */ + if (gst_type_find_factory_has_function (factory)) + continue; + /* get the extension that this typefind factory can handle */ ext = gst_type_find_factory_get_extensions (factory); if (ext == NULL) @@ -1026,6 +1030,10 @@ factory = GST_TYPE_FIND_FACTORY (l->data); + /* We only want to check those factories without a function */ + if (gst_type_find_factory_has_function (factory)) + continue; + /* Get the caps that this typefind factory can handle */ factory_caps = gst_type_find_factory_get_caps (factory); if (!factory_caps) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.6/meson.build new/gstreamer-1.28.7/meson.build --- old/gstreamer-1.28.6/meson.build 2026-08-05 13:59:39.000000000 +0200 +++ new/gstreamer-1.28.7/meson.build 2026-09-07 21:11:13.000000000 +0200 @@ -1,5 +1,5 @@ project('gstreamer', 'c', - version : '1.28.6', + version : '1.28.7', meson_version : '>= 1.4', default_options : [ 'warning_level=1', 'buildtype=debugoptimized', @@ -402,6 +402,9 @@ elif cc.has_function('_pipe', prefix : '#include <io.h>') cdata.set('HAVE_PIPE', 1) endif +if cc.has_function('elf_aux_info', prefix : '#include <sys/auxv.h>') + cdata.set('HAVE_ELF_AUX_INFO', 1) +endif # Platform deps; only ws2_32 and execinfo for now platform_deps = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.6/plugins/elements/gstdataurisrc.c new/gstreamer-1.28.7/plugins/elements/gstdataurisrc.c --- old/gstreamer-1.28.6/plugins/elements/gstdataurisrc.c 2026-08-05 13:59:39.000000000 +0200 +++ new/gstreamer-1.28.7/plugins/elements/gstdataurisrc.c 2026-09-07 21:11:13.000000000 +0200 @@ -405,13 +405,23 @@ g_convert_with_fallback (bdata, bsize, "UTF-8", charset, (char *) "*", &read, &written, NULL); g_free (bdata); + if (data == NULL) + goto invalid_uri_encoded_data; bdata = data; bsize = written; } - buffer = gst_buffer_new_wrapped (bdata, bsize); + if (bsize == 0) { + g_free (bdata); + buffer = gst_buffer_new (); + } else { + buffer = gst_buffer_new_wrapped (bdata, bsize); + } - caps = gst_type_find_helper_for_buffer (GST_OBJECT (src), buffer, NULL); + if (bsize > 0) + caps = gst_type_find_helper_for_buffer (GST_OBJECT (src), buffer, NULL); + else + caps = NULL; if (!caps) caps = gst_caps_new_empty_simple (mimetype); gst_base_src_set_caps (GST_BASE_SRC_CAST (src), caps); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.6/tests/check/elements/dataurisrc.c new/gstreamer-1.28.7/tests/check/elements/dataurisrc.c --- old/gstreamer-1.28.6/tests/check/elements/dataurisrc.c 2026-08-05 13:59:39.000000000 +0200 +++ new/gstreamer-1.28.7/tests/check/elements/dataurisrc.c 2026-09-07 21:11:13.000000000 +0200 @@ -517,6 +517,25 @@ GST_END_TEST; +static gboolean +can_convert_iso_8859_5_to_utf8 (void) +{ + const gchar iso_8859_5_sample[] = { (gchar) 0xc0, 0 }; + GError *error = NULL; + gchar *converted; + + converted = + g_convert_with_fallback (iso_8859_5_sample, 1, "UTF-8", "ISO-8859-5", + (gchar *) "*", NULL, NULL, &error); + if (converted == NULL) { + g_clear_error (&error); + return FALSE; + } + + g_free (converted); + return TRUE; +} + GST_START_TEST (test_dataurisrc_uris) { #define STRING_CONTENT(s) s, sizeof(s) - 1 @@ -548,6 +567,10 @@ GstElement *src; GstBuffer *buf; + if (g_str_equal (tests[i].name, "charset_base64") && + !can_convert_iso_8859_5_to_utf8 ()) + continue; + src = gst_element_factory_make ("dataurisrc", NULL); g_object_set (src, "uri", tests[i].uri, NULL); h = gst_harness_new_with_element (src, NULL, "src"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.6/tests/check/gst/gstpipeline.c new/gstreamer-1.28.7/tests/check/gst/gstpipeline.c --- old/gstreamer-1.28.6/tests/check/gst/gstpipeline.c 2026-08-05 13:59:39.000000000 +0200 +++ new/gstreamer-1.28.7/tests/check/gst/gstpipeline.c 2026-09-07 21:11:13.000000000 +0200 @@ -43,6 +43,157 @@ GST_END_TEST; +typedef struct +{ + GstElement *pipeline; + GstElement *sink; + GstPad *sinkpad; + GMutex lock; + GCond cond; + gboolean stream_locked; + gboolean post_reset_time; + gboolean message_posted; + gboolean do_latency_called; + gboolean state_lock_contended; + GstClockTime reset_running_time; +} ResetTimeLockData; + +static gboolean +reset_time_do_latency (G_GNUC_UNUSED GstBin * bin, gpointer user_data) +{ + ResetTimeLockData *data = user_data; + gboolean state_lock_acquired = GST_STATE_TRYLOCK (data->pipeline); + + if (state_lock_acquired) + GST_STATE_UNLOCK (data->pipeline); + + data->do_latency_called = TRUE; + data->state_lock_contended = !state_lock_acquired; + + /* Do not run the default handler, whose latency event would eventually + * wait for the state lock. */ + return TRUE; +} + +static gpointer +post_reset_time_with_stream_lock (gpointer user_data) +{ + ResetTimeLockData *data = user_data; + + GST_PAD_STREAM_LOCK (data->sinkpad); + + g_mutex_lock (&data->lock); + data->stream_locked = TRUE; + g_cond_broadcast (&data->cond); + while (!data->post_reset_time) + g_cond_wait (&data->cond, &data->lock); + g_mutex_unlock (&data->lock); + + gst_element_post_message (data->sink, + gst_message_new_reset_time (GST_OBJECT (data->sink), + data->reset_running_time)); + + g_mutex_lock (&data->lock); + data->message_posted = TRUE; + g_cond_broadcast (&data->cond); + g_mutex_unlock (&data->lock); + + GST_PAD_STREAM_UNLOCK (data->sinkpad); + + return NULL; +} + +/* Check that RESET_TIME updates the base time without running the parent bin's + * state transition. Model the lock inversion seen when a streaming thread + * posts RESET_TIME while holding a sink-pad stream lock and a state-change + * thread holds the pipeline state lock while waiting for that stream lock. The + * custom do-latency handler uses trylock to detect the inverse state-lock + * contention and suppresses the default handler so the test reports the + * condition rather than deadlocking. */ +GST_START_TEST (test_reset_time_during_state_change) +{ + ResetTimeLockData data = { 0, }; + GstElement *pipeline = gst_pipeline_new (NULL); + GstElement *src = gst_element_factory_make ("fakesrc", NULL); + GstElement *sink = gst_element_factory_make ("fakesink", NULL); + GstClock *clock = gst_test_clock_new (); + gboolean stream_lock_contended; + GstClockTime base_time; + gulong signal_id; + GThread *thread; + + fail_unless (pipeline && src && sink); + + gst_test_clock_set_time (GST_TEST_CLOCK (clock), 100 * GST_SECOND); + gst_pipeline_use_clock (GST_PIPELINE (pipeline), clock); + g_object_set (src, "is-live", TRUE, NULL); + g_object_set (sink, "async", FALSE, "sync", FALSE, NULL); + gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL); + fail_unless (gst_element_link (src, sink)); + fail_unless (gst_element_set_state (pipeline, GST_STATE_PLAYING) != + GST_STATE_CHANGE_FAILURE); + fail_unless (gst_element_get_state (pipeline, NULL, NULL, + GST_CLOCK_TIME_NONE) != GST_STATE_CHANGE_FAILURE); + fail_unless_equals_uint64 (gst_element_get_base_time (pipeline), + 100 * GST_SECOND); + + data.pipeline = pipeline; + data.sink = sink; + data.sinkpad = gst_element_get_static_pad (sink, "sink"); + data.reset_running_time = 10 * GST_SECOND; + g_mutex_init (&data.lock); + g_cond_init (&data.cond); + + signal_id = g_signal_connect (pipeline, "do-latency", + G_CALLBACK (reset_time_do_latency), &data); + thread = g_thread_new ("reset-time", post_reset_time_with_stream_lock, &data); + + g_mutex_lock (&data.lock); + while (!data.stream_locked) { + g_printerr ("Waiting for worker to acquire stream lock\n"); + mark_point (); + g_cond_wait (&data.cond, &data.lock); + } + g_mutex_unlock (&data.lock); + + GST_STATE_LOCK (pipeline); + stream_lock_contended = !GST_PAD_STREAM_TRYLOCK (data.sinkpad); + if (!stream_lock_contended) + GST_PAD_STREAM_UNLOCK (data.sinkpad); + + g_mutex_lock (&data.lock); + data.post_reset_time = TRUE; + g_cond_broadcast (&data.cond); + while (!data.message_posted) { + g_printerr ("Waiting for worker to post RESET_TIME\n"); + mark_point (); + g_cond_wait (&data.cond, &data.lock); + } + g_mutex_unlock (&data.lock); + GST_STATE_UNLOCK (pipeline); + + g_thread_join (thread); + g_signal_handler_disconnect (pipeline, signal_id); + base_time = gst_element_get_base_time (pipeline); + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (data.sinkpad); + gst_object_unref (pipeline); + gst_object_unref (clock); + g_cond_clear (&data.cond); + g_mutex_clear (&data.lock); + + fail_unless (data.stream_locked, "Worker did not acquire the stream lock"); + fail_unless (stream_lock_contended, + "Stream lock was unexpectedly available to the state-change thread"); + fail_unless (data.message_posted, "RESET_TIME message was not posted"); + fail_unless_equals_uint64 (base_time, 90 * GST_SECOND); + fail_if (data.do_latency_called && data.state_lock_contended, + "RESET_TIME synchronously recalculated latency while another thread " + "held the pipeline state lock"); +} + +GST_END_TEST; + GST_START_TEST (test_async_state_change_fake_ready) { GstPipeline *pipeline; @@ -748,6 +899,7 @@ suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_async_state_change_empty); + tcase_add_test (tc_chain, test_reset_time_during_state_change); tcase_add_test (tc_chain, test_async_state_change_fake_ready); tcase_add_test (tc_chain, test_async_state_change_fake); tcase_add_test (tc_chain, test_get_bus); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gstreamer-1.28.6/tests/validate/simplest.validatetest new/gstreamer-1.28.7/tests/validate/simplest.validatetest --- old/gstreamer-1.28.6/tests/validate/simplest.validatetest 2026-08-05 13:59:39.000000000 +0200 +++ new/gstreamer-1.28.7/tests/validate/simplest.validatetest 2026-09-07 21:11:13.000000000 +0200 @@ -1,12 +1,12 @@ meta, handles-states=true, ignore-eos=true, - args = { + args={ "fakesrc num-buffers=5 ! fakesink sync=true name=sink", }, - configs = { - "core, fail-on-missing-plugin=true", - "$(validateflow), pad=sink:sink, buffers-checksum=true", + configs={ + [core, fail-on-missing-plugin=true], + [validateflow, pad=sink:sink, buffers-checksum=true], } play @@ -14,4 +14,3 @@ crank-clock, repeat=5, expected-elapsed-time=0.0 stop, on-message=eos - ++++++ gstreamer.obsinfo ++++++ --- /var/tmp/diff_new_pack.Y57pUO/_old 2026-09-11 19:01:07.413098813 +0200 +++ /var/tmp/diff_new_pack.Y57pUO/_new 2026-09-11 19:01:07.421099147 +0200 @@ -1,5 +1,5 @@ name: gstreamer -version: 1.28.6 -mtime: 1785931179 -commit: 2d3e05cbdad68e47d645f548899b432dc9fb4473 +version: 1.28.7 +mtime: 1788808273 +commit: 070125524a8422e29d3b69a372ed4f62fd343ffa
