Commit graph

5275 commits

Author SHA1 Message Date
Barnabás Pőcze
348e703be0 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.
2025-08-13 10:22:57 +02:00
Barnabás Pőcze
b9b7c0ab05 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.
2025-08-13 10:22:53 +02:00
Barnabás Pőcze
89545946fd 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()`.
2025-08-13 10:22:50 +02:00
Barnabás Pőcze
14e0a8f66f 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`.
2025-08-13 10:22:46 +02:00
Barnabás Pőcze
47ee86938b spa: libcamera: source: port_set_format(): remove goto
Remove the `done` label by moving things into the `format != nullptr` branch.
2025-08-13 10:22:41 +02:00
Barnabás Pőcze
860e455440 spa: libcamera: source: support libcamera::formats::R8
Map `libcamera::formats::R8` to `SPA_VIDEO_FORMAT_GRAY8`.
2025-08-13 09:46:56 +02:00
Frédéric Danis
a50b66651e bluez5: backend-native: Add log for call state changes
This also to track each call state changes.
2025-08-12 18:22:40 +03:00
Frédéric Danis
1ad3fdff8a bluez5: backend-native: Free command list queue on RFComm free
When RFComm conection is closed or lost, the pending commands should
be freed, and if a DBus message is attached an error reply should be
sent.
2025-08-12 11:35:02 +02:00
Pauli Virtanen
618d60a1f2 alsa: show correct value in api.alsa.period-num 2025-08-09 12:53:41 +03:00
George Kiagiadakis
22e80e228c bluez5: backend-native: reset hfp_hf_in_progress state on error reply
If a AT+CHLD command fails, we may get stuck in the "in progress" state
forever unless we clear the state here.
2025-08-09 09:24:02 +00:00
Pauli Virtanen
a39462a6c0 bluez5: support 44.1kHz rate for BAP LC3
liblc3 doesn't support 44.1kHz directly, but its authors write one
should just use some nearby rate instead. Do just that.
2025-08-09 11:30:40 +03:00
Barnabás Pőcze
9aeba05e47 spa: libcamera: source: rework control setting
Instead of applying each control separately, collect them into a
`libcamera::ControlList`, and try to apply them at the end.

Furthermore, instead of doing a blocking loop invoke, use `spa_loop_locked()`
as it is sufficient to update `impl::ctrls`.

After this change control setting works in a more "atomic" way since every
control is parsed and checked before actually reaching the camera. It is
also detected if the given control is not supported by the camera.
2025-08-07 07:59:54 +00:00
Niklas Carlsson
30ba62e47c filter-graph: set NULL data support in LV2
In LV2, a port supports NULL data if the connectionOptional
property is set.
2025-08-06 12:09:13 +02:00
Niklas Carlsson
2ac708d916 filter-graph: add NULL data support per port
It would be good to define NULL support per port in e.g. LV2
plugins where sidechains are usually defined optional.
2025-08-06 12:08:23 +02:00
Barnabás Pőcze
e6f767d41d 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.
2025-08-05 17:51:53 +00:00
Barnabás Pőcze
8673f17c0a 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`.
2025-08-05 17:51:53 +00:00
Barnabás Pőcze
e379267274 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.
2025-08-05 17:51:53 +00:00
Barnabás Pőcze
8d9e469e09 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.
2025-08-05 17:51:53 +00:00
Barnabás Pőcze
e9367443ac spa: libcamera: source: ignore array controls
Properly ignore array controls because they are not supported for now.
2025-08-05 17:51:53 +00:00
Barnabás Pőcze
66cc01ee2d 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.
2025-08-05 17:51:53 +00:00
Barnabás Pőcze
44c05cfa7b spa: libcamera: source: move control enumeration to loop
Remove the `goto`s and instead move everything into a loop.
2025-08-05 17:51:53 +00:00
Barnabás Pőcze
cc187b035b 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.
2025-08-05 17:51:53 +00:00
Demi Marie Obenour
bac3d31283 pod: fix some data races in body code
The body code didn't use atomic loads, so it had undefined behavior if
the body was concurrently modified.  Use atomic loads to fix this.
Since the memory order is __ATOMIC_RELAXED this has no runtime overhead.
Also add barriers around a strncpy call and cast to volatile before
checking for a NUL terminator, though NUL-terminated strings in shared
memory are unuseable.  There are some places where bytewise atomic
memcpy(), which doesn't currently exist, is needed.  Instead, try to
fake it by using two barriers around memcpy().
2025-08-05 10:49:33 -04:00
Wim Taymans
c9c7552fed alsa: clear port before adding to free list
If we clear the port after adding, we will destroy the links into the
list and cause crashes later.
2025-08-04 11:02:02 +02:00
Barnabás Pőcze
8614fc45f8 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);
2025-08-01 15:54:10 +00:00
Barnabás Pőcze
a36b8a273d 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.
2025-08-01 15:54:10 +00:00
Barnabás Pőcze
e0e8bf083d spa: libcamera: source: create eventfd before starting camera
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.
2025-08-01 15:41:16 +00:00
Barnabás Pőcze
49be2a1c52 spa: libcamera: source: generate camera config right away
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()`.
2025-08-01 15:41:16 +00:00
Barnabás Pőcze
8c4f60af48 spa: libcamera: source: remove SPA_PROP_device{,Name}
`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.
2025-08-01 15:41:16 +00:00
Barnabás Pőcze
429c0e03a3 spa: libcamera: source: do not close fd
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.
2025-08-01 15:41:16 +00:00
Barnabás Pőcze
c167b98ff2 spa: libcamera: source: remove unused enum_fmt member
This was introduced by b2c38a2b3b ("libcamera: work on rewrite"),
but it has never been used.
2025-08-01 15:41:16 +00:00
Barnabás Pőcze
30ce210c2a spa: libcamera: source: prop_id_to_control(): do range check first
If it is a custom spa property, it will not be found in the lookup
table, so we can return immediately.
2025-08-01 15:41:16 +00:00
Barnabás Pőcze
07a4e593bb spa: libcamera: source: fix mapping of libcamera::ColorSpace::TransferFunction::Linear
`SPA_VIDEO_TRANSFER_GAMMA10` should be used to represent a
linear transfer function.

Fixes: 7e202a3844 ("spa: libcamera: add colorimetry support")
2025-08-01 15:41:16 +00:00
Barnabás Pőcze
938195b19f spa: libcamera: source: simplify color space conversion
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.
2025-08-01 15:41:16 +00:00
Barnabás Pőcze
a858290e4b spa: libcamera: source: avoid iterator overrun when enumerating controls
Do not overrun the iterator when skipping the initial couple items.
2025-08-01 15:41:16 +00:00
Barnabás Pőcze
6f058e6b0d spa: examples: local-libcamera: pass camera id to the plugin 2025-08-01 15:40:28 +00:00
Barnabás Pőcze
4e4086934c spa: examples: local-libcamera: do not set SPA_PARAM_Props
Setting `SPA_PROP_device` has no effect, do not do it.
2025-08-01 15:40:28 +00:00
Pauli Virtanen
e8fa7929b7 bluez5: use BT_PKT_SEQNUM for ISO packet sequence numbers
Use kernel BT_PKT_SEQNUM (likely in Linux v6.17) to provide the ISO
packets sequence numbers. Fall back to counting packets if kernel is too
old to support the feature.
2025-08-01 15:39:45 +00:00
George Kiagiadakis
79a069c886 bluez5: backend-native: add debug log in hfp_hf_remove_disconnected_calls() 2025-08-01 15:39:06 +00:00
George Kiagiadakis
5ccd1c5619 bluez5: backend-native: update hfp_hf_in_progress at the end of the CLCC update
When we skip the CIEV event in order to update the call list with CLCC,
we may receive multiple +CLCC events or even none, if the calls are
disconnected. To avoid any mistakes, update the hfp_hf_in_progress flag
after the CLCC update is entirely done.
2025-08-01 15:39:06 +00:00
George Kiagiadakis
e4b0f68e0b bluez5: telephony: implement asynchronous D-Bus calls
This removes the need to call poll() on the rfcomm socket in order
to wait for replies from the AG.

Use a queue to buffer all the commands that are to be sent to the AG
and match them to replies when they are received. Optionally associate
each command with a DBusMessage that is assumed to be a method call
from the telephony interface, which is then replied to when the rfcomm
command reply is received. Also associate each command with a state,
so that it is always deterministic what gets executed after the reply
is received.

On the telephony module, pass on the DBusMessage on the callbacks and
add a method to allow the receiver to send a reply. Only send FAILED
directly when the callback is not handled. Also, remove the return value
from the Dial() command (it was not advertised on the introspection
anyway) to make things easier.
2025-08-01 15:39:06 +00:00
Wim Taymans
0b647a9009 pod: fuse can_collect, SKIP and COLLECT
Make one COLLECT function that always reads all the varargs (SKIP)
and then tries to collect the pod+body with type checks
(can_collect + COLLECT). This makes things nicer because we can do
everything in one go and we only do one type check.
2025-08-01 16:23:37 +02:00
Wim Taymans
bef0706238 Revert "pod: remove checks from spa_pod_body_get_*()"
This partially reverts commit f7ae61cb1e.

We do want to do the checks in spa_pod_body_get_*() for extra safety.
The reason they were removed is because then we do the checks twice in
the parser. It should however be possible to fuse the can_collect and
COLLECT and SKIP calls together in the future.
2025-08-01 10:46:45 +02:00
Wim Taymans
00dbe9cb2a pod: add missing parser varargs formats 2025-07-31 14:13:41 +02:00
Pauli Virtanen
121608f040 bluez5: allow framing for BAP
There's actually no reason to disable framed qos presets.
2025-07-31 10:58:00 +00:00
Wim Taymans
28510f3117 bluez: safely parse the control data from buffers 2025-07-31 11:24:29 +02:00
Wim Taymans
f4ab704948 spa: use safe IO_Control parsing
The IO_Control areas are in shaed memory and need to use the parser to
safely extract the info.
2025-07-31 11:23:30 +02:00
Wim Taymans
ede1924ded pod: add more functions for easy pod+body parsing
Add functions to parse an object and struct from pod+body.
2025-07-31 11:21:28 +02:00
Wim Taymans
45ed70d480 control: mark the input as const, we don't change it 2025-07-31 10:54:09 +02:00
Wim Taymans
4715e36a5c spa: don't free the mix_list ports
We can't move the mix_list ports to the free_list like that because the
elements in the list use a different list to link together. Also, we
don't need to free those ports at all because they will be freed when we
move the port_list to the free_list.
2025-07-31 10:20:59 +02:00