Commit graph

15654 commits

Author SHA1 Message Date
zuozhiwei
9bfea81847 bluez5: destroy update_delay_event and fd on media-source transport_start failure
Symmetric follow-up to 47a3479490 which fixed
the same leak in media-sink. media-source transport_start() registers
update_delay_event and dups the transport fd before ensuring SCO I/O; on
HFP failure the fail path only deinited codec_data, leaking the event
source and fd. Early allocation failures also returned without cleanup.

Mirror media-sink: destroy update_delay_event, close the dup'd fd, clear
the decode buffer, and route early errors through the same fail path.
2026-07-10 10:46:37 +00:00
zuozhiwei
a2c09923ff bluez5: complete Opus 05 companion caps like AAC ELD
After a6f529b5, opus_05_51/71 only set endpoint_companion. The owner
fill_caps still advertised up to MAX_CHANNELS, there was no combine_caps,
and validate_config was not id-gated. Disabled surround companions remained
visible in endpoint caps, and SetConfiguration could bind a 5.1/7.1 config
to the stereo opus_05 object (wrong bitrate limits / channel profile).

Mirror a2dp-codec-aac.c:
- split fill_caps per codec id (2ch / 5.1 / 7.1; duplex 2+2; pro wide)
- add combine_caps on endpoint owners
- id-gate validate_config so the config-aware resolver picks the companion
- give companions their own fill_caps for the monitor merge path
2026-07-10 17:29:42 +08:00
John-John Tedro
73c0c51af6 jack: prevent data for removed objects from leaking
This is done by unsetting the link to jack internal objects to their
corresponding object.id, which is otherwise used when reacting to
registry events. Without this, serials would "leak" when multiple jack
objects have the same object id during lookup - the first serial would
be picked as jack_port_id even if it's removed and would reference its
node data instead of the new port.

Unsetting object.id also means we need to refactor internals to lookup
by serial instead of id.

See #5356 for more
2026-07-09 17:02:01 +00:00
George Kiagiadakis
a6f529b508 bluez5: fix shared A2DP endpoint caps including disabled companion codecs
Codecs that share an A2DP endpoint (e.g. aac + aac_eld) previously used
an asymmetric pattern: one codec (the "owner") had fill_caps and quietly
advertised the union of all siblings' capability bits; companions had
fill_caps = NULL.

This caused a bug: when aac_eld is absent from bluez5.codecs, the "aac"
endpoint still advertised the ELD object-type bit because a2dp_codec_aac's
fill_caps emitted it unconditionally (gated only by eld_supported(), never
by enabled_codecs). A remote could then select ELD; SetConfiguration
resolved the transport to a2dp_codec_aac (the only fill_caps holder for "aac")

Refactor to a symmetric, composable model:

- Add bool endpoint_companion to struct media_codec (default false = owner).
  Companion codec objects set this flag instead of fill_caps = NULL.
- Add combine_caps() function to struct media_codec. Owners that share
  an endpoint implement this to union two capability blobs of the same
  codec_id.
- Each codec's fill_caps now describes only its own bits. AAC LC advertises
  only LC object types; AAC ELD advertises only the ELD type (or returns
  -ENOTSUP when FDK-AAC lacks ELD support).
- Bump SPA_VERSION_BLUEZ5_CODEC_MEDIA 16 -> 17.

On the monitor side (bluez5-dbus.c):
- New media_codec_fill_endpoint_caps() helper fills the owner's caps then
  walks enabled companions on the same endpoint and merges each via
  combine_caps. All five endpoint-registration fill_caps call sites are
  routed through this helper.
- endpoint_should_be_registered() gates on !endpoint_companion (not on
  fill_caps != NULL), so companions correctly skip endpoint registration.
- media_endpoint_to_codec() now filters by is_media_codec_enabled and
  prefers owners as a tiebreaker.
- New media_endpoint_to_codec_for_config() resolves SetConfiguration by
  calling each enabled candidate's validate_config against the negotiated
  config bytes. This ensures that an "aac" endpoint carrying ELD bytes is
  mapped to a2dp_codec_aac_eld (not a2dp_codec_aac).
- AAC validate_config and codec_init are id-gated so a stale ELD config
  can never be decoded by the LC codec object.

Assisted-by: Claude Opus 4.7
2026-07-09 10:33:14 +00:00
Julian Bouzas
1e817dff65 gst: device-provider: don't re-add metadata listener on permission change
PipeWire re-emits the registry global event for an existing object when the
client's permissions change. This can cause pw_metadata_add_listener() to be
called again on the same hook, corrupting the proxy's object_listener_list.

This is easily triggered by WirePlumber 0.5.15, whose reworked client access
logic sets portal permissions in several stages, causing the metadata global to
be announced more than once.

Bind the default metadata and add the listener only once, and tear down the
proxy and listener in global_remove so a genuine remove/re-add still works.
2026-07-09 10:21:25 +00:00
Wim Taymans
68716afa3d filter-graph: pass softVolume unmodified if not used
If the filter-graph can apply volume, it will set the softVolume to 1.0
so that the rest of the audioconvert will not apply softVolume anymore.

If it however not applies softVolume, it should pass the given
softVolume and softMute unmodified to be applied elsewhere.

The problem is that the filter-graph completely removed the softVolume
and softMute properties and in case the filter-graph was in use, this
resulted in the channelVolumes being applied in software. This then
could result in double volumes, once in hardware and another time in
software, causing sudden volume loss.

Fixes #5344
2026-07-08 14:09:40 +02:00
zuozhiwei
47a3479490 bluez5: destroy update_delay_event on transport_start failure
transport_start() creates update_delay_event before ensuring SCO I/O.
When spa_bt_transport_ensure_sco_io() fails, the fail path only cleans
up codec_data and leaks the event source on the loop.

Destroy update_delay_event in fail, matching do_remove_source().
2026-07-07 16:04:04 +08:00
Wim Taymans
696103cda9 libcamera: fix multi-character character constant warning 2026-07-06 09:37:01 +02:00
刘佳和
78a53b3c8d fix(libcamera): add missing commas to JSON device numbers array
Signed-off-by: liujiahe <liujiahe@uniontech.com>
2026-07-06 07:24:11 +00:00
filmsi
a0b92908bf Replace sl.po 2026-07-06 07:22:44 +00:00
Barnabás Pőcze
8ee3fbd6ec spa: libcamera: device: expose libcamera camera properties
A libcamera camera has a set of static properties found in `Camera::properties()`.
Some of the properties are already available for pipewire clients
(Model, Rotation, Location), most of them are not.

So serialize all properties into a strings and make them available on the
pipewire device. The keys have the form "api.libcamera.property.<vendor>.<name>"
and the values are intended to be valid json values, parsable by
python's `json.loads()` or qt's `QJsonValue::fromJson()`.

Controls of type "rectangle", "size", or "point" are not supported for now since
their json forms are not self-evident. They can be added when the need arises.
2026-07-06 07:16:48 +00:00
Barnabás Pőcze
8285966d15 spa: utils: json: add spa_json_encode_stringn()
Add the function `spa_json_encode_stringn()` that works very similarly
to `spa_json_encode_string()`, with the difference that it works with
non-null terminated strings (e.g. `std::string_view`).

`spa_json_encode_string()` is then implemented with this new function.

Additionally, since the input string is no longer null terminated,
escape bytes of value 0. This is probably better that putting
it into the result.
2026-07-06 07:16:48 +00:00
Mike Lothian
b904c3ee15 spa: alsa: acp-device: stop 100% CPU spin when a poll fd hangs up
handle_acp_poll() copies the poll revents into ACP and clears them, but
never actually looks at them. When one of the polled fds reports
POLLERR/POLLHUP - which happens when the ALSA card goes away, e.g. the
audio function of a USB dock being unplugged - the source is never
removed, and because that condition is level-triggered the loop just
keeps redispatching the handler.

The result is wireplumber pegged at 100% CPU, spinning on the card's
control fd:

    read(24, ..., 72) = -1 ENODEV (No such device)

with fd 24 pointing at a now-deleted /dev/snd/controlC<n>. It stays like
that until the card comes back or the service is restarted.

Accumulate the returned mask and, if anything reports SPA_IO_ERR or
SPA_IO_HUP, drop the poll sources so we stop hammering a dead descriptor.
The udev monitor still drives the real device removal and setup_sources()
re-arms the poll if the card reappears - the same teardown alsa-pcm.c
already does for its own control sources.

Signed-off-by: Mike Lothian <mike@fireburn.co.uk>
2026-07-05 00:04:50 +01:00
刘佳和
85df114eb4 bluez5: Fix JSON parser iterator usage in bcast_source config
Fix incorrect JSON iterator usage when parsing retransmissions and
max_transport_latency fields in BIS configuration.

The code incorrectly used it[2] iterator instead of it[1] when parsing
BIS object fields, causing undefined behavior and configuration values
being ignored.

Signed-off-by: liujiahe <liujiahe@uniontech.com>
2026-07-03 14:09:44 +08:00
Wim Taymans
53c2dd8d40 filter-graph: set io with the new method 2026-07-02 17:26:42 +02:00
Wim Taymans
95b95179d2 filter-graph: add set_io functions
Make it possible to set io areas like the clock and latency
2026-07-02 17:25:56 +02:00
Wim Taymans
c06b6c53c2 Revert "filter-graph: pass context to plugins"
This reverts commit 5e521d3532.

I think this can be done in a better, more flexible way with a new
method on the filter-graph to set io areas.
2026-07-02 16:47:07 +02:00
Carlos Rafael Giani
c4a9023215 module-rtp: Add documentation about module internals and improve comments
* Add .dox file that describes the internal design of the RTP module.
* Add details to the sink module documentation about the meaning of
  source.ip and how it interacts with local.ifname .
* Rename "constant delay mode" to "constant latency mode" comments in the
  code to match the documentation.
* Minor comment fixes.
2026-07-02 11:55:36 +02:00
Carlos Rafael Giani
2f94a49962 module-rtp-source: Detect and drop packets that are larger than the MTU 2026-07-02 11:55:36 +02:00
Carlos Rafael Giani
20f17c73de module-rtp: Correctly scale device_delay in constant latency mode 2026-07-02 11:55:36 +02:00
Carlos Rafael Giani
6c3fd1f07f module-rtp: Cleanup default raw / raop formats
This places the default formats into a single place, which makes
it easier to keep track of them.
2026-07-02 11:55:36 +02:00
Carlos Rafael Giani
505b3c6807 spa: Add atomics documentation 2026-07-02 06:45:31 +02:00
Carlos Rafael Giani
67ac1d101b spa: Fix SPA_LOAD_ONCE and SPA_STORE_ONCE atomic macros
These expected pointer to variables instead of variables directly, which
is inconsistent with how the other atomic macros behave. Furthermore,
SPA_STORE_ONCE was plain broken, since the underlying operation expects
an additional argument that was not included.
2026-07-02 06:45:28 +02:00
Daniel Scally
551eb0a473 gstpipewiresrc: Add a wait_negotiated() call to create()
Add a wait_negotiated() call to gst_pipewire_src_create(). This works
around a race-condition that we experience where the function is
called after the state is transitioning to paused, and after a
SPA_PARAM_Format with a NULL parameter has been passed. That event
is handled in the pipewire source by setting its negotiated flag to
False, which results in gst_pipewire_src_create() returning
GST_FLOW_NOT_NEGOTIATED, resulting in a failed stream attempt.

With this change, the stream survives the state change.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2026-07-01 09:21:31 +00:00
Julian Bouzas
8d93b779cd pulse-server: don't consider monitor nodes when finding the default source
If a system does not have any Audio/Source node, clients that want to capture
audio from the default source should fail instead of capturing audio from a
monitor Audio/Sink node.
2026-07-01 09:11:03 +00:00
Hugo Osvaldo Barrera
855735d720 Use descriptive description for Pro devices
For Pro Audio devices, the description is the card name with "Pro" or
Pro 1", "Pro 2", etc. appended. The result is user interfaces showing
around half a dozen devices with descriptions that don't help
disambiguate devices in the slightest.

Append the underlying PCM names instead of the "Pro N" string, so that
devices can be recognised at a glance.

Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/work_items/3982
2026-07-01 09:00:39 +00:00
刘佳和
6eddd1080f avb-pcm: fix typo in error log message 2026-07-01 08:43:31 +00:00
Charles
fc6e12bed0 gst: don't make stream errors fatal in pipewiresink mode=provide
When a consumer (e.g. Firefox via xdg-desktop-portal) connects to a
pipewiresink mode=provide node and format negotiation fails, the error
reaches the stream as a transient proxy error. The comments in
proxy_error suggest the application should decide whether the error is
permanent.

Before this on_state_changed unconditionally made every proxy error
permanent by calling pw_stream_set_error, which posted
GST_ELEMENT_ERROR and killed the entire provider pipeline. A virtual
camera provider should survive consumer negotiation failures.

In mode=provide, log the error as a warning and continue. Other modes
retain the existing behavior.

To reproduce (with the previous pool fix applied):

Producers:

gst-launch-1.0 -v -e pipewiresrc path=<id> ! \
  video/x-raw,width=1280,height=720,framerate=24/1 ! \
  jpegenc ! rtpjpegpay ! rtpstreampay ! \
  udpsink host=127.0.0.1 port=5000
gst-launch-1.0 -e \
  udpsrc address=127.0.0.1 port=5000 ! queue ! \
  application/x-rtp-stream,encoding-name=JPEG ! rtpstreamdepay ! \
  application/x-rtp,encoding-name=JPEG ! rtpjpegdepay ! \
  decodebin ! videorate ! videoconvert ! \
  pipewiresink mode=provide \
  stream-properties="properties,media.class=Video/Source,media.role=Camera" \
  client-name=VirtualCam

Then open Firefox and select VirtualCam as camera source, without this
fix the provider pipeline exits with an error, bringing down any other
clients streaming from it.
2026-07-01 08:42:56 +00:00
Charles
e95cad05ef gst: skip invalid crop metadata in pipewiresrc
META_VideoCrop is present on every buffer negotiated through the
adapter, even when the producer never sets a meaningful crop
region. Before commit c634ef961, gst_buffer_get_video_crop_meta
returned NULL on new GstBuffers so the zero values were never
applied. After that commit, gst_buffer_add_video_crop_meta always
succeeds, and an invalid crop produces black frames.

Without this, the following produces black frames,

Producer:

gst-launch-1.0 videotestsrc is-live=true ! \
  video/x-raw,format=I420,width=1280,height=720,framerate=24/1 ! \
  pipewiresink mode=provide \
  stream-properties="properties,media.class=Video/Source,media.role=Camera" \
  client-name=VirtualCam

Consumer:

gst-launch-1.0 pipewiresrc path=<id> ! videoconvert ! autovideosink
2026-07-01 08:42:56 +00:00
Torkel Niklasson
0a413c866c gst: deviceprovider: tear down node proxies before releasing core
Destroy the bound node proxies in probe() and stop() while the loop is
locked, before releasing the core. This removes the node listeners so no
node_event_info can fire after the core is gone, fixing the root cause of
the resync() NULL-deref crash and a node-proxy leak.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-30 14:21:08 +00:00
Elliot Chen
7ee2416bdd pipewiresrc: fix caps negotiation failure in some cases when changing state from playing to paused
basesrc will do caps negotiation if pad is reconfigured. Should check and
wait if caps negotiation is currently in progress before corking the stream.

Return true when flushing to avoid caps negotiation failure.
2026-06-30 14:20:10 +00:00
Wim Taymans
3c14693bed client-node: clear mix when clearing the node
Even if we don't have a transport we should clear the mix info if there
is any available.

Fixes #5348
2026-06-30 16:17:12 +02:00
Wim Taymans
187b9154a6 filter-chain: pass context to filter-graph
Pass the IO_Position and IO_Latency to the filter graph in the
context.
2026-06-30 12:52:32 +02:00
Wim Taymans
e42657f030 io: flesh out the node IO_Latency
Make this more useful by adding the capture and playback latency.

This structure can be used to say how much latency there is between the
capture and playback hardware.
2026-06-30 12:35:00 +02:00
Wim Taymans
5e521d3532 filter-graph: pass context to plugins
Make it possible to pass context to plugins and nodes in the
filter-chain.

We can use this to make filters aware of the graph clock or
latency, for example.
2026-06-30 12:24:54 +02:00
Wim Taymans
aa075c2a12 filter-graph: add support for multiple handles
Make instantiate create all the related handles in one go.

When a processing node has 1 in/out, multiple handles are created to
support multichannel. By instantiating the handles in one go, the
implementation could do some special multichannel support or do some
optimizations, like parse the config string only once.
2026-06-30 11:58:33 +02:00
Wim Taymans
b3eb2eabb8 filter-graph: return result from instatiate
Instead of returning a handle (and errno on NULL), return a result code
and store the handle in a return variable.

This makes it easier to handle the errors but also makes it possible to
return multiple handles later.
2026-06-30 11:20:15 +02:00
Wim Taymans
978e8c1a4b audioconvert: small cleanups
Move the sync code to before it is used.

We don't need to clear the graph setup state anymore in force mode, we
did that before we did the sync.
2026-06-29 10:36:26 +02:00
Torkel Niklasson
f174b4e688 audioconvert: sync filter-graphs out of data loop before forced rebuild
A forced setup_filter_graphs() deactivates and re-instantiates every graph,
which frees and recreates the underlying plugin handles (node_cleanup sets
node->hndl[i] = NULL before re-instantiating). This was done on a graph that
was still referenced by the RT data-loop snapshot (filter_graph[]), so the
RT thread could run a graph whose handles were NULL mid-rebuild, leading to a
NULL handle dereference in the filter-graph process path.

Mirror the safe ordering already used by load_filter_graph()/clean_filter_handles():
before reconfiguring, mark the graphs not-setup and sync_filter_graph() so the
data loop drops them from filter_graph[] under the loop lock. They are
republished by the sync that follows setup. The cheap snapshot swap is done
under the lock; the heavy re-instantiation stays off the RT path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-29 08:17:07 +00:00
Wim Taymans
10b339bbf8 docs: fix SVG text rendering to always use black
The drawio-exported SVGs used light-dark() CSS to switch text between
black and white based on color scheme. This caused white-on-light text
when viewing in dark mode. Replace all light-dark() values with their
light-mode equivalents so text and strokes are always black.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-26 12:52:47 +02:00
Wim Taymans
a988df47a2 docs: escape angle brackets in conf.c and fix page_core_api references
- conf.c: escape <key>, <value>, <action> placeholders in doc comment
- context.h, permission.h: fix \ref page_core_api to \ref api_pw_core

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-26 12:46:00 +02:00
Wim Taymans
9710f02837 docs: escape angle brackets and fix @filename and \ref in doc comments
Escape <portname>, <tensorname>, <paramname>, <port>, <rules> and
similar angle-bracket placeholders that doxygen interprets as HTML
tags. Also escape @filename (unknown doxygen command) and fix the
pw_stream::process() reference in thread-loop.h.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-26 12:43:56 +02:00
Wim Taymans
f055949cb5 docs: fix broken doxygen references and escape HTML tags
- modules.dox: remove references to non-existent sendspin modules
- access.dox: remove reference to deprecated pipewire-media-session
- dma-buf.dox: fix \ref EnumFormat to \ref SPA_PARAM_EnumFormat,
  fix \ref struct to struct \ref for spa_meta_sync_timeline
- pipewire.conf.5.md: add explicit {#synopsis} anchor for internal links
- pipewire-client.conf.5.md: fix audio_converter to audio_adapter ref
- pipewire-jack.conf.5.md: escape <id> HTML tags
- pipewire-props.7.md: fix monitor-prop__ to props__ for card profiles ref
- pipewire-pulse.1.md: fix pipewire-env ref to full anchor name
- pipewire.1.md: fix \ref CPU to \ref spa_cpu

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-26 12:42:01 +02:00
Wim Taymans
c4b767cba1 docs: rename pulse module files to fix doxygen \file name collisions
Prefix all pulse module source files with pulse- to give them unique
basenames, avoiding ambiguous \file suffix matching in doxygen when
identically-named files exist under src/modules/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-26 12:37:39 +02:00
Simon A. Eugster
2a88fb6ae8 docs: Remove specific user overview page again 2026-06-26 10:00:15 +00:00
Simon A. Eugster
1201b2ed32 docs: Extend description of object types 2026-06-26 10:00:15 +00:00
Simon A. Eugster
24770baaa0 docs: Add Tools and Configuration sections 2026-06-26 10:00:15 +00:00
Simon A. Eugster
8e5617c439 docs: Add routing examples 2026-06-26 10:00:15 +00:00
Simon A. Eugster
8a659f1aaa docs: Explain PipeWire role, add graphics 2026-06-26 10:00:15 +00:00
Simon A. Eugster
6a6feb45fe docs: Add user overview docs for PipeWire 2026-06-26 10:00:15 +00:00