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.
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.
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()`.
Previously, the "impl" object was never properly constructed or
destructed, but it more or less worked out since the memory was initialized
to zero bytes and each member had trivial constructors. Except std::shared_ptr,
but an all zero storage happened to be equivalent to a default constructed
shared_ptr.
However, there was the still the problem that the shared_ptr was never
destructed, so it kept the referenced `Camera` object alive, which lead
to memory leaks.
An additional, somewhat unrelated change is that the "props" struct
is removed, and the device identifier is now stored in an `std::string`.
The reason is that `CameraManager::get()` already takes a const std::string reference,
so an std::string must be constructed in any case, so we might as well
take advantage of that and use `std::string` in the "impl" object as well.
Furthermore, wrap the `impl` struct in an anonymous namespace
to avoid name resolution problems.
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.
BlueZ adds the Endpoint property to the Properties dictionary of
SelectProperties.
This allows to know which remote Endpoint is an acceptor, and so which
local transport should be used as an initiator.
Multiple transport from the same device may share the same stream (CIS)
and group (CIG) but for different direction, e.g. a speaker and a
microphone. In this case they are linked.
In this case:
- On acquire, if another transport has already been acquired, the new
transport should not call Acquire or TryAcquire but re-use values from
the previously acquired transport,
- on release, the closing of transport fd and call to Release should be
done only for the last transport.
We can't determine which remote endpoint or device the
SelectConfiguration() call is associated with. For LE Audio BAP, as this
method is called only for the Initiator we set the whole instance as a
Central/Initiator.
This flag is unset on BAP media endpoint removal.
Make one function that updates the eventfd based on the state of
the plugin.
Do this check before getting the desciptors. The functional difference
is that the eventfd could become blocking now as well when getting the
descriptors. This fixes a problem where the poll would wake up without
any work to do.
See #1697
Add methods activate() that is called before first call to run() when
stream starts and deactivate() that is called after last call to run()
when stream stops. This makes it possible for aec-plugins to reset their
state between streams.
When a port name contains a ':' we will try to split it and use the part
before the colon as the node name, which will then fail.
If we can't find a node name after splitting, try again by assuming the
colon is part of the port name.
Fixes control port names such as "Ratio (1:n)" in #2685
Collect all timing info in the process function. When doing delay
reporting, get a consistent snapshot of all the pipewire side state to
calculate the result.
This should result in more correct timing results.
Only subtract the elapsed time from the server delay. Our reported
delay should always at least still include the data that we have
buffered or else read and write operations might think they can read
or write more than they actually can.
There is no need to patch the pw_time values with the io->rate just so
we can use it to convert the elapsed time to samples. Use the io->rate
directly instead.