Commit graph

14759 commits

Author SHA1 Message Date
Wim Taymans
5cc63c1b34 audiomixer: only add the input port to mix_list
Adding the output port is not a problem because there is never a buffer
to consume and mix but it wastes cycles.
2026-03-11 12:36:39 +01:00
Wim Taymans
5f4b422ab1 loop: improve cancellation handling
Now that the loop_leave function will assert when the unlock fails we
need to be extra careful with the cancellable loop. If it cancels inside
the poll or one of the before/after callbacks we need to make sure that
we lock the loop correctly again or we will create an assert later on.

Do this by pushing the cleanup earlier and then record all the things we
managed to do before we get canceled. If we ever get canceled and the
lock was unlocked but not locked again, fix this up.

Fix fixes issues when using the JACK API causing assertions when the
data loop is stopped/cancelled.
2026-03-10 16:46:29 +01:00
Wim Taymans
7ecd51dc80 client-node: avoid using invalid fd or mem in clear_data
Don't close an -1 fd in clear_data.

If we let the client allocate buffer, set our fd and data to invalid
values. If the client decides to renegotiate before we get the buffer
data we might otherwise try to clear the mem_id (default 0) or
close the fd (also default 0).

Fixes #5162
2026-03-10 14:25:07 +01:00
Wim Taymans
6a3ac7f7b0 examples: support REQUEST like video-src 2026-03-10 12:30:03 +01:00
Wim Taymans
8f22785cf0 json-core: use table to classify chars for number check 2026-03-10 12:30:03 +01:00
Barnabás Pőcze
5c67ab2a7a pipewire: mem: log if close() fails
If a file descriptor is expected to be closed by the associated `pw_memblock`,
and closing fails, then that usually signals a more serious issue in the memory
accounting. So add a log message when that happens.
2026-03-10 12:27:44 +01:00
Barnabás Pőcze
d33066cdd7 pipewire: module-client-node: use pw_log_*()
Use the `pw_log_*()` macros instead of the `spa_log_*()` ones since
this is a pipewire module, and otherwise not the expected log topic
would be used.
2026-03-10 12:09:36 +01:00
Barnabás Pőcze
810617997b spa: libcamera: source: SPA_PARAM_Props is write-only
There are no readable `SPA_PARAM_Props` on the node, so mark it write-only.
2026-03-09 21:19:38 +00:00
Barnabás Pőcze
a661f14d2c spa: support: loop: check enter_count before iterating
Calling "iterate()" on a loop that has not been entered by the
calling thread is invalid. So try to diagnose misbehaving applications
on a "best effort" basis by checking `impl::enter_count`.

This is not a foolproof check, and can also technically cause data
races while reading the variable.

See #5148
2026-03-09 22:08:23 +01:00
Barnabás Pőcze
dc1738ce57 spa: support: loop: more mutex lock checks
Check the return values of `pthread_mutex_{,un}lock()` in more places
to diagnose misbehaving applications.

See #5148
2026-03-09 22:08:22 +01:00
Barnabás Pőcze
abf37dbdde pipewire: module-client-node: use pw_param_info_find() to check validity
Previously when parameters were enumarated, it was checked if at least one
param was known for `id`. If not, `-ENOENT` was returned to signal that
this param id is not supported.

This is not necessarily true, since a param id might be supported, but it
might have zero params at the moment, in which case an unexpected error
would be returned.

Fix that by using `pw_param_info_find()` with the underlying impl object
to check if the param id is actually supported.
2026-03-09 21:34:19 +01:00
Barnabás Pőcze
5e37d43881 pipewire: impl-{node,port}: do not cache failed param enumerations
If the param enumeration fails, do not set `spa_param_info::user` to 1
indicating that the result is cached. Doing so can lead to the first
(uncached) call failing, while the rest will succeed (with 0 params).
2026-03-09 20:04:22 +00:00
Pauli Virtanen
22a5fad902 bluez5: cleanup get_codec_profile()
Check codec kinds for each direction properly when mapping to profiles
corresponding to it. Being sloppy here masked another bug, so best fix
it.
2026-03-09 21:35:22 +02:00
Pauli Virtanen
75c3d3ecf8 bluez5: fix spa_bt_device_supports_media_codec() for HFP codecs
HFP codecs don't have a direction dependent "target" profile, and this
function was returning false if A2DP is disabled.

Don't check target profile for HFP, leave checks to backend.

Fixes HFP-only configurations, which were missing profiles.
2026-03-09 21:33:28 +02:00
Wim Taymans
2548fcad25 spa: update lib.c 2026-03-09 18:33:32 +01:00
Wim Taymans
f6939a1cf0 json: Use state machine and fix 1E10 parsing
Use a state machine to check for valid numbers and fix the 1E10
parsing case.

With help from Claude.
2026-03-09 18:17:04 +01:00
Jonas Ådahl
c745582ef5 pipewire/capabilities: Remove left-over macro defiition
This was used for a previous iteration, that used tags, and was replaced
with PW_CAPABILITY_DEVICE_ID_NEGOTIATION.
2026-03-09 15:54:08 +00:00
Jonas Ådahl
f7bb4c95ed pipewire/capabilities: Update device ID negotation according to API docs
It was was documenting a previous iteration of the protocol which used a
boolean and a base64 encoded list.
2026-03-09 15:54:08 +00:00
Jonas Ådahl
99079dd955 docs/dma-buf: Document the correct device ID negotation key
The correct key is PW_CAPABILITY_DEVICE_ID_NEGOTIATION which contains a
number.
2026-03-09 15:54:08 +00:00
Pauli Virtanen
d42646e91f bluez5: sbc: clean up codec_enum_config
Non-spec compliant devices may set multiple bits in code config, which
we currently reject in validate_config().

enum_config() does work to deal with multiple bits set, but this is
never used, so write the code in a simpler way to return a single
configuration.
2026-03-09 15:53:35 +00:00
Pauli Virtanen
67b4732c26 bluez5: aac: for multiple bits in aot, normalize to mandatory
Non-spec compliant devices may set multiple bits in AAC AOT, which is
invalid.

In this case, we should normalize to MPEG-2 AAC LC which is the
mandatory value in spec, not to MPEG-4 AAC LC. In select_config() we
also prefer MPEG-2 over MPEG-4.
2026-03-09 15:53:35 +00:00
Pauli Virtanen
5f8ece7017 bluez5: aac: coerce non-spec compliant freq/channels to single choice
Some non-spec compliant devices (Sony XB100) set multiple bits
in all AAC field, including the frequency & channels.

Although they set multiple bits, these devices appear to intend that the
sender picks some specific format and uses it, and don't work correctly
with the others.

validate_config() already picks one configuration, so use the result in
enum_config(), instead of allowing also other settings.

Assume devices generally want preferably 44.1 kHz stereo.

Note we cannot reject the configuration, as BlueZ does not necessarily
retry, leaving the device connected but with no audio.
2026-03-09 15:53:35 +00:00
Pauli Virtanen
f9e2b1d8b9 bluez5: backend-native: don't crash without dbus session bus
When there is no DBus session bus, creation of the telephony backend
fails, and we later crash on null ptr deref.

In this case, avoid crash trying to create telephony_ag or iterate its
call list.
2026-03-09 15:52:05 +00:00
Wim Taymans
ddf63e0863 json: relax float parsing some more
We already support more float variants than standard JSON in the relaxed
format, adding extra restrictions does not actually help much. If you
need to know if this is a value JSON number, there is now a function to
check that instead.
2026-03-09 16:48:05 +01:00
Wim Taymans
231a41a22f impl-link: fix shared mem test
We can only use non-shared memory when both nodes live in the same
process _and_ we can be sure the output port is never going to be linked
to a remote node because it is exclusive.

This fixes the case where a null-sink is loaded inside the process space
of the server and linked to the ALSA sink. This would create a link
without shared mem and then as soon as something else (out of process)
wants to link to the null-sink output, it would get a -22 EINVAL
negotiation error because the memory can't be shared.

Fixes #5159
2026-03-09 16:18:58 +01:00
Wim Taymans
6f73e42d05 v4l2: use 0x as the prefix for hex values
fixes #5161
2026-03-09 13:50:38 +01:00
Wim Taymans
3a2d16a3bc json-builder: do better json number check
If we are going to produce valid JSON we need to do a better JSON number
check because our own float and int parser can accept more variants
and will let through numbers that are not valid JSON.

See #5161
2026-03-09 13:33:20 +01:00
Wim Taymans
48c22e2aa7 pw-dump: place key before None choice values
See #5161
2026-03-09 13:19:43 +01:00
qaqland
d1c372f5ee alsa-udev: support alsa.ignore-dB
Some sound cards are only adapted for Android/macOS and other
systems, without considering Linux. The hardware-reported dB
volume is incorrect (while the percentage volume is normal).
Add support for the ignore-dB option to simplify compatibility.

For example, the 3206:0798 HP SIMGOT GEW1 Sound Card reports:

numid=4,iface=MIXER,name='PCM Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=100,step=0
  : values=100,100
  | dBminmax-min=0.00dB,max=0.39dB

This dB value does not match actual audio perception, and the
vendor attributed this issue to non-target system compatibility.
2026-03-07 13:53:38 +08:00
Wim Taymans
70b7b42f5d pw-cat: fix encoded format playback
We keep a mapping between the sndfile formats and the format we would
like to decode them to for encoded formats. Make sure we don't mix up
the sample widths between them.

Make sure we don't send encoded formats as raw.

Debug the uncompressed format name correctly.

Fixes #5155
2026-03-06 17:03:20 +01:00
Wim Taymans
a179e8c695 sendspin: implement parsing of client state 2026-03-06 11:24:21 +01:00
Wim Taymans
784ad934a4 impl-node: remove the can_suspend boolean
Sink and Sources can now be implemented as the follow passive mode,
they won't activate anything themselves but follow the state of the
peer.
2026-03-06 10:42:00 +01:00
Wim Taymans
118d8574c8 impl-port: support mode port.passive values
Add a port.passive = follow mode and the node.passive equivalents
out-follow, in-follow, follow.

This makes it possible to control how a port influences the state of
the peer and how the peer influences the state of the node independently.

In passive mode, the port will not make the peer runnable and will also
not become runnable when the peer activates.

In the follow mode, the port will not make the peer runnable but it will
become runnable when the peer is active.

This makes it possible to do new things like (f for follow):

  Source -> (f)loopback1-in|loopback1-out(f) -> Sink

It will not make the source and sink run but when one of them start, all
will become runnable.

Or you can now better do the leak node hack that was previously used:

  Source -> (f)pw-record

That will only start running when the source is activated by something
else.

With port.passive = true|false|follow there is a potential 4th case
which would activate the peer but not be activated by the peer, which is
not something that makes sense.
2026-03-06 09:35:17 +01:00
Wim Taymans
437a8d32f2 impl-node: remove the leaf node check
This was a hack around some scheduler issues that we should be able to
handle better now.

One of the cases is:

  Source -> (p)pw-record

Which would never work otherwise because pw-record does not activate the
Source and when the Source is activated in any other way, pw-record
would not follow.

This will still fail with the current scheduler, but the leaf check is
not so great because it doesn't work in this case:

  Source -> (p)loopback-in|loopback-out(p) -> Sink

What is probably required is a passive mode that doesn't activate but
does follows the peer.
2026-03-05 15:03:30 +01:00
Wim Taymans
106b4a37d4 node: remove node.link-group from drivers
Sink/Source pairs should not have the same link-group otherwise the
session manager will not be able to autoconnect them with a loopback or
some other internally linked stream.
2026-03-05 14:32:41 +01:00
Wim Taymans
e6a5951a47 gst: fix compilation on older GStreamer
These functions are since 1.28, which is a little too new.
2026-03-04 17:55:53 +01:00
Robert Mader
efd1526423 pipewiresrc: Use clock time difference to update last_buffer time
Setting the current clock time when resending buffers is often wrong.
Especially for pseudo-live sources - the default mode - it discards
the original buffer time, which again is used by the base-class to
adjust the timestamps further, ultimately resulting in very wrong
timestamps.

Instead, try to calculate the delta between when we originally got the
buffer and now.
2026-03-03 22:52:52 +01:00
Robert Mader
49300d8ee0 pipewiresrc: Take a copy instead of a reference for last_buffer
Buffer timestamps get adjusted by the base class, GstBaseSrc, even if we
take an additional ref. Arguably the base class should check if buffers
are writable (gst_buffer_make_writable()), which would trigger a buffer
copy. That is currently not the case, though, thus do so on our side.

Notes:
1. Usually a buffer copy doesn't copy the underlying memory, i.e.
copying is cheap.
2. The copy holds a reference to the copied buffer, preventing the
buffer from getting recycled as before.
2026-03-03 22:51:04 +01:00
Wim Taymans
a3853c2c3d scheduler: activate links also in make_runnable
Also make sure we unset the preparing flag when the port state
changes.
2026-03-03 11:56:35 +01:00
Elliot Chen
95e89f786a pipewiresrc: update per-plane stride and offset according to chunk info 2026-03-03 09:16:51 +00:00
qaqland
182f52603c meson.build: bump sndfile version to 1.1.0
This commit follows 35817c0d85

Bump required sndfile version to 1.1.0 for SF_FORMAT_MPEG_LAYER
and other formats added in commit 35817c0d8c.
2026-03-03 09:14:25 +00:00
Wim Taymans
ea21281f38 scheduler: skip checking runnable from suspendable nodes
We used to skip the runnable state from driver nodes because we assume
that they will be activated from other nodes. We however need to make
this more general to all suspendable nodes.

This makes pw-play -> loopback1-sink loopback1-out -> loopback2-sink
loopback-out -> sink also work correctly because the loopback2-sink does
not activate loopback1-out then.
2026-03-02 17:22:05 +01:00
Wim Taymans
797cdbc72f impl-link: link.passive is no longer used 2026-03-02 17:19:41 +01:00
Wim Taymans
b8e27cc02b modules: IO_HUP also has an error 2026-03-02 12:22:30 +01:00
Wim Taymans
6e2522b657 modules: improve error reporting
Instead of reporting -EPIPE, get the error from the socket and report
that instead.
2026-03-02 12:13:22 +01:00
Wim Taymans
87087a4629 jack: never return NULL from jack_port_by_id()
JACK will never return NULL from jack_port_by_id() because the id
and the port_t are the same for JACK.

In PipeWire however we use the serial number as the id and so it can
be removed and become invalid. In this case, return a dummy port
from the client that can be used for some of the basic operations
you can do on a port_t, like get the name etc.

Also make sure that port_name() doesn't return NULL in case we use the
dummy port (which has the client set to NULL).

Fixes #3512
2026-03-02 11:41:21 +01:00
Jonas Holmberg
f4e174870e module-protocol-native: Fix socket activation
Fix path comparison in is_socket_unix() and don't unset LISTEN_FDS since
the function that uses it is called more than once and it was not unset
when sd_listen_fds() was used.

Fixes #5140
2026-03-02 10:28:26 +01:00
Wim Taymans
d206b06c70 sendspin: cleanup receive sync and logging
don't check the same thing twice.

Make sure values are set before we log them.
2026-03-01 12:49:24 +01:00
Wim Taymans
06f336a581 json-builder: handle allocation failures in vasprintf 2026-03-01 12:40:34 +01:00
thewrz
8ceb671cc8 module-vban: derive write position from frame counter
Instead of writing packets sequentially and losing sync on any
frame gap, compute the write position from the VBAN header's
n_frames field. Out-of-order packets land at the correct
ringbuffer offset, matching how module-rtp handles this.

Only advance the writeindex when a packet extends the frontier
so that late arrivals fill gaps without moving the pointer
backwards.

Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/5145
2026-02-27 22:48:12 -08:00