When we are already past the size of the buffer, don't bother calling
the overflow callback anymore, the buffer is already corrupted.
Otherwise it would be possible to have the overflow callback fail the
first time around, some data will be skipped, and then the next
overflow callback would succeed, giving the impression that all is
fine.
Add a unit test for this.
Pass the parameters around in a structure.
Add BUFFER_BYTES argument to configure the buffer size.
Add PIPEWIRE_ALSA env variable to set format, rate, channels,
period-bytes and buffer-bytes.
Add more variables in the alsa config file.
Instantiate the graph nodes when the samplerate is known instead of
using a fixed samplerate of 48KHz.
Warn when the convolver samplerate does not match the graph rate. We
might want to resample the IR later.
Suspend all nodes of the driver, even if the driver is already
suspended.
The suspend command makes sure that all nodes renegotiate to the new
graph rate.
This fixes the following sequence of events:
1. Play 44.1KHz file to loopback sink
2. Sink switches to 44.1, negotiates to 44.1
3. Loopback input and output streams negotiate to 44.1. All is good.
4. Stop playback, wait 5 seconds
5. Sink suspends, loopback input suspends (output stream doesn't suspend)
6. Play 48KHz file
7. Sink switches to 48, negotiates to 48. Sink (and followers) don't
suspend because sink was already suspended.
8. loopback input negotiates to 48, output stays at 44.1 -> failure
This patch fixes step 7. where it now tries to suspend all followers
even when the driver was already suspended. This then ensures that all
followers will try to negotiate to the new driver rate.
Use a reference to the location in the node where the handle of the
plugin can be found. That way we can change the handle only in the
node and have it changed everywhere else.
Add a resampler option to prefill the resampler with 0. This then
results in the resampler always outputing and consuming the same
amount of data instead of a short buffer in the beginning.
Add a process_playback function and use _trigger in the process_capture
to start processing. This ensure that the requested size is updated
before calling the process function.
We always need to update the latest requested size for output streams
before calling process. If there are no buffers or no suggestion, let
the audioconvert make one before we try again.
This way we always get the most recent requested size.
In monitor mode, we only need one sync to get the prompt and then we
just wait until we need to stop. There is no need to keep on syncing
because it consumes a lot of CPU.
Patch by Hiero32
Fixes#2709
When rfcomm_hfp_ag() returns false, an "ERROR" reply is sent.
When testing if the SLC is configured, 2 "ERROR" replies are sent, which
should not be done.
For backward compatibility with old Wireplumber releases, support the
old api.bluez5.a2dp.sink/source names, and use them in object events
instead of the media.sink/source names.
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.
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.