An eventfd is used to signal the data loop from the libcamera request
completion event handler. Previously, this eventfd was created and
installed after the camera has been started and requests were queued.
This is problematic because it creates a small time frame where the
libcamera request completion handler will run in a state where the
eventfd is not fully set up.
Fix that by settup up the eventfd before the camera is started.
(cherry picked from commit e0e8bf083d)
Currently the plugin uses a single configuration during its entire lifetime.
So generate that configuration during initialization and hold on to it.
This makes the code a bit simpler, and also fixes issues stemming from missed
calls to `spa_libcamera_get_config()` as well as no error checking of
`libcamera::Camera::generateConfiguration()`.
(cherry picked from commit 49be2a1c52)
`SPA_PROP_deviceName` is an empty string and setting it does nothing.
`SPA_PROP_device` is always the libcamera identifier of the camera,
and setting it has no effect whatsoever in contrast to other plugins
such as v4l2.
So remove them both for now.
(cherry picked from commit 8c4f60af48)
Currently the plugin does not support importing memory and uses
`libcamera::FrameBufferAllocator` to allocate memory. Every file
descriptor is managed by that object, so they must not be closed
manually.
(cherry picked from commit 429c0e03a3)
`SPA_VIDEO_TRANSFER_GAMMA10` should be used to represent a
linear transfer function.
Fixes: 7e202a3844 ("spa: libcamera: add colorimetry support")
(cherry picked from commit 07a4e593bb)
Instead of using an out parameter, just return the `spa_video_colorimetry`
object; and do the libcamera -> spa conversion in a single place, where
the data is actually added to the pod.
(cherry picked from commit 938195b19f)
There is an issue in the id allocation mechanism which can result
in the different devices having the same id. Specifically, consider
the scenario where there are only two cameras, which have just been
added. In this case `impl::devices` looks like this:
(0, camA) | (1, camB) | (?, nullptr) | ...
Now assume that `camA` is removed, after which the array appears
as follows:
(1, camB) | (1, nullptr) | (?, nullptr) | ...
Then assume that a new camera appears. When `get_free_id()` runs,
when `i == 1`, it will observe that `devices[i].camera == nullptr`,
so it selects `1` as the id. Leading to the following:
(1, camB) | (1, camC) | (?, nullptr) | ...
This is of course incorrect. The set of ids must be unique. When
wireplumber is faced with this situation it destroys the device
object for `camB` when `camC` is emitted.
Fix this by simply not moving elements in the `devices` array,
leaving everything where it is. In which case the array looks
like this:
(nullptr) | (camB) | (nullptr) | ... // after `camA` removal
(camC) | (camB) | (nullptr) | ... // after `camC` appearance
Note that `device::id` is removed, and the id is now derived from
the position in `impl::devices`.
(cherry picked from commit 2c2808fab1)
Move most things into anonymous namespaces for internal linkage
instead of using `static`. This shortes declarations and makes it
hard to forget.
(cherry picked from commit bb8223bff1)
The function has a single caller is essentially just a wrapper only
calling `mmap_init()`. So inline it into `spa_libcamera_alloc_buffers()`.
(cherry picked from commit e19a8bb5cd)
If the libcamera `FrameMetadata` reports anything other than `FrameSuccess`,
then set `SPA_META_HEADER_FLAG_CORRUPTED`, notifying the application that
the frame may be unusable.
(cherry picked from commit 561a9d6ebb)
Use a union since only one member is active at a time, and use the
proper `libcamera::ControlType` enum to store the type instead of a
bare number. Also remove an unnecessary cast.
(cherry picked from commit 0022fc90b7)
`StreamFormats::pixelformats()` and `StreamFormats::sizes()` both
return newly created `std::vector`s, so do not call them multiple
times.
(cherry picked from commit 311b3cc37f)
The file is not useful without `libcamera-source.cpp` because it
uses symbols only defined there. And being a non-self-contained
source file, it also breaks clangd. So move its contents directly
to `libcamera-source.cpp`. This makes the file about 2200 lines long,
but I feel that is still manageable (and it is by far not the longest).
(cherry picked from commit 1a1cf55efb)
Make `libcamera_manager_acquire()` thread safe by locking a mutex
when the `CameraManager` instance is created and started.
(cherry picked from commit 5f4f4b5dd3)
libcamera says that cameras should default to manual focus mode. This
means that unless pipewire clients specifically change this control,
users with an autofocus-capable camera are left with an out-of-focus
image. This patch sets the autofocus mode to continuous and enables
auto-exposure (as the default for this is unspecified).
Testing with an imx708 on Raspberry Pi OS on a Raspberry Pi 4, before
this patch the image was generally out of focus in Firefox/webrtc, after
this patch autofocus works correctly.
(cherry picked from commit 3a0ffe21e6)
Based on testing, ALSA FireWire drivers introduce additional latency
determined by the buffer size.
Report that latency.
Pass device.bus to the node, so it can recognize firewire.
FireWire ALSA driver latency is determined by the buffer size and not the
period. Timer-based scheduling is then not really useful on these devices as
the latency is fixed.
In pro-audio profile, enable IRQ scheduling unconditionally for these
devices, so that controlling the latency works properly.
See #4785
Some devices (FireWire) fail to produce audio if period count is < 3,
and also have small buffer size. When quantum is too large, we might
then get too few periods and broken sound.
Set minimum for the period count in ALSA, to determine the maximum
period size we can use. If smaller than what we were going to use, round
down to power-of-2.
See #4785
Currently the v4l2 and libcamera plugins map `SPA_PROP_exposure` in incompatible
ways. So change the v4l2 mapping to `V4L2_CID_EXPOSURE_ABSOLUTE` because at least
that is in units of time (a step closer to addressing #4697), and because that
is more relevant for UVC cameras.
Also change the pipewire-v4l2 translation layer.
The Max latency property only works for timer based scheduling so that
we don't select a quantum larger than we can handle in our buffer.
With IRQ based scheduling this does not make sense because we will
reconfigure the buffer completely when we change quantums and so the
currently selected buffer size does not limit the latency in any way.
Fixes#4877
Some drivers (Firewire) have a latency depending on the ALSA buffer size
instead of the period size.
In IRQ mode, we can safely use 2 (or 3 for batch devices) periods
because we always need to reconfigure the hardware when we want to
change the period and so we don't need to keep some headroom like we do
for timer based scheduling.
See #4785
We don't actually need to calculate the GCD for each resampler rate
update. The GCD is only used to scale the in/out rates when using the
full resampler and this we can cache and reuse when we did the setup.
The interpolating resampler can work perfectly fine with a GCD of 1 and
so we can just assume that.
spa_alsa_read is called from the source process function when we are a
follower and no buffer is ready yet.
Part of the rate correction was performed by the ALSA driver when it
woke up but now, the resampler has updated the requested size and we
need to requery it before we can start reading samples.
Otherwise, we end up with requested samples from before the rate update
and we might not give enough samples to the resampler. In that case, the
adapter will call us again and we will again try to produce a buffer
worth of the requested samples, which will xrun.
A2DP v1.4 uses the rfa bits for adding 5.1 and 7.1 configurations.
Clear those bits properly when sending configuration, in case remote
device sets them.
(cherry picked from commit ae7a893ce9)