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.
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.
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
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
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
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
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>
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
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.
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
`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)
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)
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)
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)
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)
`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)
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)
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)
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)