Commit graph

27 commits

Author SHA1 Message Date
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
2c2808fab1 spa: libcamera: manager: fix id allocation
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`.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
db3d91ebeb spa: libcamera: use nullptr instead of NULL 2025-07-15 08:12:54 +00:00
Barnabás Pőcze
4fa11619a2 spa: libcamera: use C++ style casts 2025-07-15 08:12:54 +00:00
Barnabás Pőcze
bb8223bff1 spa: libcamera: use anon ns instead of static
Move most things into anonymous namespaces for internal linkage
instead of using `static`. This shortes declarations and makes it
hard to forget.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
5a9cdd724f spa: libcamera: clean up includes
Remove some unnecessarily includes.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
5f4f4b5dd3 spa: libcamera: use lock when acquiring CameraManager
Make `libcamera_manager_acquire()` thread safe by locking a mutex
when the `CameraManager` instance is created and started.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
b7ef5c92bc spa: libcamera: remove unnecessary snprintf() 2024-05-15 08:31:03 +00:00
Barnabás Pőcze
9eab76d862 spa: libcamera: don't calculate id twice 2024-05-15 08:31:03 +00:00
Barnabás Pőcze
da1dbc1120 treewide: fix C++20 compilation error wrt. designated initializers
C++20 introduced designated initializers similar to the ones found
in C99, however, in C++ designated initializers cannot be mixed
with non-designated initializers. GCC rejects mixed initializers
with an error.
2024-05-03 07:16:57 +00:00
Barnabás Pőcze
934ab3036e treewide: use SPDX tags to specify copyright information
SPDX tags make the licensing information easy to understand and clear,
and they are machine parseable.

See https://spdx.dev for more information.
2023-02-16 10:54:48 +00:00
Wim Taymans
93d2571b30 libcamera: fix device id assignment
Find a free id from the available ids instead of just taking the current
number of devices, which would give assign the same id to multiple
cameras when: added 0, added 1, removed 0, added 1.
2022-11-14 16:04:21 +01:00
Wim Taymans
a57590e334 libcamera: emit device removal event
We need to emit the device id with NULL info to emit a device remove
event.

Also indent some code properly.
2022-11-14 15:38:16 +01:00
Barnabás Pőcze
83a510cba3 spa: libcamera: fix hook adding logic
Previously, if "add_listener" was called on the monitor device, then it
did not necessarily emit events about all devices because it called
`enum_devices()` which does not emit events about already existing
devices. So the very first listener would get all existing devices,
but subsequent ones would not get events about the existence of devices
that have already been seen by the monitor. Fix that by simply emitting
events about all existing devices if the current listener is not the first.
2022-09-15 11:17:47 +00:00
Barnabás Pőcze
74b66d939a spa: libcamera: do not try to acquire CameraManager if there is already one 2022-09-15 11:17:47 +00:00
Barnabás Pőcze
0f6c5a04c7 spa: libcamera: fix CameraManager event handling
libcamera's CameraManager runs the event handlers on its own thread,
thus synchronization is needed to ensure correct functionality.
Implement that by collecting hotplug events into a mutex protected queue
and signalling the main loop where they can be processed and the
"object_info" event can be safely emitted.
2022-09-15 11:17:47 +00:00
Barnabás Pőcze
f9796fc024 spa: libcamera: remove unnecessary typedef 2022-09-15 11:17:47 +00:00
Barnabás Pőcze
13357fec20 spa: libcamera: manage libcamera::CameraManager via a shared_ptr
Using a shared_ptr removes the need for manually calling
`libcamera_manager_release()` to drop the reference as it is done
automatically whenever the shared_ptr is destroyed or reset.
2022-09-15 11:17:47 +00:00
Barnabás Pőcze
222368e562 spa: libcamera: properly construct/destruct libcamera manager impl
Previously, the libcamera manager `impl` object was neither properly
constructed neither properly destructed. As a consequence, for example,
the shared pointers in the `devices` array weren't properly destructed,
although this has been somewhat mitigated by a previous change
that modifed `clear_devices()`.
2022-09-15 11:17:47 +00:00
Barnabás Pőcze
f699fa698e spa: libcamera: remove main loop from manager
The libcamera manager does not actually use the event loop
that it acquires during initialization. Remove it.
2022-09-15 11:17:47 +00:00
Barnabás Pőcze
13208220d8 spa: libcamera: print camera id when it appears/disappears 2022-09-15 11:17:47 +00:00
Barnabás Pőcze
086de7dcac spa: libcamera: properly dispose of shared_ptr
Previously, in `remove_device()`, the last device would be copied into
the slot of the to-be-remove device. The problem with this is that it
left the shared_ptr untouched in the previously last slot, and hence
creating an extra reference. Fix this by moving instead of copying.

A similar problem is present in `clear_devices()` which also
did not properly dispose of the shared_ptrs. Fix that by
calling `reset()` on each device's camera pointer.
2022-09-15 11:17:47 +00:00
Barnabás Pőcze
442a0c54ea spa: libcamera: move shared_ptr to avoid copy 2022-09-15 11:17:47 +00:00
Barnabás Pőcze
ba04a0f936 spa: libcamera: take raw pointer to avoid shared_ptr copy 2022-09-15 11:17:47 +00:00
Barnabás Pőcze
9370fbee3d spa: libcamera: indent with tabs instead of spaces 2022-09-15 11:17:47 +00:00
Wim Taymans
b2c38a2b3b libcamera: work on rewrite
Use manager to hotplug devices
Use StreamConfig to enumerate formats
2021-11-03 17:49:10 +01:00