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 2025-07-03 12:09:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gstreamer-plugins-good (Old)
 and      /work/SRC/openSUSE:Factory/.gstreamer-plugins-good.new.1903 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gstreamer-plugins-good"

Thu Jul  3 12:09:59 2025 rev:119 rq:1289973 version:1.26.3

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/gstreamer-plugins-good/gstreamer-plugins-good.changes
    2025-06-06 22:34:51.496442697 +0200
+++ 
/work/SRC/openSUSE:Factory/.gstreamer-plugins-good.new.1903/gstreamer-plugins-good.changes
  2025-07-03 12:11:58.397463190 +0200
@@ -1,0 +2,24 @@
+Tue Jul  1 19:57:02 UTC 2025 - Bjørn Lie <bjorn....@gmail.com>
+
+- Update to version 1.26.3:
+  + aacparse: Fix counting audio channels in program_config_element
+  + adaptivedemux2: free cancellable when freeing transfer task
+  + dashdemux2: Fix seeking in a stream with gaps
+  + decodebin wavparse cannot pull header
+  + imagefreeze: fix not negotiate log when stop
+  + osxvideosink: Use gst_pad_push_event() and post navigation
+    messages
+  + qml6glsink: Allow configuring if the item will consume input
+    events
+  + qtmux: Update chunk offsets when converting stco to co64 with
+    faststart
+  + splitmuxsink: Only send closed message once per open fragment
+  + rtph265depay: CRA_NUT can also start an (open) GOP
+  + rtph265depay: fix codec_data generation
+  + rtspsrc: Don't emit error during close if server is EOF
+  + twcc: Fix reference timestamp wrapping (again)
+  + v4l2: Fix possible internal pool leak
+  + v4l2object: Add support for colorimetry bt2100-pq and 1:4:5:3
+  + wavparse: Don't error out always when parsing acid chunks
+
+-------------------------------------------------------------------

Old:
----
  gst-plugins-good-1.26.2.obscpio

New:
----
  gst-plugins-good-1.26.3.obscpio

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

Other differences:
------------------
++++++ gstreamer-plugins-good.spec ++++++
--- /var/tmp/diff_new_pack.hMJPNa/_old  2025-07-03 12:12:00.221538676 +0200
+++ /var/tmp/diff_new_pack.hMJPNa/_new  2025-07-03 12:12:00.225538842 +0200
@@ -33,7 +33,7 @@
 %endif
 
 Name:           gstreamer-plugins-good
-Version:        1.26.2
+Version:        1.26.3
 Release:        0
 Summary:        GStreamer Streaming-Media Framework Plug-Ins
 License:        LGPL-2.1-or-later

++++++ _service ++++++
--- /var/tmp/diff_new_pack.hMJPNa/_old  2025-07-03 12:12:00.305542153 +0200
+++ /var/tmp/diff_new_pack.hMJPNa/_new  2025-07-03 12:12:00.309542319 +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.26.2</param>
+    <param name="revision">1.26.3</param>
     <param name="versionformat">@PARENT_TAG@+@TAG_OFFSET@</param>
     <param name="versionrewrite-pattern">v?(.*)\+0</param>
     <param name="versionrewrite-replacement">\1</param>

++++++ gst-plugins-good-1.26.2.obscpio -> gst-plugins-good-1.26.3.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/NEWS 
new/gst-plugins-good-1.26.3/NEWS
--- old/gst-plugins-good-1.26.2/NEWS    2025-05-30 00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/NEWS    2025-06-26 22:25:24.000000000 +0200
@@ -1809,6 +1809,213 @@
 -   List of Merge Requests applied in 1.26.2
 -   List of Issues fixed in 1.26.2
 
+1.26.3
+
+The third 1.26 bug-fix release (1.26.3) was released on 26 June 2025.
+
+This release only contains bugfixes including some important playback fixes, 
and it should be safe to update from 1.26.x.
+
+Highlighted bugfixes in 1.26.3
+
+-   Security fix for the H.266 video parser
+-   Fix regression for WAV files with acid chunks
+-   Fix high memory consumption caused by a text handling regression in 
uridecodebin3 and playbin3
+-   Fix panic on late GOP in fragmented MP4 muxer
+-   Closed caption conversion, rendering and muxing improvements
+-   Decklink video sink preroll frame rendering and clock drift handling fixes
+-   MPEG-TS demuxing and muxing fixes
+-   MP4 muxer fixes for creating very large files with faststart support
+-   New thread-sharing 1:N inter source and sink elements, and a ts-rtpdtmfsrc
+-   New speech synthesis element around ElevenLabs API
+-   RTP H.265 depayloader fixes and improvements, as well as TWCC and GCC 
congestion control fixes
+-   Seeking improvements in DASH client for streams with gaps
+-   WebRTC sink and source fixes and enhancements, including to LiveKit and 
WHIP signallers
+-   The macOS osxvideosink now posts navigation messages
+-   QtQML6GL video sink input event handling improvements
+-   Overhaul detection of hardware-accelerated video codecs on Android
+-   Video4Linux capture source fixes and support for BT.2100 PQ and 1:4:5:3 
colorimetry
+-   Vulkan buffer upload and memory handling regression fixes
+-   gst-python: fix various regressions introduced in 1.26.2
+-   cerbero: fix text relocation issues on 32-bit Android and fix broken 
VisualStudio VC templates
+-   packages: ship pbtypes plugin and update openssl to 3.5.0 LTS
+-   Various bug fixes, build fixes, memory leak fixes, and other stability and 
reliability improvements
+
+gstreamer
+
+-   aggregator: Do not set event seqnum to INVALID
+-   baseparse: test: Fix race on test start
+-   pad: Only remove TAG events on STREAM_START if the stream-id actually 
changes
+-   utils: Mark times array as static to avoid symbol conflict with the POSIX 
function
+-   vecdeque: Use correct index type gst_vec_deque_drop_struct()
+
+gst-plugins-base
+
+-   GstAudioAggregator: fix structure unref in peek_next_sample()
+-   audioconvert: Fix setting mix-matrix when input caps changes
+-   encodebasebin: Duplicate encoding profile in property setter
+-   gl: simplify private gst_gl_gst_meta_api_type_tags_contain_only()
+-   osxvideosink: Use gst_pad_push_event() and post navigation messages
+-   playsink: Fix race condition in stream synchronizer pad cleanup during 
state changes
+-   python: Fix pulling events from appsink
+-   streamsynchronizer: Consider streams having received stream-start as 
waiting
+-   urisourcebin: Text tracks are no longer set as sparse stream in 
urisourcebin’s multiqueue
+
+gst-plugins-good
+
+-   aacparse: Fix counting audio channels in program_config_element
+-   adaptivedemux2: free cancellable when freeing transfer task
+-   dashdemux2: Fix seeking in a stream with gaps
+-   decodebin wavparse cannot pull header
+-   imagefreeze: fix not negotiate log when stop
+-   osxvideosink: Use gst_pad_push_event() and post navigation messages
+-   qml6glsink: Allow configuring if the item will consume input events
+-   qtmux: Update chunk offsets when converting stco to co64 with faststart
+-   splitmuxsink: Only send closed message once per open fragment
+-   rtph265depay: CRA_NUT can also start an (open) GOP
+-   rtph265depay: fix codec_data generation
+-   rtspsrc: Don’t emit error during close if server is EOF
+-   twcc: Fix reference timestamp wrapping (again)
+-   v4l2: Fix possible internal pool leak
+-   v4l2object: Add support for colorimetry bt2100-pq and 1:4:5:3
+-   wavparse: Don’t error out always when parsing acid chunks
+
+gst-plugins-bad
+
+-   amc: Overhaul hw-accelerated video codecs detection
+-   bayer2rgb: Fix RGB stride calculation
+-   d3d12compositor: Fix critical warnings
+-   dashsink: Fix failing test
+-   decklink: calculate internal using values closer to the current clock times
+-   decklinkvideosink: show preroll frame correctly
+-   decklink: clock synchronization after pause
+-   h266parser: Fix overflow when parsing subpic_level_info
+-   lcevcdec: Check for errors after receiving all enhanced and base pictures
+-   meson: fix building -bad tests with disabled soundtouch
+-   mpegts: handle MPEG2-TS with KLV metadata safely by preventing out of 
bounds
+-   mpegtsmux: Corrections around Teletext handling
+-   srtsink: Fix header buffer filtering
+-   transcoder: Fix uritranscodebin reference handling
+-   tsdemux: Allow access unit parsing failures
+-   tsdemux: Send new-segment before GAP
+-   vulkanupload: fix regression for uploading VulkanBuffer
+-   vulkanupload: fix regression when uploading to single memory multiplaned 
memory images.
+-   webrtcbin: disconnect signal ICE handlers on dispose
+-   {d3d12,d3d11}compositor: Fix negative position handling
+-   {nv,d3d12,d3d11}decoder: Use interlace info in input caps
+
+gst-plugins-ugly
+
+-   No changes
+
+GStreamer Rust plugins
+
+-   Add new speech synthesis element around ElevenLabs API
+-   cea708mux: fix another WouldOverflow case
+-   cea708mux: support configuring a limit to how much data will be pending
+-   cea708overlay: also reset the output size on flush stop
+-   gcc: handle out of order packets
+-   fmp4mux: Fix panic on late GOP
+-   livekit: expose a connection state property
+-   mp4mux: add taic box
+-   mp4mux: test the trak structure
+-   pcap_writer: Make target-property and pad-path properties writable again
+-   skia: Don’t build skia plugin by default for now
+-   threadshare: cleanups & usability improvements
+-   threadshare: sync runtime with latest async-io
+-   threadshare: fix kqueue reactor
+-   threadshare: Update to getifaddrs 0.2
+-   threadshare: add new thread-sharing inter elements
+-   threadshare: add a ts-rtpdtmfsrc element
+-   transcriberbin: fix naming of subtitle pads
+-   tttocea708: don’t panic if a new service would overflow
+-   webrtc: android: Update Gradle and migrate to FindGStreamerMobile
+-   webrtc: add new examples for stream selection over data channel
+-   webrtcsrc: the webrtcbin get-transceiver index is not mlineindex
+-   webrtcsrc: send CustomUpstream events over control channel ..
+-   webrtcsink: Don’t require encoder element for pre-encoded streams
+-   webrtcsink: Don’t reject caps events if the codec_data changes
+-   whip: server: pick session-id from the endpoint if specified
+-   cargo: add config file to force CARGO_NET_GIT_FETCH_WITH_CLI=true
+-   Cargo.lock, deny: Update dependencies and log duplicated targo-lexicon
+-   Update windows-sys dependency from “>=0.52, <=0.59” to “>=0.52, <=0.60”
+-   deny: Add override for windows-sys 0.59
+-   deny: Update lints
+-   cargo_wrapper: Fix backslashes being parsed as escape codes on Windows
+-   Fixes for Clock: non-optional return types
+-   Rename relationmeta plugin to analytics
+
+gst-libav
+
+-   No changes
+
+gst-rtsp-server
+
+-   rtsp-server: tests: Fix a few memory leaks
+
+gstreamer-vaapi
+
+-   No changes
+
+gstreamer-sharp
+
+-   No changes
+
+gst-python
+
+This release includes some important regression fixes for the GStreamer Python 
bindings for regressions introduced in 1.26.2.
+
+-   gst-python/tests: don’t depend on webrtc and rtsp-server
+-   python: Fix pulling events from appsink and other fixes
+
+gst-editing-services
+
+-   No changes
+
+gst-devtools, gst-validate + gst-integration-testsuites
+
+-   validate: More memory leaks
+-   validate: Valgrind fixes
+
+gst-examples
+
+-   No changes
+
+gstreamer-docs
+
+-   No changes
+
+Development build environment
+
+-   gst-env: Emit a warning about DYLD_LIBRARY_PATH on macOS
+
+Cerbero build tool and packaging changes in 1.26.3
+
+-   WiX: fix broken VC templates
+-   android: Don’t ignore text relocation errors on 32-bit, and error out if 
any are found
+-   build: source: handle existing .cargo/config.toml as in plugins-rs
+-   ci: Detect text relocations when building android examples
+-   gst-plugins-base: Ship pbtypes
+-   gst-plugins-base: Fix category of pbtypes
+-   gst-plugins-rs: Update for relationmeta -> analytics plugin rename
+-   libsoup.recipe: XML-RPC support was removed before the 3.0 release
+-   openssl: Update to 3.5.0 LTS
+
+Contributors to 1.26.3
+
+Albert Sjolund, Aleix Pol, Ben Butterworth, Brad Hards, César Alejandro 
Torrealba Vázquez, Changyong Ahn, Doug Nazar, Edward
+Hervey, Elliot Chen, Enrique Ocaña González, François Laignel, Glyn Davies, He 
Junyan, Jakub Adam, James Cowgill, Jan Alexander
+Steffens (heftig), Jan Schmidt, Jochen Henneberg, Johan Sternerup, Julian 
Bouzas, L. E. Segovia, Loïc Le Page, Mathieu
+Duponchelle, Matthew Waters, Nicolas Dufresne, Nirbheek Chauhan, Philippe 
Normand, Pratik Pachange, Qian Hu (胡骞), Sebastian
+Dröge, Seungha Yang, Taruntej Kanakamalla, Théo Maillart, Thibault Saunier, 
Tim-Philipp Müller, Víctor Manuel Jáquez Leal,
+Xavier Claessens,
+
+… and many others who have contributed bug reports, translations, sent 
suggestions or helped testing. Thank you all!
+
+List of merge requests and issues fixed in 1.26.3
+
+-   List of Merge Requests applied in 1.26.3
+-   List of Issues fixed in 1.26.3
+
 Schedule for 1.28
 
 Our next major feature release will be 1.28, and 1.27 will be the unstable 
development version leading up to the stable 1.28
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/RELEASE 
new/gst-plugins-good-1.26.3/RELEASE
--- old/gst-plugins-good-1.26.2/RELEASE 2025-05-30 00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/RELEASE 2025-06-26 22:25:24.000000000 +0200
@@ -1,4 +1,4 @@
-This is GStreamer gst-plugins-good 1.26.2.
+This is GStreamer gst-plugins-good 1.26.3.
 
 The GStreamer team is thrilled to announce a new major feature release
 of your favourite cross-platform multimedia framework!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-good-1.26.2/ext/adaptivedemux2/dash/gstmpdclient.c 
new/gst-plugins-good-1.26.3/ext/adaptivedemux2/dash/gstmpdclient.c
--- old/gst-plugins-good-1.26.2/ext/adaptivedemux2/dash/gstmpdclient.c  
2025-05-30 00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/ext/adaptivedemux2/dash/gstmpdclient.c  
2025-06-26 22:25:24.000000000 +0200
@@ -1710,10 +1710,16 @@
         GstClockTime chunk_time;
 
         selectedChunk = segment;
-        repeat_index =
-            ((ts - segment->start) +
-            ((GstMediaSegment *) stream->segments->pdata[0])->start) /
-            segment->duration;
+        if (ts < segment->start) {
+          /* Seek time lies in a gap between segments. Continue playing from
+           * the first repetition of selectedChunk. */
+          repeat_index = 0;
+        } else {
+          repeat_index =
+              ((ts - segment->start) +
+              ((GstMediaSegment *) stream->segments->pdata[0])->start) /
+              segment->duration;
+        }
 
         chunk_time = segment->start + segment->duration * repeat_index;
 
@@ -1738,7 +1744,7 @@
           }
         } else if (((forward && flags & GST_SEEK_FLAG_SNAP_AFTER) ||
                 (!forward && flags & GST_SEEK_FLAG_SNAP_BEFORE)) &&
-            ts != chunk_time) {
+            ts > chunk_time) {
 
           if (repeat_index + 1 < segment->repeat) {
             repeat_index++;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-good-1.26.2/ext/adaptivedemux2/downloadhelper.c 
new/gst-plugins-good-1.26.3/ext/adaptivedemux2/downloadhelper.c
--- old/gst-plugins-good-1.26.2/ext/adaptivedemux2/downloadhelper.c     
2025-05-30 00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/ext/adaptivedemux2/downloadhelper.c     
2025-06-26 22:25:24.000000000 +0200
@@ -93,6 +93,7 @@
   if (transfer->blocking)
     g_cond_clear (&transfer->cond);
 
+  g_clear_object (&transfer->cancellable);
   g_object_unref (transfer->msg);
   g_free (transfer->read_buffer);
   g_free (transfer);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/ext/qt/qtitem.cc 
new/gst-plugins-good-1.26.3/ext/qt/qtitem.cc
--- old/gst-plugins-good-1.26.2/ext/qt/qtitem.cc        2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/ext/qt/qtitem.cc        2025-06-26 
22:25:24.000000000 +0200
@@ -207,6 +207,16 @@
   return this->priv->force_aspect_ratio;
 }
 
+void
+QtGLVideoItem::setAcceptEvents(bool accept)
+{
+  if (accept == acceptEvents)
+    return;
+
+  acceptEvents = accept;
+  Q_EMIT acceptEventsChanged(acceptEvents);
+}
+
 bool
 QtGLVideoItem::itemInitialized()
 {
@@ -495,18 +505,21 @@
     g_object_unref (element);
   }
   g_mutex_unlock (&this->priv->lock);
+  event->setAccepted(acceptEvents);
 }
 
 void
-QtGLVideoItem::hoverEnterEvent(QHoverEvent *)
+QtGLVideoItem::hoverEnterEvent(QHoverEvent *event)
 {
   mouseHovering = true;
+  event->setAccepted(acceptEvents);
 }
 
 void
-QtGLVideoItem::hoverLeaveEvent(QHoverEvent *)
+QtGLVideoItem::hoverLeaveEvent(QHoverEvent *event)
 {
   mouseHovering = false;
+  event->setAccepted(acceptEvents);
 }
 
 void
@@ -535,6 +548,7 @@
     }
   }
   g_mutex_unlock (&this->priv->lock);
+  event->setAccepted(acceptEvents);
 }
 
 void
@@ -597,6 +611,7 @@
 
   g_object_unref (element);
   g_mutex_unlock (&this->priv->lock);
+  event->setAccepted(acceptEvents);
 }
 
 void
@@ -649,12 +664,14 @@
 {
   forceActiveFocus();
   sendMouseEvent(event, TRUE);
+  event->setAccepted(acceptEvents);
 }
 
 void
 QtGLVideoItem::mouseReleaseEvent(QMouseEvent * event)
 {
   sendMouseEvent(event, FALSE);
+  event->setAccepted(acceptEvents);
 }
 
 void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/ext/qt/qtitem.h 
new/gst-plugins-good-1.26.3/ext/qt/qtitem.h
--- old/gst-plugins-good-1.26.2/ext/qt/qtitem.h 2025-05-30 00:56:43.000000000 
+0200
+++ new/gst-plugins-good-1.26.3/ext/qt/qtitem.h 2025-06-26 22:25:24.000000000 
+0200
@@ -71,6 +71,10 @@
                READ getForceAspectRatio
                WRITE setForceAspectRatio
                NOTIFY forceAspectRatioChanged)
+    Q_PROPERTY(bool acceptEvents
+               READ getAcceptEvents
+               WRITE setAcceptEvents
+               NOTIFY acceptEventsChanged)
 
 public:
     QtGLVideoItem();
@@ -82,6 +86,9 @@
     bool getForceAspectRatio();
     bool itemInitialized();
 
+    bool getAcceptEvents() const { return acceptEvents; }
+    void setAcceptEvents(bool accept);
+
     QSharedPointer<QtGLVideoItemInterface> getInterface() { return proxy; };
     /* private for C interface ... */
     QtGLVideoItemPrivate *priv;
@@ -89,6 +96,7 @@
 Q_SIGNALS:
     void itemInitializedChanged();
     void forceAspectRatioChanged(bool);
+    void acceptEventsChanged(bool acceptEvents);
 
 private Q_SLOTS:
     void handleWindowChanged(QQuickWindow * win);
@@ -117,6 +125,7 @@
 
     quint32 mousePressedButton;
     bool mouseHovering;
+    bool acceptEvents = true;
 
     QSharedPointer<QtGLVideoItemInterface> proxy;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/ext/qt6/qt6glitem.cc 
new/gst-plugins-good-1.26.3/ext/qt6/qt6glitem.cc
--- old/gst-plugins-good-1.26.2/ext/qt6/qt6glitem.cc    2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/ext/qt6/qt6glitem.cc    2025-06-26 
22:25:24.000000000 +0200
@@ -193,6 +193,16 @@
   emit forceAspectRatioChanged(force_aspect_ratio);
 }
 
+void
+Qt6GLVideoItem::setAcceptEvents(bool accept)
+{
+  if (accept == acceptEvents)
+    return;
+
+  acceptEvents = accept;
+  Q_EMIT acceptEventsChanged(acceptEvents);
+}
+
 bool
 Qt6GLVideoItem::getForceAspectRatio()
 {
@@ -487,18 +497,22 @@
     g_object_unref (element);
   }
   g_mutex_unlock (&this->priv->lock);
+
+  event->setAccepted(acceptEvents);
 }
 
 void
-Qt6GLVideoItem::hoverEnterEvent(QHoverEvent *)
+Qt6GLVideoItem::hoverEnterEvent(QHoverEvent *event)
 {
   mouseHovering = true;
+  event->setAccepted(acceptEvents);
 }
 
 void
-Qt6GLVideoItem::hoverLeaveEvent(QHoverEvent *)
+Qt6GLVideoItem::hoverLeaveEvent(QHoverEvent *event)
 {
   mouseHovering = false;
+  event->setAccepted(acceptEvents);
 }
 
 void
@@ -527,6 +541,7 @@
     }
   }
   g_mutex_unlock (&this->priv->lock);
+  event->setAccepted(acceptEvents);
 }
 
 void
@@ -589,6 +604,7 @@
 
   g_object_unref (element);
   g_mutex_unlock (&this->priv->lock);
+  event->setAccepted(acceptEvents);
 }
 
 void
@@ -641,12 +657,14 @@
 {
   forceActiveFocus();
   sendMouseEvent(event, TRUE);
+  event->setAccepted(acceptEvents);
 }
 
 void
 Qt6GLVideoItem::mouseReleaseEvent(QMouseEvent * event)
 {
   sendMouseEvent(event, FALSE);
+  event->setAccepted(acceptEvents);
 }
 
 void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/ext/qt6/qt6glitem.h 
new/gst-plugins-good-1.26.3/ext/qt6/qt6glitem.h
--- old/gst-plugins-good-1.26.2/ext/qt6/qt6glitem.h     2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/ext/qt6/qt6glitem.h     2025-06-26 
22:25:24.000000000 +0200
@@ -73,7 +73,10 @@
                READ getForceAspectRatio
                WRITE setForceAspectRatio
                NOTIFY forceAspectRatioChanged)
-
+    Q_PROPERTY(bool acceptEvents
+               READ getAcceptEvents
+               WRITE setAcceptEvents
+               NOTIFY acceptEventsChanged)
 public:
     Qt6GLVideoItem();
     ~Qt6GLVideoItem();
@@ -83,6 +86,8 @@
     void setForceAspectRatio(bool);
     bool getForceAspectRatio();
     bool itemInitialized();
+    bool getAcceptEvents() const { return acceptEvents; }
+    void setAcceptEvents(bool accept);
 
     QSharedPointer<Qt6GLVideoItemInterface> getInterface() { return proxy; };
     /* private for C interface ... */
@@ -91,6 +96,7 @@
 Q_SIGNALS:
     void itemInitializedChanged();
     void forceAspectRatioChanged(bool);
+    void acceptEventsChanged(bool acceptEvents);
 
 private Q_SLOTS:
     void handleWindowChanged(QQuickWindow * win);
@@ -120,6 +126,7 @@
 
     quint32 mousePressedButton;
     bool mouseHovering;
+    bool acceptEvents = true;
 
     QSharedPointer<Qt6GLVideoItemInterface> proxy;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-good-1.26.2/gst/audioparsers/gstaacparse.c 
new/gst-plugins-good-1.26.3/gst/audioparsers/gstaacparse.c
--- old/gst-plugins-good-1.26.2/gst/audioparsers/gstaacparse.c  2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst/audioparsers/gstaacparse.c  2025-06-26 
22:25:24.000000000 +0200
@@ -555,6 +555,12 @@
   guint8 num_side_channel_elements;
   guint8 num_back_channel_elements;
   guint8 num_lfe_channel_elements;
+  guint8 program_config_skipping_data;
+  guint8 mixdown_present_skipflag;
+  guint8 is_cpe;
+  guint8 total_num_channel_elements;
+  guint8 total_num_channel;
+  guint8 channel_element_tag;
 
   if (!gst_bit_reader_get_bits_uint8 (br, &element_instance_tag, 4))
     return FALSE;
@@ -568,13 +574,55 @@
     return FALSE;
   if (!gst_bit_reader_get_bits_uint8 (br, &num_back_channel_elements, 4))
     return FALSE;
-  if (!gst_bit_reader_get_bits_uint8 (br, &num_lfe_channel_elements, 4))
+  if (!gst_bit_reader_get_bits_uint8 (br, &num_lfe_channel_elements, 2))
     return FALSE;
-  GST_LOG_OBJECT (aacparse, "channels front %d side %d back %d lfe %d ",
-      num_front_channel_elements, num_side_channel_elements,
-      num_back_channel_elements, num_lfe_channel_elements);
-  *channels = num_front_channel_elements + num_side_channel_elements +
-      num_back_channel_elements + num_lfe_channel_elements;
+
+  // skip num_assoc_data_elements + num_valid_cc_elements
+  if (!gst_bit_reader_get_bits_uint8 (br, &program_config_skipping_data, 7))
+    return FALSE;
+
+  if (!gst_bit_reader_get_bits_uint8 (br, &mixdown_present_skipflag, 1))
+    return FALSE;
+
+  // skip mono_mixdown_element_number
+  if (mixdown_present_skipflag)
+    if (!gst_bit_reader_get_bits_uint8 (br, &program_config_skipping_data, 4))
+      return FALSE;
+
+  if (!gst_bit_reader_get_bits_uint8 (br, &mixdown_present_skipflag, 1))
+    return FALSE;
+
+  // skip stereo_mixdown_element_number
+  if (mixdown_present_skipflag)
+    if (!gst_bit_reader_get_bits_uint8 (br, &program_config_skipping_data, 4))
+      return FALSE;
+
+  if (!gst_bit_reader_get_bits_uint8 (br, &mixdown_present_skipflag, 1))
+    return FALSE;
+
+  // skip matrix_mixdown_idx + pseudo_surround_enable
+  if (mixdown_present_skipflag) {
+    if (!gst_bit_reader_get_bits_uint8 (br, &program_config_skipping_data, 3))
+      return FALSE;
+  }
+
+  total_num_channel_elements =
+      num_front_channel_elements + num_side_channel_elements +
+      num_back_channel_elements;
+
+  total_num_channel = total_num_channel_elements + num_lfe_channel_elements;
+  // If cpe (coupled), then each single channel element represents two channels
+  for (guint8 i = 0; i < total_num_channel_elements; i++) {
+    if (!gst_bit_reader_get_bits_uint8 (br, &is_cpe, 1))
+      return FALSE;
+    if (is_cpe)
+      total_num_channel += 1;
+    if (!gst_bit_reader_get_bits_uint8 (br, &channel_element_tag, 4))
+      return FALSE;
+  }
+
+  *channels = total_num_channel;
+  GST_LOG_OBJECT (aacparse, "total channels : %d", *channels);
 
   return TRUE;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-good-1.26.2/gst/imagefreeze/gstimagefreeze.c 
new/gst-plugins-good-1.26.3/gst/imagefreeze/gstimagefreeze.c
--- old/gst-plugins-good-1.26.2/gst/imagefreeze/gstimagefreeze.c        
2025-05-30 00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst/imagefreeze/gstimagefreeze.c        
2025-06-26 22:25:24.000000000 +0200
@@ -85,6 +85,8 @@
     GstEvent * event);
 static gboolean gst_image_freeze_src_query (GstPad * pad, GstObject * parent,
     GstQuery * query);
+static gboolean gst_image_freeze_src_activate_mode (GstPad * pad,
+    GstObject * parent, GstPadMode mode, gboolean active);
 
 static GstStaticPadTemplate sink_pad_template = GST_STATIC_PAD_TEMPLATE 
("sink",
     GST_PAD_SINK,
@@ -178,6 +180,8 @@
       GST_DEBUG_FUNCPTR (gst_image_freeze_src_event));
   gst_pad_set_query_function (self->srcpad,
       GST_DEBUG_FUNCPTR (gst_image_freeze_src_query));
+  gst_pad_set_activatemode_function (self->srcpad,
+      GST_DEBUG_FUNCPTR (gst_image_freeze_src_activate_mode));
   gst_pad_use_fixed_caps (self->srcpad);
   gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
 
@@ -609,6 +613,45 @@
   return ret;
 }
 
+static gboolean
+gst_image_freeze_src_activate_mode (GstPad * pad, GstObject * parent,
+    GstPadMode mode, gboolean active)
+{
+  gboolean res;
+  GstImageFreeze *self = GST_IMAGE_FREEZE (parent);
+
+  switch (mode) {
+    case GST_PAD_MODE_PUSH:
+      if (!active) {
+        GST_DEBUG_OBJECT (pad, "Pad deactivating");
+
+        g_mutex_lock (&self->lock);
+        self->flushing = TRUE;
+        if (self->clock_id) {
+          GST_DEBUG_OBJECT (self, "unlock clock wait");
+          gst_clock_id_unschedule (self->clock_id);
+        }
+        g_cond_signal (&self->blocked_cond);
+        g_mutex_unlock (&self->lock);
+
+        res = gst_pad_stop_task (pad);
+        gst_image_freeze_reset (self);
+      } else {
+        GST_DEBUG_OBJECT (pad, "Pad activating");
+        gst_image_freeze_reset (self);
+
+        g_mutex_lock (&self->lock);
+        self->flushing = FALSE;
+        g_mutex_unlock (&self->lock);
+        res = TRUE;
+      }
+      break;
+    default:
+      res = FALSE;
+      break;
+  }
+  return res;
+}
 
 static gboolean
 gst_image_freeze_sink_event (GstPad * pad, GstObject * parent, GstEvent * 
event)
@@ -866,6 +909,14 @@
   GstFlowReturn flow_ret;
 
   g_mutex_lock (&self->lock);
+
+  if (self->flushing) {
+    GST_DEBUG_OBJECT (pad, "Flushing");
+    gst_buffer_unref (buffer);
+    g_mutex_unlock (&self->lock);
+    return GST_FLOW_FLUSHING;
+  }
+
   if (self->buffer && !self->allow_replace) {
     GST_DEBUG_OBJECT (pad, "Already have a buffer, dropping");
     gst_buffer_unref (buffer);
@@ -1192,9 +1243,7 @@
 
   switch (transition) {
     case GST_STATE_CHANGE_READY_TO_PAUSED:
-      gst_image_freeze_reset (self);
       g_mutex_lock (&self->lock);
-      self->flushing = FALSE;
       self->blocked = TRUE;
       g_mutex_unlock (&self->lock);
       if (self->is_live)
@@ -1208,16 +1257,9 @@
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       g_mutex_lock (&self->lock);
-      self->flushing = TRUE;
-      if (self->clock_id) {
-        GST_DEBUG_OBJECT (self, "unlock clock wait");
-        gst_clock_id_unschedule (self->clock_id);
-      }
       self->blocked = FALSE;
       g_cond_signal (&self->blocked_cond);
       g_mutex_unlock (&self->lock);
-      gst_image_freeze_reset (self);
-      gst_pad_stop_task (self->srcpad);
       break;
     default:
       break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/gst/isomp4/atoms.c 
new/gst-plugins-good-1.26.3/gst/isomp4/atoms.c
--- old/gst-plugins-good-1.26.2/gst/isomp4/atoms.c      2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst/isomp4/atoms.c      2025-06-26 
22:25:24.000000000 +0200
@@ -3475,6 +3475,67 @@
   moov->chunks_offset = offset;
 }
 
+guint64
+atom_moov_calc_stco_to_co64_conversion_total_offset (AtomMOOV * moov,
+    guint64 offset)
+{
+  /* Whenever any stco32 chunk offset exceeds its 32-bit limit, the
+   * corresponding stco32 atom must be converted to a stco64 atom, increasing
+   * its size. Because faststart files place the moov atom before the mdat
+   * atom, this conversion must increase the value of the chunk offsets in all
+   * stco32 and stco64 atoms, so they continue to point to the correct
+   * positions within the mdat atom. Increasing the chunk offsets in a single
+   * stco32 atom may require its conversion to stco64. This in turn increases
+   * the chunk offsets of other atoms, some of which may also need to be
+   * converted, potentially requiring further conversions.
+   *
+   * This function takes as input an offset representing the size from the
+   * start of the moov atom to the start of the mdat data. It uses this offset
+   * to determine whether any stco32 atom would require conversion to stco64,
+   * incrementing the offset accordingly. The function returns this total
+   * offset that should be applied to adjust the chunk offsets in all
+   * stco32 and stco64 atoms. It does not perform any atom conversions nor
+   * update any chunk offsets itself, as this is done by subsequent calls to
+   * atom_moov_chunks_set_offset() and atom_moov_copy_data() (in that order).
+   */
+
+  GList *stco32_atoms = NULL;
+  for (GList * l = moov->traks; l; l = l->next) {
+    AtomTRAK *trak = (AtomTRAK *) l->data;
+    AtomSTCO64 *stco64 = (AtomSTCO64 *) & trak->mdia.minf.stbl.stco64;
+    if (stco64->header.header.type == FOURCC_stco) {
+      stco32_atoms = g_list_prepend (stco32_atoms, stco64);
+    }
+  }
+
+  GList *pending_stco32_atoms = stco32_atoms;
+  while (pending_stco32_atoms) {
+    AtomSTCO64 *stco64 = (AtomSTCO64 *) pending_stco32_atoms->data;
+
+    if ((stco64->max_offset + offset) > G_MAXUINT32) {
+      /* This stco32 atom must be converted to stco64 to be able to accommodate
+       * its new maximum offset, which exceeds the representable range of a
+       * 32-bit entry and therefore requires a 64-bit one. Neither this
+       * conversion nor the update of the atom's maximum chunk offset is
+       * performed by this function.
+       * However, the value of the total offset must be increased to account
+       * for the larger size of a stco64 atom, as each one of its chunk offset
+       * entries will be increased from 4 bytes to 8 bytes. */
+      offset += atom_array_get_len (&stco64->entries) * 4;
+      /* This atom must be treated as it were already converted to stco64. All
+       * stco32 atoms must be re-evaluated considering the updated offset. */
+      stco32_atoms = g_list_remove (stco32_atoms, stco64);
+      pending_stco32_atoms = stco32_atoms;
+    } else {
+      pending_stco32_atoms = g_list_next (pending_stco32_atoms);
+    }
+  }
+
+  g_list_free (stco32_atoms);
+
+  return offset;
+}
+
 void
 atom_trak_update_bitrates (AtomTRAK * trak, guint32 avg_bitrate,
     guint32 max_bitrate)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/gst/isomp4/atoms.h 
new/gst-plugins-good-1.26.3/gst/isomp4/atoms.h
--- old/gst-plugins-good-1.26.2/gst/isomp4/atoms.h      2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst/isomp4/atoms.h      2025-06-26 
22:25:24.000000000 +0200
@@ -967,6 +967,7 @@
 void       atom_moov_chunks_set_offset (AtomMOOV *moov, guint32 offset);
 void       atom_moov_add_trak          (AtomMOOV *moov, AtomTRAK *trak);
 guint      atom_moov_get_trak_count    (AtomMOOV *moov);
+guint64    atom_moov_calc_stco_to_co64_conversion_total_offset (AtomMOOV 
*moov, guint64 offset);
 
 guint      atom_framerate_to_timescale (gint fps_n, gint fps_d);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/gst/isomp4/gstqtmux.c 
new/gst-plugins-good-1.26.3/gst/isomp4/gstqtmux.c
--- old/gst-plugins-good-1.26.2/gst/isomp4/gstqtmux.c   2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst/isomp4/gstqtmux.c   2025-06-26 
22:25:24.000000000 +0200
@@ -4198,9 +4198,18 @@
       ret = gst_qt_mux_send_extra_atoms (qtmux, FALSE, &offset, FALSE);
       if (ret != GST_FLOW_OK)
         return ret;
+
+      offset =
+          atom_moov_calc_stco_to_co64_conversion_total_offset (qtmux->moov,
+          offset);
       break;
     }
     default:
+      /* The file is not being written as faststart, so the offset, which
+       * corresponds to the file size up to the start of the mdat payload, does
+       * not include the size of the moov atom, as this comes after the mdat
+       * atom. Therefore, any changes to the moov atom will not affect the
+       * offset value assigned here */
       offset = qtmux->header_size;
       break;
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-good-1.26.2/gst/multifile/gstsplitmuxsink.c 
new/gst-plugins-good-1.26.3/gst/multifile/gstsplitmuxsink.c
--- old/gst-plugins-good-1.26.2/gst/multifile/gstsplitmuxsink.c 2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst/multifile/gstsplitmuxsink.c 2025-06-26 
22:25:24.000000000 +0200
@@ -184,6 +184,7 @@
 static GQuark PAD_CONTEXT;
 static GQuark EOS_FROM_US;
 static GQuark SINK_FRAGMENT_INFO;
+static GQuark SENT_FRAGMENT_CLOSED;
 /* EOS_FROM_US is only valid in async-finalize mode. We need to know whether
  * to forward an incoming EOS message, but we cannot rely on the state of the
  * splitmux anymore, so we set this qdata on the sink instead.
@@ -207,6 +208,8 @@
   EOS_FROM_US = g_quark_from_static_string ("splitmuxsink-eos-from-us");
   SINK_FRAGMENT_INFO =
       g_quark_from_static_string ("splitmuxsink-fragment-info");
+  SENT_FRAGMENT_CLOSED =
+      g_quark_from_static_string ("splitmuxsink-sent-fragment-closed");
   GST_DEBUG_CATEGORY_INIT (splitmux_debug, "splitmuxsink", 0,
       "Split File Muxing Sink");
 }
@@ -2322,6 +2325,7 @@
   g_list_foreach (splitmux->contexts, (GFunc) restart_context, splitmux);
 
   update_output_fragment_info (splitmux);
+  g_object_set_qdata ((GObject *) sink, SENT_FRAGMENT_CLOSED, NULL);
   send_fragment_opened_closed_msg (splitmux, TRUE, sink);
 
   /* FIXME: Is this always the correct next state? */
@@ -2376,7 +2380,11 @@
       sink = GST_ELEMENT (GST_MESSAGE_SRC (message));
       GST_SPLITMUX_LOCK (splitmux);
 
-      send_fragment_opened_closed_msg (splitmux, FALSE, sink);
+      if (!g_object_get_qdata ((GObject *) sink, SENT_FRAGMENT_CLOSED)) {
+        send_fragment_opened_closed_msg (splitmux, FALSE, sink);
+        g_object_set_qdata ((GObject *) sink, SENT_FRAGMENT_CLOSED,
+            GINT_TO_POINTER (TRUE));
+      }
 
       if (splitmux->async_finalize) {
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/gst/rtp/gstrtph265depay.c 
new/gst-plugins-good-1.26.3/gst/rtp/gstrtph265depay.c
--- old/gst-plugins-good-1.26.2/gst/rtp/gstrtph265depay.c       2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst/rtp/gstrtph265depay.c       2025-06-26 
22:25:24.000000000 +0200
@@ -503,6 +503,7 @@
     GstBitReader br;
     guint32 tmp;
     guint8 tmp8 = 0;
+    gsize src_offset, dst_offset;
     guint32 max_sub_layers_minus1, temporal_id_nesting_flag, chroma_format_idc,
         bit_depth_luma_minus8, bit_depth_chroma_minus8,
         min_spatial_segmentation_idc;
@@ -544,7 +545,42 @@
     max_sub_layers_minus1 = ((nalmap.data[2]) >> 1) & 0x07;
     temporal_id_nesting_flag = nalmap.data[2] & 0x01;
 
-    gst_bit_reader_init (&br, nalmap.data + 15, nalmap.size - 15);
+    /* HEVCDecoderConfigurationVersion = 1 */
+    data[0] = 1;
+
+    /* Copy from profile_tier_level (Rec. ITU-T H.265 (04/2013) section 7.3.3
+     *
+     * profile_space | tier_flat | profile_idc |
+     * profile_compatibility_flags | constraint_indicator_flags |
+     * level_idc | progressive_source_flag | interlaced_source_flag
+     * non_packed_constraint_flag | frame_only_constraint_flag
+     * reserved_zero_44bits | level_idc */
+
+    guint n_zero_bytes = 0;
+    // 16 bit nal header and sps-vps id.
+    for (src_offset = 3, dst_offset = 1; dst_offset < 13; src_offset++) {
+      if (src_offset >= nalmap.size)
+        // SPS not long enough
+        return FALSE;
+
+      if (n_zero_bytes == 2 && nalmap.data[src_offset] == 0x03) {
+        n_zero_bytes = 0;
+        // ignore emulation prevention bytes: [0x00, 0x00, 0x03]
+        continue;
+      }
+
+      if (nalmap.data[src_offset] == 0x00)
+        n_zero_bytes++;
+      else
+        n_zero_bytes = 0;
+
+      data[dst_offset] = nalmap.data[src_offset];
+      dst_offset++;
+    }
+
+    // FIXME: does not parse any sub layers
+    gst_bit_reader_init (&br, nalmap.data + src_offset,
+        nalmap.size - src_offset);
 
     gst_rtp_read_golomb (&br, &tmp);    /* sps_seq_parameter_set_id */
     gst_rtp_read_golomb (&br, &chroma_format_idc);      /* chroma_format_idc */
@@ -570,23 +606,6 @@
         "Ignoring min_spatial_segmentation for now (assuming zero)");
 
     min_spatial_segmentation_idc = 0;   /* NOTE - we ignore this for now, but 
in a perfect world, we should continue parsing to obtain the real value */
-
-    gst_buffer_unmap (g_ptr_array_index (rtph265depay->sps, 0), &nalmap);
-
-    /* HEVCDecoderConfigurationVersion = 1 */
-    data[0] = 1;
-
-    /* Copy from profile_tier_level (Rec. ITU-T H.265 (04/2013) section 7.3.3
-     *
-     * profile_space | tier_flat | profile_idc |
-     * profile_compatibility_flags | constraint_indicator_flags |
-     * level_idc | progressive_source_flag | interlaced_source_flag
-     * non_packed_constraint_flag | frame_only_constraint_flag
-     * reserved_zero_44bits | level_idc */
-    gst_buffer_map (g_ptr_array_index (rtph265depay->sps, 0), &nalmap,
-        GST_MAP_READ);
-    for (i = 0; i < 12; i++)
-      data[i + 1] = nalmap.data[i];
     gst_buffer_unmap (g_ptr_array_index (rtph265depay->sps, 0), &nalmap);
 
     /* min_spatial_segmentation_idc */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/gst/rtp/gstrtph265pay.c 
new/gst-plugins-good-1.26.3/gst/rtp/gstrtph265pay.c
--- old/gst-plugins-good-1.26.2/gst/rtp/gstrtph265pay.c 2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst/rtp/gstrtph265pay.c 2025-06-26 
22:25:24.000000000 +0200
@@ -1094,7 +1094,8 @@
         }
       } else if (rtph265pay->vps_sps_pps_interval == -1
           && (nal_type == GST_H265_NAL_SLICE_IDR_W_RADL
-              || nal_type == GST_H265_NAL_SLICE_IDR_N_LP)) {
+              || nal_type == GST_H265_NAL_SLICE_IDR_N_LP
+              || nal_type == GST_H265_NAL_SLICE_CRA_NUT)) {
         /* send VPS/SPS/PPS before every IDR frame */
         send_ps = TRUE;
       }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/gst/rtpmanager/rtptwcc.c 
new/gst-plugins-good-1.26.3/gst/rtpmanager/rtptwcc.c
--- old/gst-plugins-good-1.26.2/gst/rtpmanager/rtptwcc.c        2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst/rtpmanager/rtptwcc.c        2025-06-26 
22:25:24.000000000 +0200
@@ -105,7 +105,7 @@
   GstClockTime feedback_interval;
 
   guint64 remote_ts_base;
-  gint64 base_time_prev;
+  guint32 base_time_prev;
 };
 
 G_DEFINE_TYPE (RTPTWCCManager, rtp_twcc_manager, G_TYPE_OBJECT);
@@ -128,7 +128,9 @@
   twcc->feedback_interval = GST_CLOCK_TIME_NONE;
   twcc->next_feedback_send_time = GST_CLOCK_TIME_NONE;
 
-  twcc->remote_ts_base = -1;
+  /* Start with an initial offset of 1 << 24 so that we don't risk going below 0
+     if a future timestamp is earlier than the first. */
+  twcc->remote_ts_base = G_GINT64_CONSTANT (1) << 24;
 }
 
 static void
@@ -1019,8 +1021,8 @@
   GArray *twcc_packets;
   guint16 base_seqnum;
   guint16 packet_count;
-  GstClockTime base_time;
-  gint64 base_time_ext;
+  guint32 base_time;
+  gint64 base_time_diff;
   GstClockTime ts_rounded;
   guint8 fb_pkt_count;
   guint packets_parsed = 0;
@@ -1036,10 +1038,6 @@
   base_seqnum = GST_READ_UINT16_BE (&fci_data[0]);
   packet_count = GST_READ_UINT16_BE (&fci_data[2]);
   base_time = GST_READ_UINT24_BE (&fci_data[4]);
-  /* Sign-extend the base_time from a 24-bit integer into a 64-bit signed 
integer
-   * so that we can calculate diffs with regular 64-bit operations. */
-  base_time_ext =
-      (base_time & 0x800000) ? base_time | 0xFFFFFFFFFF800000 : base_time;
   fb_pkt_count = fci_data[7];
 
   GST_DEBUG ("Parsed TWCC feedback: base_seqnum: #%u, packet_count: %u, "
@@ -1075,17 +1073,16 @@
   if (twcc->sent_packets->len > 0)
     first_sent_pkt = &g_array_index (twcc->sent_packets, SentPacket, 0);
 
-  if (twcc->remote_ts_base == -1) {
-    /* Add an initial offset of 1 << 24 so that we don't risk going below 0 if
-     * a future extended timestamp is earlier than the first. */
-    twcc->remote_ts_base = (G_GINT64_CONSTANT (1) << 24) + base_time_ext;
-  } else {
-    /* Calculate our internal accumulated reference timestamp by continously
-     * adding the diff between the current and the previous sign-extended
-     * reference time. */
-    twcc->remote_ts_base += base_time_ext - twcc->base_time_prev;
-  }
-  twcc->base_time_prev = base_time_ext;
+  base_time_diff = (gint64) ((base_time - twcc->base_time_prev) & 0xFFFFFF);
+  if (base_time_diff >= 0x7FFFFF) {
+    base_time_diff -= 0x1000000;
+  }
+  twcc->base_time_prev = base_time;
+
+  /* Calculate our internal accumulated reference timestamp by continously
+     adding the diff between the current and the previous reference time. */
+  twcc->remote_ts_base += base_time_diff;
+
   /* Our internal accumulated reference time is in units of 64ms, propagate as
    * GstClockTime in ns. */
   ts_rounded = twcc->remote_ts_base * REF_TIME_UNIT;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/gst/rtsp/gstrtspsrc.c 
new/gst-plugins-good-1.26.3/gst/rtsp/gstrtspsrc.c
--- old/gst-plugins-good-1.26.2/gst/rtsp/gstrtspsrc.c   2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst/rtsp/gstrtspsrc.c   2025-06-26 
22:25:24.000000000 +0200
@@ -7246,6 +7246,9 @@
 
 send_error:
   {
+    if (src->busy_cmd == CMD_CLOSE && res == GST_RTSP_EEOF)
+      return res;
+
     gchar *str = gst_rtsp_strresult (res);
 
     if (res != GST_RTSP_EINTR) {
@@ -9279,6 +9282,9 @@
   }
 send_error:
   {
+    if (res == GST_RTSP_EEOF)
+      goto close;
+
     gchar *str = gst_rtsp_strresult (res);
 
     gst_rtsp_message_unset (&request);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/gst/wavparse/gstwavparse.c 
new/gst-plugins-good-1.26.3/gst/wavparse/gstwavparse.c
--- old/gst-plugins-good-1.26.2/gst/wavparse/gstwavparse.c      2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst/wavparse/gstwavparse.c      2025-06-26 
22:25:24.000000000 +0200
@@ -1482,7 +1482,6 @@
           buf = NULL;
           res =
               gst_wavparse_pull_range_exact (wav, wav->offset + 8, size, &buf);
-          goto header_pull_error;
           if (res == GST_FLOW_EOS)
             break;
           else if (res != GST_FLOW_OK)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/gst-plugins-good.doap 
new/gst-plugins-good-1.26.3/gst-plugins-good.doap
--- old/gst-plugins-good-1.26.2/gst-plugins-good.doap   2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/gst-plugins-good.doap   2025-06-26 
22:25:24.000000000 +0200
@@ -34,6 +34,16 @@
 
  <release>
   <Version>
+   <revision>1.26.3</revision>
+   <branch>1.26</branch>
+   <name></name>
+   <created>2025-06-26</created>
+   <file-release 
rdf:resource="https://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-1.26.3.tar.xz";
 />
+  </Version>
+ </release>
+
+ <release>
+  <Version>
    <revision>1.26.2</revision>
    <branch>1.26</branch>
    <name></name>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/meson.build 
new/gst-plugins-good-1.26.3/meson.build
--- old/gst-plugins-good-1.26.2/meson.build     2025-05-30 00:56:43.000000000 
+0200
+++ new/gst-plugins-good-1.26.3/meson.build     2025-06-26 22:25:24.000000000 
+0200
@@ -1,5 +1,5 @@
 project('gst-plugins-good', 'c',
-  version : '1.26.2',
+  version : '1.26.3',
   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.26.2/sys/osxvideo/osxvideosink.m 
new/gst-plugins-good-1.26.3/sys/osxvideo/osxvideosink.m
--- old/gst-plugins-good-1.26.2/sys/osxvideo/osxvideosink.m     2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/sys/osxvideo/osxvideosink.m     2025-06-26 
22:25:24.000000000 +0200
@@ -454,7 +454,6 @@
     GstStructure * structure)
 {
   GstOSXVideoSink *osxvideosink = GST_OSX_VIDEO_SINK (navigation);
-  GstPad *peer;
   GstEvent *event;
   GstVideoRectangle src = { 0, };
   GstVideoRectangle dst = { 0, };
@@ -462,9 +461,7 @@
   NSRect bounds;
   gdouble x, y, xscale = 1.0, yscale = 1.0;
 
-  peer = gst_pad_get_peer (GST_VIDEO_SINK_PAD (osxvideosink));
-
-  if (!peer || !osxvideosink->osxwindow)
+  if (!osxvideosink->osxwindow)
     return;
 
   event = gst_event_new_navigation (structure);
@@ -508,8 +505,14 @@
         (gdouble) y * yscale, NULL);
   }
 
-  gst_pad_send_event (peer, event);
-  gst_object_unref (peer);
+  gst_event_ref (event);
+  if (!gst_pad_push_event (GST_VIDEO_SINK_PAD (osxvideosink), event)) {
+    /* If the event was not handled/used upstream,
+     * we post it as a message on the bus so that applications can handle it */
+    gst_element_post_message (GST_ELEMENT_CAST (osxvideosink),
+        gst_navigation_message_new_event (GST_OBJECT_CAST (osxvideosink), 
event));
+  }
+  gst_event_unref (event);
 }
 
 static void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/sys/v4l2/gstv4l2object.c 
new/gst-plugins-good-1.26.3/sys/v4l2/gstv4l2object.c
--- old/gst-plugins-good-1.26.2/sys/v4l2/gstv4l2object.c        2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/sys/v4l2/gstv4l2object.c        2025-06-26 
22:25:24.000000000 +0200
@@ -2596,19 +2596,66 @@
       else
         colorspace = fmt.fmt.pix.colorspace;
 
-      if (colorspace == req_cspace) {
-        if (gst_v4l2_object_get_colorspace (v4l2object, &fmt, &cinfo))
-          gst_v4l2_object_fill_colorimetry_list (&list, &cinfo);
-        if (colorspace == V4L2_COLORSPACE_REC709) {
-          /* support for full-range variants of colorspaces 
V4L2_COLORSPACE_REC709
-           * (such as Apple's full-range bt709 variant 1:3:5:1) */
-          struct v4l2_format alt_fmt;
-          memcpy (&alt_fmt, &fmt, sizeof (alt_fmt));
-
-          if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type))
-            alt_fmt.fmt.pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
-          else
-            alt_fmt.fmt.pix.quantization = V4L2_QUANTIZATION_FULL_RANGE;
+      if (colorspace != req_cspace)
+        continue;
+
+      if (gst_v4l2_object_get_colorspace (v4l2object, &fmt, &cinfo))
+        gst_v4l2_object_fill_colorimetry_list (&list, &cinfo);
+
+      if (colorspace == V4L2_COLORSPACE_REC709 ||
+          colorspace == V4L2_COLORSPACE_470_SYSTEM_BG) {
+        /* support for full-range variants of colorspaces 
V4L2_COLORSPACE_REC709
+         * (such as Apple's full-range bt709 variant 1:3:5:1) and colorspace
+         * V4L2_COLORSPACE_470_SYSTEM_BG */
+        struct v4l2_format alt_fmt;
+        enum v4l2_quantization quantization;
+        memcpy (&alt_fmt, &fmt, sizeof (alt_fmt));
+
+        if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type))
+          alt_fmt.fmt.pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
+        else
+          alt_fmt.fmt.pix.quantization = V4L2_QUANTIZATION_FULL_RANGE;
+
+        if (gst_v4l2_object_try_fmt (v4l2object, &alt_fmt) == 0) {
+          if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type)) {
+            colorspace = alt_fmt.fmt.pix_mp.colorspace;
+            quantization = alt_fmt.fmt.pix_mp.quantization;
+          } else {
+            colorspace = alt_fmt.fmt.pix.colorspace;
+            quantization = alt_fmt.fmt.pix.quantization;
+          }
+
+          if (colorspace != req_cspace
+              || quantization != V4L2_QUANTIZATION_FULL_RANGE)
+            continue;
+
+          if (gst_v4l2_object_get_colorspace (v4l2object, &alt_fmt, &cinfo))
+            gst_v4l2_object_fill_colorimetry_list (&list, &cinfo);
+        }
+      }
+      if (colorspace == V4L2_COLORSPACE_BT2020) {
+        /* support for colorimetry bt2100-pq, variant of colorspace
+         * V4L2_COLORSPACE_BT2020 */
+        struct v4l2_format alt_fmt;
+        enum v4l2_xfer_func xfer_func;
+        memcpy (&alt_fmt, &fmt, sizeof (alt_fmt));
+
+        if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type))
+          alt_fmt.fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_SMPTE2084;
+        else
+          alt_fmt.fmt.pix.xfer_func = V4L2_XFER_FUNC_SMPTE2084;
+
+        if (gst_v4l2_object_try_fmt (v4l2object, &alt_fmt) == 0) {
+          if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type)) {
+            colorspace = alt_fmt.fmt.pix_mp.colorspace;
+            xfer_func = alt_fmt.fmt.pix_mp.xfer_func;
+          } else {
+            colorspace = alt_fmt.fmt.pix.colorspace;
+            xfer_func = alt_fmt.fmt.pix.xfer_func;
+          }
+
+          if (colorspace != req_cspace || xfer_func != 
V4L2_XFER_FUNC_SMPTE2084)
+            continue;
 
           if (gst_v4l2_object_get_colorspace (v4l2object, &alt_fmt, &cinfo))
             gst_v4l2_object_fill_colorimetry_list (&list, &cinfo);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/sys/v4l2/gstv4l2transform.c 
new/gst-plugins-good-1.26.3/sys/v4l2/gstv4l2transform.c
--- old/gst-plugins-good-1.26.2/sys/v4l2/gstv4l2transform.c     2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/sys/v4l2/gstv4l2transform.c     2025-06-26 
22:25:24.000000000 +0200
@@ -932,6 +932,7 @@
         self->v4l2output->mode == GST_V4L2_IO_DMABUF_IMPORT) {
       if (!gst_v4l2_object_try_import (self->v4l2output, inbuf)) {
         GST_ERROR_OBJECT (self, "cannot import buffers from upstream");
+        gst_object_unref (pool);
         return GST_FLOW_ERROR;
       }
 
@@ -961,8 +962,7 @@
     goto beach;
 
   do {
-    if (pool)
-      g_object_unref (pool);
+    g_object_unref (pool);
     pool = gst_base_transform_get_buffer_pool (trans);
 
     if (!gst_buffer_pool_set_active (pool, TRUE))
@@ -995,8 +995,7 @@
     }
 
 beach:
-  if (pool)
-    g_object_unref (pool);
+  g_object_unref (pool);
   return ret;
 
 activate_failed:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gst-plugins-good-1.26.2/sys/v4l2/gstv4l2videoenc.c 
new/gst-plugins-good-1.26.3/sys/v4l2/gstv4l2videoenc.c
--- old/gst-plugins-good-1.26.2/sys/v4l2/gstv4l2videoenc.c      2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/sys/v4l2/gstv4l2videoenc.c      2025-06-26 
22:25:24.000000000 +0200
@@ -660,8 +660,7 @@
 
   ret = gst_buffer_pool_acquire_buffer (pool, &buffer, NULL);
   if (ret != GST_FLOW_OK) {
-    if (cpool)
-      gst_object_unref (cpool);
+    gst_object_unref (cpool);
     goto beach;
   }
 
@@ -669,8 +668,7 @@
 
   GST_LOG_OBJECT (encoder, "Process output buffer");
   ret = gst_v4l2_buffer_pool_process (cpool, &buffer, NULL);
-  if (cpool)
-    gst_object_unref (cpool);
+  gst_object_unref (cpool);
   if (ret != GST_FLOW_OK)
     goto beach;
 
@@ -789,26 +787,23 @@
                 self->input_state->caps, self->v4l2output->info.vinfo.size, 
min,
                 min)) {
           gst_structure_free (config);
-          if (opool)
-            gst_object_unref (opool);
+          gst_object_unref (opool);
           goto activate_failed;
         }
 
         if (!gst_buffer_pool_set_config (opool, config)) {
-          if (opool)
-            gst_object_unref (opool);
+          gst_object_unref (opool);
           goto activate_failed;
         }
       }
 
       if (!gst_buffer_pool_set_active (opool, TRUE)) {
-        if (opool)
-          gst_object_unref (opool);
+        gst_object_unref (opool);
         goto activate_failed;
       }
     }
-    if (opool)
-      gst_object_unref (opool);
+
+    gst_object_unref (opool);
   }
 
   if (task_state == GST_TASK_STOPPED || task_state == GST_TASK_PAUSED) {
@@ -816,8 +811,7 @@
       GstBufferPool *cpool =
           gst_v4l2_object_get_buffer_pool (self->v4l2capture);
       active = gst_buffer_pool_set_active (cpool, TRUE);
-      if (cpool)
-        gst_object_unref (cpool);
+      gst_object_unref (cpool);
     }
     if (!active) {
       GST_WARNING_OBJECT (self, "Could not activate capture buffer pool.");
@@ -854,8 +848,7 @@
       GstBufferPool *opool = gst_v4l2_object_get_buffer_pool 
(self->v4l2output);
       ret = gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (opool),
           &frame->input_buffer, &frame->system_frame_number);
-      if (opool)
-        gst_object_unref (opool);
+      gst_object_unref (opool);
     }
 
     GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-good-1.26.2/tests/check/elements/aacparse.c 
new/gst-plugins-good-1.26.3/tests/check/elements/aacparse.c
--- old/gst-plugins-good-1.26.2/tests/check/elements/aacparse.c 2025-05-30 
00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/tests/check/elements/aacparse.c 2025-06-26 
22:25:24.000000000 +0200
@@ -28,6 +28,7 @@
 #include "parser.h"
 
 #define SRC_CAPS_CDATA "audio/mpeg, mpegversion=(int)4, framed=(boolean)false, 
codec_data=(buffer)1190"
+#define SRC_CAPS_CDATA_6CH "audio/mpeg, mpegversion=(int)4, 
framed=(boolean)false, 
codec_data=(buffer)118004c841000108800d4c61766336312e31392e31303156e500,"
 #define SRC_CAPS_TMPL  "audio/mpeg, framed=(boolean)false, 
mpegversion=(int){2,4}"
 #define SRC_CAPS_RAW   "audio/mpeg, mpegversion=(int)4, framed=(boolean)true, 
stream-format=(string)raw, rate=(int)48000, channels=(int)2, 
codec_data=(buffer)1190"
 
@@ -289,6 +290,35 @@
 
 GST_END_TEST;
 
+GST_START_TEST (test_parse_handle_codec_data_6ch)
+{
+  GstCaps *caps;
+  GstStructure *s;
+  const gchar *stream_format;
+
+  /* Push random data. It should get through since the parser should be
+   * initialized because it got codec_data in the caps */
+  caps = gst_parser_test_get_output_caps (NULL, 100, SRC_CAPS_CDATA_6CH);
+  fail_unless (caps != NULL);
+
+  /* Check that the negotiated caps are as expected */
+  /* When codec_data is present, parser assumes that data is version 4 */
+  GST_LOG ("aac output caps: %" GST_PTR_FORMAT, caps);
+  s = gst_caps_get_structure (caps, 0);
+  fail_unless (gst_structure_has_name (s, "audio/mpeg"));
+  fail_unless_structure_field_int_equals (s, "mpegversion", 4);
+  fail_unless_structure_field_int_equals (s, "channels", 6);
+  fail_unless_structure_field_int_equals (s, "rate", 48000);
+  fail_unless (gst_structure_has_field (s, "codec_data"));
+  fail_unless (gst_structure_has_field (s, "stream-format"));
+  stream_format = gst_structure_get_string (s, "stream-format");
+  fail_unless (strcmp (stream_format, "raw") == 0);
+
+  gst_caps_unref (caps);
+}
+
+GST_END_TEST;
+
 GST_START_TEST (test_parse_proxy_constraints)
 {
   GstCaps *caps, *resultcaps;
@@ -369,6 +399,7 @@
 
   /* Other tests */
   tcase_add_test (tc_chain, test_parse_handle_codec_data);
+  tcase_add_test (tc_chain, test_parse_handle_codec_data_6ch);
 
   /* caps tests */
   tcase_add_test (tc_chain, test_parse_proxy_constraints);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gst-plugins-good-1.26.2/tests/check/elements/rtpsession.c 
new/gst-plugins-good-1.26.3/tests/check/elements/rtpsession.c
--- old/gst-plugins-good-1.26.2/tests/check/elements/rtpsession.c       
2025-05-30 00:56:43.000000000 +0200
+++ new/gst-plugins-good-1.26.3/tests/check/elements/rtpsession.c       
2025-06-26 22:25:24.000000000 +0200
@@ -4387,6 +4387,211 @@
 
 GST_END_TEST;
 
+GST_START_TEST (test_twcc_reference_time_wrap)
+{
+  SessionHarness *h = session_harness_new ();
+  guint i, j;
+  GstBuffer *buf;
+  GstEvent *event;
+  GValueArray *packets_array;
+
+  /* This fci packet is used as a template for generating fci packets in the
+   * test. In these packets only the reference time is patched, which means we
+   * get a completely unrealistic sequence of packets all claiming to report 
the
+   * status of packets with sequence number 1 and 2. This is fine in this test
+   * since we're only concerned with changes to the reference timestamp and 
want
+   * to get rid of other noise. */
+  guint8 fci[] = {
+    0x00, 0x01,                 /* base sequence number: 1 */
+    0x00, 0x02,                 /* packet status count: 2 */
+    0xcc, 0xcc, 0xcc,           /* reference time (will be replaced in each 
packet sent) */
+    0x00,                       /* feedback packet count: 0 */
+    0x40, 0x02,                 /* run-length with large delta for 2 packets: 
0 1 0 0 0 0 0 0 | 0 0 0 0 0 0 1 0 */
+    /* recv deltas: */
+    0x0f, 0xa0,                 /* large delta: +0:00:01.000000000 */
+    0xe0, 0xc0,                 /* large delta: -0:00:02.000000000 */
+    /* padding */
+    0x00, 0x00
+  };
+
+  guint8 fci_base_times[][3] = {
+    {0x7f, 0xff, 0xfe},         /* 0x7ffffe <=> +149:07:50.784 */
+    /* increase over signed wrap */
+    {0x80, 0x00, 0x03},         /* 0x800003 <=> +149:07:51.104 */
+    /* decrease over signed wrap */
+    {0x7f, 0xff, 0xf7},         /* 0x7ffff7 <=> +149:07:50.336 */
+    /* increase over signed wrap again */
+    {0xff, 0xff, 0xf1},         /* 0xfffff1 <=> +298:15:40.864 */
+    /* increase over unsigned wrap */
+    {0x00, 0x00, 0x05},         /* 0x000005 (+0x1000000) <=> +298:15:42.144 */
+    /* decrease over unsigned wrap */
+    {0xff, 0xff, 0xfe},         /* 0xfffffe <=> +298:15:41.696 */
+    /* increase over unsigned wrap again */
+    {0x55, 0x55, 0x55},         /* 0x555555 (+0x1000000) <=> +397:40:55.744 */
+    /* increase over signed wrap again */
+    {0xaa, 0xaa, 0xaa},         /* 0xaaaaaa (+0x1000000) <=> +497:06:09.664 */
+    /* increase over unsigned wrap again */
+    {0x00, 0x00, 0x42},         /* 0x000042 (+0x1000000) <=> +597:31:27.872 */
+  };
+
+  GstClockTime exp_ts[] = {
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x07ffffeLL * 64 * GST_MSECOND +
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x07ffffeLL * 64 * GST_MSECOND -
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x0800003LL * 64 * GST_MSECOND +
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x0800003LL * 64 * GST_MSECOND -
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x07ffff7LL * 64 * GST_MSECOND +
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x07ffff7LL * 64 * GST_MSECOND -
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x0fffff1LL * 64 * GST_MSECOND +
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x0fffff1LL * 64 * GST_MSECOND -
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x1000005LL * 64 * GST_MSECOND +
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x1000005LL * 64 * GST_MSECOND -
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x0fffffeLL * 64 * GST_MSECOND +
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x0fffffeLL * 64 * GST_MSECOND -
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x1555555LL * 64 * GST_MSECOND +
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x1555555LL * 64 * GST_MSECOND -
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x1aaaaaaLL * 64 * GST_MSECOND +
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x1aaaaaaLL * 64 * GST_MSECOND -
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x2000042LL * 64 * GST_MSECOND +
+        1 * GST_SECOND,
+    TWCC_REF_TIME_INITIAL_OFFSET + 0x2000042LL * 64 * GST_MSECOND -
+        1 * GST_SECOND,
+  };
+
+  for (i = 0; i < sizeof (fci_base_times) / 3; ++i) {
+    /* patch our fci packet with a new reference time */
+    fci[4] = fci_base_times[i][0];
+    fci[5] = fci_base_times[i][1];
+    fci[6] = fci_base_times[i][2];
+    buf = generate_twcc_feedback_rtcp (fci, sizeof (fci));
+    session_harness_recv_rtcp (h, buf);
+  }
+
+  for (i = 0; i < 2; i++)
+    gst_event_unref (gst_harness_pull_upstream_event (h->send_rtp_h));
+
+  for (i = 0; i < sizeof (fci_base_times) / 3; ++i) {
+    event = gst_harness_pull_upstream_event (h->send_rtp_h);
+    packets_array =
+        g_value_get_boxed (gst_structure_get_value (gst_event_get_structure
+            (event), "packets"));
+
+    fail_unless_equals_int (packets_array->n_values, 2);
+
+    /* iterate all values in the array and check that the remote-ts property 
is set to 0 */
+    for (j = 0; j < packets_array->n_values; j++) {
+      const GstStructure *pkt_s =
+          gst_value_get_structure (g_value_array_get_nth (packets_array, j));
+      GstClockTime ts = 1;      /* initialize to non-zero */
+      fail_unless (gst_structure_get_clock_time (pkt_s, "remote-ts", &ts));
+      fail_unless_equals_clocktime (ts, exp_ts[i * 2 + j]);
+    }
+
+    gst_event_unref (event);
+  }
+
+  session_harness_free (h);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_twcc_reference_time_wrap_start_negative)
+{
+  SessionHarness *h = session_harness_new ();
+  guint i, j;
+  GstBuffer *buf;
+  GstEvent *event;
+  GValueArray *packets_array;
+
+  /* This fci packet is used as a template for generating fci packets in the
+   * test. In these packets only the reference time is patched, which means we
+   * get a completely unrealistic sequence of packets all claiming to report 
the
+   * status of packets with sequence number 1 and 2. This is fine in this test
+   * since we're only concerned with changes to the reference timestamp and 
want
+   * to get rid of other noise. */
+  guint8 fci[] = {
+    0x00, 0x01,                 /* base sequence number: 1 */
+    0x00, 0x02,                 /* packet status count: 2 */
+    0xcc, 0xcc, 0xcc,           /* reference time (will be replaced in each 
packet sent) */
+    0x00,                       /* feedback packet count: 0 */
+    0x40, 0x02,                 /* run-length with large delta for 2 packets: 
0 1 0 0 0 0 0 0 | 0 0 0 0 0 0 1 0 */
+    /* recv deltas: */
+    0x0f, 0xa0,                 /* large delta: +0:00:01.000000000 */
+    0xe0, 0xc0,                 /* large delta: -0:00:02.000000000 */
+    /* padding */
+    0x00, 0x00
+  };
+
+  guint8 fci_base_times[][3] = {
+    {0x80, 0x00, 0x03},         /* 0x800003 <=> +149:07:51.104 */
+    /* decrease over signed wrap */
+    {0x7f, 0xff, 0xf7},         /* 0x7ffff7 <=> +149:07:50.336 */
+    /* increase over signed wrap again */
+    {0xff, 0xff, 0xf1},         /* 0xfffff1 <=> +298:15:40.864 */
+  };
+
+  /* note that we should not add TWCC_REF_TIME_INITIAL_OFFSET here because we
+   * subtract from that */
+  GstClockTime exp_ts[] = {
+    0x800003LL * 64 * GST_MSECOND + 1 * GST_SECOND,
+    0x800003LL * 64 * GST_MSECOND - 1 * GST_SECOND,
+    0x7ffff7LL * 64 * GST_MSECOND + 1 * GST_SECOND,
+    0x7ffff7LL * 64 * GST_MSECOND - 1 * GST_SECOND,
+    0xfffff1LL * 64 * GST_MSECOND + 1 * GST_SECOND,
+    0xfffff1LL * 64 * GST_MSECOND - 1 * GST_SECOND,
+  };
+
+  for (i = 0; i < sizeof (fci_base_times) / 3; ++i) {
+    /* patch our fci packet with a new reference time */
+    fci[4] = fci_base_times[i][0];
+    fci[5] = fci_base_times[i][1];
+    fci[6] = fci_base_times[i][2];
+    buf = generate_twcc_feedback_rtcp (fci, sizeof (fci));
+    session_harness_recv_rtcp (h, buf);
+  }
+
+  for (i = 0; i < 2; i++)
+    gst_event_unref (gst_harness_pull_upstream_event (h->send_rtp_h));
+
+  for (i = 0; i < sizeof (fci_base_times) / 3; ++i) {
+    event = gst_harness_pull_upstream_event (h->send_rtp_h);
+    packets_array =
+        g_value_get_boxed (gst_structure_get_value (gst_event_get_structure
+            (event), "packets"));
+
+    fail_unless_equals_int (packets_array->n_values, 2);
+
+    /* iterate all values in the array and check that the remote-ts property 
is set to 0 */
+    for (j = 0; j < packets_array->n_values; j++) {
+      const GstStructure *pkt_s =
+          gst_value_get_structure (g_value_array_get_nth (packets_array, j));
+      GstClockTime ts = 1;      /* initialize to non-zero */
+      fail_unless (gst_structure_get_clock_time (pkt_s, "remote-ts", &ts));
+      fail_unless_equals_clocktime (ts, exp_ts[i * 2 + j]);
+    }
+
+    gst_event_unref (event);
+  }
+
+  session_harness_free (h);
+}
+
+GST_END_TEST;
 
 static Suite *
 rtpsession_suite (void)
@@ -4467,6 +4672,8 @@
       G_N_ELEMENTS (test_twcc_feedback_interval_ctx));
   tcase_add_test (tc_chain, test_twcc_feedback_count_wrap);
   tcase_add_test (tc_chain, test_twcc_feedback_old_seqnum);
+  tcase_add_test (tc_chain, test_twcc_reference_time_wrap);
+  tcase_add_test (tc_chain, test_twcc_reference_time_wrap_start_negative);
 
   return s;
 }

++++++ gst-plugins-good.obsinfo ++++++
--- /var/tmp/diff_new_pack.hMJPNa/_old  2025-07-03 12:12:01.757602245 +0200
+++ /var/tmp/diff_new_pack.hMJPNa/_new  2025-07-03 12:12:01.761602410 +0200
@@ -1,5 +1,5 @@
 name: gst-plugins-good
-version: 1.26.2
-mtime: 1748559403
-commit: 100c21e1faf68efe7f3830b6e9f856760697ab48
+version: 1.26.3
+mtime: 1750969524
+commit: 87bc0c6e949e3dcc440658f78ef52aa8088cb62f
 

Reply via email to