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 <[email protected]>
+
+- 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