Commit graph

15452 commits

Author SHA1 Message Date
Stefan Klug
7f17b50ae6 Merge branch 'sklug/upstream/fix-stream-synchronization-v1' into 'master'
RFC: Improve/fix timestamping issues with gstpipewiresrc

See merge request pipewire/pipewire!2786
2026-05-22 17:45:57 +00:00
Wim Taymans
4e1257a6e6 seq: the training 0xf0 in continuations is optional
This is not strictly required because our control events have a size and
don't need the 0xf0 trailing byte to find the boundary.

It also makes it easier to just use the midifile events directly without
having to add the 0xf0.
2026-05-21 17:51:51 +02:00
Wim Taymans
fdb08f3c60 pw-cat: send midi as-is by default
Don't try to convert midi and ump by default.
2026-05-21 17:13:42 +02:00
Wim Taymans
2ee3d3e16b midifile: correctly write sysex chunks
In midifile we can write sysex continuation chunks starting with
0xf7 but we should not write the trailing 0xf0 byte, if any.
2026-05-21 16:47:22 +02:00
Wim Taymans
981613075f tools: pass maxsize to the fill function
Pass the max size of the buffer to the fill function.

Use this for writing midi events in the buffer. We can use the total
buffer size for midi events.

The n_frames is to limit the amount of midi events *in time*, not in
bytes.
2026-05-21 16:44:29 +02:00
Wim Taymans
a3bea5d586 impl-port: warn when loading a mixer fails 2026-05-21 16:43:38 +02:00
Wim Taymans
0fcaf1ccb2 conf: set the default mixer path correctly 2026-05-21 16:41:37 +02:00
Wim Taymans
7614a2a5d6 midifile: fix header writes on close
When writing a midifile, update the pos with each write so that the seek
back to 0 when updating the headers actually does something.
2026-05-21 14:04:19 +02:00
Wim Taymans
26a2467e7b alsa-seq: handle SysEx without snd_midi_event_t
When writing sysex, bypass the encoder and simply place the sysex
message in the seq queue. Make sure strip off the 0xf7 and 0xf0
continuation bytes.

When reading sysex, bypass the decoder and append/prepend the
continuation bytes.

This way, we can make the decoder buffer size back to something small
(large enough for one simple midi event) and we can handle arbitrary
sysex message lengths.
2026-05-21 12:45:43 +02:00
Wim Taymans
87a2ae2f15 pw-cat: split SysEx over multiple packets
Use the same method as RTP Midi to split long SysEx messages into chunks
that we can then put into buffers and reassemble again later.
2026-05-21 12:11:59 +02:00
Wim Taymans
4e389940e8 midifile: correctly write SysEx events
We need to place the sysex length in the message as well.
2026-05-21 12:11:59 +02:00
Arun Raghavan
f2de48f1e7 spa: aec: Expose more AGC modes as configuration 2026-05-20 17:57:19 +00:00
Arun Raghavan
9808a4baa0 spa: aec: webrtc: Allow enabling AGC1 and AGC2 independently 2026-05-20 17:57:19 +00:00
Arun Raghavan
3e5f072e11 spa: aec: webrtc: Actually enable adaptive analog control in AGC2
Without this, we only get a fixed 0dB gain + compressor.
2026-05-20 17:57:19 +00:00
Wim Taymans
e36d724d04 alsa-seq: increase MAX_EVENT_SIZE to 1024
This is also what a2jmidid has, so let's do the same.

See #5254
2026-05-20 13:25:20 +02:00
Wim Taymans
6e6fb1207d filter-graph: sync_volume initializes the control ports
Setting the volume control ports with a volume param also initializes
the controls. This ensures the controls are not restored to their
default value when the graph is activated.

Fixes #5192
2026-05-20 11:32:39 +02:00
Wim Taymans
753ce79c18 rtp: fix compilation 2026-05-20 09:09:38 +02:00
Wim Taymans
d56d5fa87a raop: implement retransmission
Keep the last relation between the sequence number and the timestamp
(ringbuffer position).

When a retransmission is requested for a given sequence number use the
relation to calculate the corresponding timestamp and retransmit the
packet from the ringbuffer again.

See #5276
2026-05-19 17:40:07 +02:00
Wim Taymans
a6fe6196d5 modules: remove redundant close
The close in the error path will never be called because the fd has been
stolen and will be -1.

Also make sure that when we free the source that we set it to NULL or
else the destroy function will try to free it again.
2026-05-18 16:58:20 +02:00
Stefan Klug
aa8f6a2147 gst: gstpipewireclock: Add error message to detect time drift
Sometime cases were observed, where the time returned from
pw_stream_get_time_n() had incorrect values.

The root cause was not fully tracked down. Roughly the case was as
follows: A gstreamer pipeline with two gstpipewiresrc elements. One
audio and one libcamera besed video src, both fed into a mp4 encoding
mux. The cock was provided by the audio gstpipewiresrc. Now between
starting the pipewire video stream and receiving the first camera frame
pw_stream_get_time_n() returned strange values (It seemed like it was
using the audio rate for something internally). This wrong value was
used to initialze pclock->start_time and therefore all following calls
to gst_pipewire_clock_get_internal_time() returned completely wrong
values.

Add a warning to hopefully catch these cases. I don't have a proper use
case to test the clock interpolation done in
gst_pipewire_clock_get_internal_time() so I can't drop that (which would
remove the bogus call to pw_stream_get_time_n() alltogether), although
it feels like the right thing to do.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
2026-05-18 09:48:10 +02:00
Stefan Klug
c8f81fcdbb spa: plugins: libcamera: Drop rate dependent calculations
The clock has SPA_IO_CLOCK_FLAG_NO_RATE set unconditionally and the rate is usally
0/0. So all the rate calculations produce NaN and are not necessary.
Drop them.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
2026-05-18 09:48:10 +02:00
Stefan Klug
e2f2b9a273 gst: gstpipewireclock: Return a valid clock before stream start
When a gstreamer pipeline transits to playing state, it sets the
base_time of all elements to the internal time of the current clock. At
that point, the pipewire stream has not yet started and the
gstpipewireclock returns last_time which is initialized to 0 in
gstpipewirestream. This leads to a incorrect base_time in the gstreamer
element and various synchronization issues.

The use-case for last_time is not really clear to me. My basic guesswork
is: If a stream is no longer streaming the internal clock should pause
at that time and return last_time. So this patch keeps this behaviour
in place and only ensures that a valid time is returned when the stream
is not yet started and last_time is not in the future.

To keep the time scaling logic in place, a start time is recorded when
the stream was started, to properly match stream time and clock
monotonic.

A gstreamer pipeline that can be used to replicate the issue is:
GST_DEBUG="pipeline:5,GST_CLOCK:6,pipewiresrc:6" gst-launch-1.0 \
pipewiresrc name=video target-object=<some video target> ! \
video/x-raw,format=UYVY !  fakesink \
pipewiresrc name=audio target-object=<some audio target> ! \
audio/x-raw ! f akesink 2>&1 | \
grep PTS

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>

---

Changes in v2:
- Drop incorrect logic in case s == NULL
- Keep clock scaling in place
2026-05-18 09:48:10 +02:00
Stefan Klug
9e52e7ee7f gst/pipewiresrc: Improve base_time handling
It can not generically assumed that the gstreamer clock (and therefore
the base_time) is based on CLOCK_MONOTONIC.

It was tried to use the logic provided by
GstBaseSrc::gst_base_src_do_sync() in commit 004206db37
("gst/pipewiresrc: Let GstBaseSrc handle pseudo-live calculations").
This has the downside, that a potential jitter on the first buffer is
included in the calculated time offset. In gstreamer pipelines with
multiple pipewiresrc elements and big jitter on the first buffer the
streams will stay out of sync.

Improve that by checking if the gstreamer clock is provided by pipewire
and therefore known to be CLOCK_MONOTONIC or if it is provided by
gstreamer and we need to manually calculate the base_time.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
2026-05-18 09:48:10 +02:00
Stefan Klug
6ac9677b35 Revert "gst/pipewiresrc: Let GstBaseSrc handle pseudo-live calculations"
This reverts commit 004206db37.
2026-05-18 09:48:10 +02:00
Stefan Klug
c64cedb372 Revert "pipewiresrc: Use clock time difference to update last_buffer time"
This reverts commit efd1526423.
2026-05-18 09:48:10 +02:00
Wim Taymans
250260e18e modules: avoid double close when loop_add_io fails 2026-05-15 13:38:32 +02:00
Wim Taymans
894e97aaa5 modules: avoid double fd close
Now that loop_add_io, avoid double free on failures. Try to use
spa_autoclose and spa_steal_fd to make the error paths easier.
2026-05-15 13:34:48 +02:00
Wim Taymans
a9f62579ba support: make sure loop_add_io is closes the fd when asked
When the close argument is true, loop_add_io is supposed to close the fd
even when an error occurs.

This makes it possible to have spa_steal_fd() work even in the case
of errors.
2026-05-15 13:21:55 +02:00
Wim Taymans
398f74571b module: check packet size for CK messages
Check that the CK packet is large enough before we start reading its
contents.
2026-05-15 10:45:14 +02:00
Wim Taymans
f3fc645496 connection: return error if too many fds in message
Check that the number of fds in the message doesn't exceed our max or
else we might overflow the fd buffer a little later.
2026-05-14 16:32:58 +02:00
Wim Taymans
79b4aba6cc pulse: also handle potential overflow in ROUND_UP 2026-05-14 16:27:20 +02:00
Wim Taymans
af151b088d pw-dump: also dump client permissions 2026-05-14 15:05:08 +02:00
Wim Taymans
98fdedf348 filter-graph: relax LADSPA plugin loading
Make a new library.filter-path for the filter-graph that will filter and
restrict the dlopen filenames (used for the LADSPA plugin only).

By default this is false and so filter-chain can load from absolute
paths without extra checks.

Enable the extra checks for the pulse LADSPA modules and the
audioconvert filter graphs because these allow loading LADSPA plugins
into other processes.

Fixes #5222
2026-05-14 13:23:19 +02:00
Wim Taymans
61431dcbc0 audioconvert: add dither noise even on empty input
When we are asked to add noise bits, don't call the clear function.

Make the passthrough and clear-on-empty flags available with a new flag
field to make it more extensible.

Fixes #5260
2026-05-14 11:19:02 +02:00
Wim Taymans
4f975d0071 treewide: add error checking to spa_json_builder_close
There could have been a write error or allocation error while building
the json file that we can detect in spa_json_builder_close().

Error out instead of silently using a truncated JSON.

Use spa_autofree for the memory to make cleanup easier.
2026-05-13 18:14:44 +02:00
Wim Taymans
6d1c242433 pulse-server: implement more valid_args on modules
If the valid_args is NULL, reject all arguments.
2026-05-13 16:53:40 +02:00
Wim Taymans
5fa87d67a1 protocol-native: unref resource after logging the error 2026-05-13 11:12:17 +02:00
Wim Taymans
b53ec3bceb impl-metadata: check PW_PERM_M permission on subject
To set a metadata on a subject, the subject must be visible (R) and we
must have the M permission on the subject.
2026-05-13 11:08:37 +02:00
Wim Taymans
a74109eef3 settings: clamp the clock rate to avoid 0 division
Setting the rate to 0 could in some cases result in a division by zero,
avoid that by clamping to a min value.
2026-05-13 10:47:52 +02:00
Wim Taymans
e5ff44910e pulse-server: improve module argument checking
Make the module valid_args a structure that includes the argument key,
description and some flags. Use this to enforce mandatory properties
in a more central place.

We should be able to generate the module usage from this as wel later to
have things a bit more structured.
2026-05-13 10:23:47 +02:00
Pauli Virtanen
a5a3eaf2cb ci: bump bluez version to fix failing bluez_tests
Bump bluez to current master to fix bluez_tests failures.
Also bump pytest-bluezenv version to current.
2026-05-12 23:56:27 +03:00
Jonas Holmberg
a7994882b9 channelmix: Convert matrices to float arrays
Convert matrix_orig and matrix to float arrays and use variable size 2d
arrays to access the elements of the matrices. This removes the need for
storing pointers to matrix rows.
2026-05-12 14:47:57 +02:00
Wim Taymans
7cfcb46fbf tests: do channelmix_free after channelmix_init 2026-05-12 13:10:21 +02:00
Wim Taymans
b54bac1862 modules: make and use pw_net_is_multicast 2026-05-12 13:02:21 +02:00
Wim Taymans
6d998a9193 modules: use pw_net_get_ip
Make pw_net_get_ip also accept NULL ip to just get the port and ip
version. Make rtsp-client use pw_net_get_ip.

Make sure we initialize the iovec before logging in all cases.
2026-05-12 12:52:03 +02:00
Wim Taymans
8860dc809d pulse-server: use pw_net_get_ip instead of inet_ntop 2026-05-12 12:14:52 +02:00
Wim Taymans
62846acb3f modules: use pw_net_get_ip 2026-05-12 09:29:19 +02:00
Niklas Carlsson
d02ebb01e1 filter-graph: expand built-in plugins min/max
No need to limit certain parameters to e.g. [-10, 10]. Some use
cases might want to use values outside of the current, somewhat,
restrictive limits.
2026-05-12 07:20:23 +00:00
Wim Taymans
0c193b2b82 modules: invert memcmp logic
memcmp returns 0 when the memory is equal. This function is not used
currently.
2026-05-12 09:18:56 +02:00
Wim Taymans
9843ee858f modules: use sockaddr_storage for socket address
sockaddr_in only works for ipv4, for ipv6, the address will be truncated
and then cause a stack overread in inet_ntop.
2026-05-12 09:15:46 +02:00