Commit graph

13610 commits

Author SHA1 Message Date
Pauli Virtanen
8c5dd0c9f7 doc: update doxygen-awesome.css
Update doxygen-awesome.css to v2.4.1 (1f3620084ff7573) from upstream.

Link: https://github.com/jothepro/doxygen-awesome-css/
2025-10-16 00:17:26 +03:00
Wim Taymans
2799350a59 modules: use timer-queue in avahi-poll
Pass the pw_context to get to the shared queue and loop.
Patch up the users of avahi-poll.

Fixes #4913
2025-10-13 11:27:56 -07:00
Wim Taymans
181269cafc timer-queue: delete next timer event when it got fired
When we fire the timer event, mark the next timeout as NULL because
nothing else is going to timeout anymore until we rearm the timer.

This has the effect that if we cancel and add the same timer from the
callback that we will reprogram the timer with the new timeout instead
of thinking the item as already programmed.
2025-10-13 11:26:43 -07:00
Wim Taymans
cf0de8f86d timer: fix compilation on arm 2025-10-13 11:26:12 -07:00
Wim Taymans
3fb9524cf1 pulse-server: clear timer when stream is created
Make a function when the stream is created so that we can clear the
create_tag and the timer.
2025-10-13 11:25:47 -07:00
Wim Taymans
5ff1cb5545 pulse-server: use the new timer-queue for timeouts
Use the timer queue for scheduling stream and object data timeouts.

This avoids allocating timerfds for these timeouts and the timer queue
can handle many timeouts more efficiently.
2025-10-13 11:25:41 -07:00
Wim Taymans
f2a11fadf4 timer-queue: add a new timer queue helper
This allows you to schedule timeouts. It keeps a sorted list of
timeouts and uses just 1 timerfd to schedule the head of the timeout
list.
2025-10-13 11:25:37 -07:00
Wim Taymans
ca51f72900 pulse-server: make timer function static and fix formatting 2025-10-13 11:25:32 -07:00
Arun Raghavan
db69a93b82 pulse: Handle timed out streams
If we don't get a link on a stream, we might never send a create stream
reply. The client handles this fine by timing out after 30s and dropping
the stream, but the server holds on to the pw_stream forever (or until
the client quits).

Let's add a timer to clean up such streams on the server.

Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4901
2025-10-13 11:25:25 -07:00
Wim Taymans
fd60e04525 1.4.9 2025-10-09 11:14:51 +02:00
Barnabás Pőcze
3bdc84aadb spa: libcamera: device: adapt to libcamera change
The interface of string typed controls has recently been changed in
libcamera[0], which affects `properties::Model`, so adapt to that change
in such a way that is compatible with both the new and old versions.

[0]: f84522d7cd
2025-10-08 17:55:14 +02:00
Wim Taymans
96b4fdec0a profiler: avoid null dereference
Avoid shadowing some variables from the parent block.

The node of a target can be NULL when the target is running in another
instance. We already do some checks for this but make sure we never
deref the NULL pointer.

Fixes #4922
2025-10-08 17:54:21 +02:00
Wim Taymans
b000859938 module-rtp: fix initial session id and hash
Add a flag to make_sdp to note if this should be a new SDP or a temp
SDP to compare to the existing one.

Move the update of session_id and hash to when we make a new SDP. This
way we also update session_id and hash when we make the first SDP.

This fixes the initial undefined SDP session id and hash.

Fixes #4852
2025-10-06 19:45:01 +02:00
Wim Taymans
636cbae9b6 avahi: handle fd allocation errors
When we fail to allocate an io source or a timerfd, return NULL instead
of crashing later on.

See #4913
2025-09-29 17:33:18 +02:00
Peter Ujfalusi
ba7790123c alsa: Use the minimum period size as headroom for SOF cards
Configure the headroom to be equal of the minimum allowed period size for
the configuration.

This is desirable when the ALSA driver's hw_ptr is 'jumpy' due to
underplaying hardware architecture, like SOF.
In case of SOF the DSP firmware will burst read at stream start to fill
it's host facing buffer and later settles to a constant pace. The minimal
period size is constrained by the driver to cover the initial burst and
settling time of the hw_ptr.

Guard this mode of working with a new boolean flag, which is only enabled
for SOF cards, kept it disabled for other cards to avoid any unforeseen
side effects.

Even if the use-period-size-min-as-headroom is set to true, the manual
headroom configuration will take precedence to allow experimentation.

Link: https://github.com/thesofproject/linux/issues/5284
Link: https://github.com/thesofproject/sof/issues/9695#issuecomment-2569033847
Link: https://github.com/thesofproject/sof/issues/10172
Link: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4489
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
2025-09-29 17:32:33 +02:00
Wim Taymans
78937ee0ec adapter: fix Start of adapter
Commit cbbf37c3b8 changed the logic of the
Start command. Before this commit, when there was no converter, the
follower would always get the Start command. After the commit, the
follower would only get Start when previously Paused.

This however breaks when we set a format or buffers on the follower
without a converter because those actions might change the state of the
follower to Paused implicitly.

We should simply remove the started check here and always call Start on
the converter and follower, the implementations themselves will keep track
if anything needs to be done.

Fixes #4911
2025-09-29 17:26:20 +02:00
Pauli Virtanen
dd3798487c alsa: don't fail if 3 periods_min fails
Some drivers (emu10k1) appear to not necessarily support more than 2
periods.

Don't fail start if snd_pcm_hw_params_set_periods_min() fails, then we
just set nearest possible periods and buffer sizes.
2025-09-29 17:25:41 +02:00
Barnabás Pőcze
989b2150dc spa: libcamera: source: fix typo in log message
';' -> ':'

(cherry picked from commit 7a98bcf735)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
b6c0f26fd1 spa: libcamera: source: query frame buffer planes just once
(cherry picked from commit 93941e5207)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
88aa30f0d2 spa: libcamera: source: simplify spa_libcamera_clear_buffers()
Remove the unused `impl` parameter and the unnecessary early return.

(cherry picked from commit bf327d3dfb)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
9be2e3d7e9 spa: libcamera: source: keep libcamera::FrameBufferAllocator
Instantiate it once and keep it instead of always dynamically
allocating it when the camera is acquired.

(cherry picked from commit 1f60cd291f)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
657e55a65b spa: libcamera: source: clear buffers when format is changed
pipewire assumes that the buffers are removed from a port when its format is
changed even without an explicit call to `port_use_buffer()`.

So if the format is not just tested, clear the buffers, as well as the libcamera
requests and buffers because they are also recreated when a new format is set.
This matches the behaviour of the v4l2 plugin. Furthermore, this change also
removes the call to `spa_libcamera_use_buffers()` because that function does
nothing. And finally this change necessitates that the current format is always
reset (when not testing), not just before reaching `spa_libcamera_set_format()`.

(cherry picked from commit c517e712ed)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
a6ec4521f7 spa: libcamera: source: handle try-only format unset
Do nothing if `format == nullptr` and `SPA_NODE_PARAM_FLAG_TEST_ONLY` is present.

(cherry picked from commit 31176120f5)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
e7eef5f7ec spa: libcamera: source: do not emit param change if try-only
If `SPA_NODE_PARAM_FLAG_TEST_ONLY`, then the format does not change
on the node, it is only tested. So do not emit the param change events.

(cherry picked from commit a8a60832cd)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
0c418d05c3 spa: libcamera: source: extract presence of SPA_NODE_PARAM_FLAG_TEST_ONLY
Use a boolean named `try_only` instead of checking `flags` each time.

(cherry picked from commit dac9e40be6)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
3b5a2c06f3 spa: libcamera: source: remove format config shortcut
Remove the code that is supposed to compare the current and the to-be-set
format for returning early if they match. This is removed:

  * v4l2 also does not have it either;
  * it needs more consideration (there are not properly handled fields);
  * it would make later changes somewhat more complicated.

(cherry picked from commit 05a9e52caf)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
11d224befa spa: libcamera: source: set chunk flags on error
Set `SPA_CHUNK_FLAG_CORRUPTED` if the frame buffer metadata
signals anything other than success.

(cherry picked from commit 25075bb3d7)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
8ed8f21100 spa: libcamera: source: process requests on data loop
Since `impl::requestComplete()` runs in an internal libcamera thread, extra care
would need to be taken to validate all accesses to common data structures. For
example, the function might call `spa_libcamera_buffer_recycle()`, which accesses
`impl::ctrls`, which would be unsafe because it could read or modified at the same
time on the data thread. So move the processing of requests to the data loop.

(cherry picked from commit 019a5c130f)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
3ca1e20b3d spa: libcamera: source: process all requests in the ring buffer
It is possible that multiple requests complete before the data loop can run
`libcamera_on_fd_events()`. However, previously only the earliest item was
processed from the ring buffer, meaning that in those cases request processing
could be lagging request completion by multiple requests.

Fix that by getting the number of available requests and processing them all.

(cherry picked from commit 22ddb88072)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
746805d30b spa: libcamera: source: reset ring buffer when stopping
Presently, the ring buffer of completed requests is only cleared
when the buffers are removed from the port. This is not entirely
correct since pause/start commands do not clear the buffers but
they stop the camera. As a consequence, it is possible that some
completed requests stay in the ring buffer, causing them to be
mistakenly processed when the camera is started next.

So reset the ring buffer after the camera is stopped, the same time
as the queue of free buffers is cleared.

(cherry picked from commit c01a2977a5)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
1d0a1cbf12 spa: libcamera: source: move request completion data to impl
A `libcamera::Request` is directly tied to the camera, not any ports ("streams")
of it. So move the request completion ring buffer into the `impl` struct.

This is a prerequisite for supporting multiple libcamera streams (~ exposing
multiple ports on the node) in the future.

(cherry picked from commit 72fd462090)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
ad1dbf1541 spa: libcamera: source: store the request pointer in ring buffer
The request will be needed later, so store that directly in the
completion ring buffer for easy access.

This is fine even though `impl::requestComplete()` calls `Request::reuse()`
because only the request cookie is used in `libcamera_on_fd_events()` and
that remains constant during the lifetime of a request object.

(cherry picked from commit 099292d63d)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
c80af0c2c0 spa: libcamera: source: remove impl::pendingRequests
The handling of `impl::pendingRequests` is a bit problematic because,
for example, during startup, if `spa_libcamera_buffer_recycle()` observes
that `impl::active == false`, then it will try to append to `impl::pendingRequests`,
which is being iterated in the main thread in `spa_libcamera_stream_on()`.
That is not allowed on an `std::deque`.

So instead remove it altogether, and simply queue all requests when starting.
After `libcamera::Camera::stop()` returns, every request is guaranteed not
to be used by libcamera, and they can be freely reused, so this is safe to do.

This also removes the need for calling `spa_libcamera_buffer_recycle()` when
the buffers are set/unset on a port since that function no longer changes
anything apart from updating `buffer::flags` but `spa_libcamera_alloc_buffers()`
is modified appropriately to take care of that. And in the case of
`spa_libcamera_clear_buffers()` clearing the flag is not required because the
next `spa_libcamera_alloc_buffers()` call will reset reset the flags.

(cherry picked from commit 68627c5563)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
ceb10964d3 spa: libcamera: source: persistent requests <-> buffer association
Currently only a single stream is used. This makes it easy to associate
each request with the appropriate frame buffer when it is created. In
turn, this makes reusing requests a bit simpler and a bit more efficient.

So do that: add buffers to requests when they are allocated in `allocBuffers()`.

(cherry picked from commit 475665d615)
2025-09-27 13:22:59 +02:00
Barnabás Pőcze
2dc1e2a5d3 spa: libcamera: source: allocBuffers(): more error checking
First, check if the request pool is empty, and signal an error if it
is not. Second, ensure that the number of allocated buffers matches.

(cherry picked from commit 29b0c87d71)
2025-09-27 13:22:58 +02:00
Barnabás Pőcze
98842d50cf spa: libcamera: source: allocBuffers(): restore on failure
Undo the allocation and clear the requests if a failure is encountered
in order to leave things in a known state.

(cherry picked from commit 348e703be0)
2025-09-27 13:22:58 +02:00
Barnabás Pőcze
b28eb20c1f spa: libcamera: source: freeBuffers(): call when format is unset
At the moment the libcamera buffer allocation is completely tied to format
negotiation. `freeBuffers()` undoes `allocBuffers()`. And `allocBuffers()`
is called as part of `spa_libcamera_set_format()`. Therefore `freeBuffers()`
should be called independent of the state of the buffers on any port.

Otherwise unsetting the format while there are no buffers on the port will
cause the libcamera requests and buffers not to be released correctly. Similarly,
removing the buffers from a port would clear the libcamera requests and buffers,
making the node unusable without setting a new format.

(cherry picked from commit b9b7c0ab05)
2025-09-27 13:22:58 +02:00
Barnabás Pőcze
a5cb888578 spa: libcamera: source: freeBuffers(): split pending request removal
`freeBuffers()` should undo exactly what `allocBuffers()` does. However,
it currently also clears `impl::pendingRequests`, but that is filled
by `spa_libcamera_buffer_recycle()` during `spa_libcamera_alloc_buffers()`.

So remove the clearing of `impl::pendingRequests` from `freeBuffers()` and
move it directly into `spa_libcamera_clear_buffers()`.

(cherry picked from commit 89545946fd)
2025-09-27 13:22:58 +02:00
Barnabás Pőcze
93426bca4b spa: libcamera: source: propagate error when setting format
If `spa_libcamera_set_format()` fails, propagate its return value
as is without rewriting it to `EINVAL`.

(cherry picked from commit 14e0a8f66f)
2025-09-27 13:22:58 +02:00
Barnabás Pőcze
ef09f436b3 spa: libcamera: source: port_set_format(): remove goto
Remove the `done` label by moving things into the `format != nullptr` branch.

(cherry picked from commit 47ee86938b)
2025-09-27 13:22:58 +02:00
Barnabás Pőcze
d76fee1353 spa: libcamera: source: use dynamic builder for controls
Use a dynamic spa pod builder when enumerating controls since previous
changes can report more information from any given control. Also increase
the stack buffer size to 4096 bytes.

(cherry picked from commit e6f767d41d)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
dbc376fc2f spa: libcamera: source: provide value labels if available
For enumerated controls of type `libcamera::ControlTypeInteger32`, libcamera
provides the names of the enumerators, so add them to `SPA_PROP_INFO_labels`.

(cherry picked from commit 8673f17c0a)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
9b638d37d1 spa: libcamera: source: handle enum controls better
If the `libcamera::ControlInfo` object explicitly lists the values of a
control, then use those values when adding `SPA_PROP_INFO_type` to
construct an enumerated choice object.

(cherry picked from commit e379267274)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
b8bbcfdb96 spa: libcamera: source: unify control range logic
If libcamera does not provide a default value, then the average of the
minimum and maximum values is taken. The same logic is duplicated for
`float` and `int32_t`, so move it into a function template.

(cherry picked from commit 8d9e469e09)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
337d3b3daf spa: libcamera: source: ignore array controls
Properly ignore array controls because they are not supported for now.

(cherry picked from commit e9367443ac)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
a1cc0f3d86 spa: libcamera: source: rework bool control type info
`SPA_POD_CHOICE_Bool()` assumes that both true and false are available,
which may not be the case for libcamera controls, so manualy construct
the enumerated choice object and only add the actually available options.

(cherry picked from commit 66cc01ee2d)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
f6d3db72a1 spa: libcamera: source: move control enumeration to loop
Remove the `goto`s and instead move everything into a loop.

(cherry picked from commit 44c05cfa7b)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
eb6b9a47fc spa: libcamera: source: separate type info generation
Add a new function `control_details_to_pod()` that builds a
`SPA_TYPE_OBJECT_PropInfo` object describing a libcamera control.

(cherry picked from commit cc187b035b)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
7b4713ec73 spa: libcamera: manager: keep libcamera::CameraManager
At the moment, the camera manager shared pointer is released when the last
listener is removed, and recreated when the first listener is added. This
is the same behaviour that the alsa and v4l2 monitors implement with their
respective udev, inotify monitors.

However, for `libcamera::CameraManager`, this is likely not the best way
for multiple reasons:

  (a) it is a complex object with significant construction and starting cost,
      which includes starting threads and usually loading shared libraries;
  (b) usually one listener is added right after creating, and it is removed
      right before destruction, in which there are real no advantages;
  (c) the camera manager, being a shared resource, might very well be kept
      alive by some other component, in which case there is again not much
      real benefit.

So simplify the code by getting a camera manager reference at the beginning
and keeping it until the libcamera monitor is destroyed.

This also fixes a race condition where a hot-plugged camera might not have
been detected if the libcamera event was emitted between these two:

  collect_existing_devices(impl);
  start_monitor(impl);

(cherry picked from commit 8614fc45f8)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
4847bb3faf spa: libcamera: manager: factor out hotplug event submission
The `impl::{add,remove}Camera` functions do the same thing except
for one value, the type of the hotplug event. Add a private method
to `impl` that implements the common parts.

(cherry picked from commit a36b8a273d)
2025-09-26 09:58:10 +02:00