If the timer was canceled, the discont flag needs to be set. But in the
next cycle, unless the timer was canceled again, that flag should not
remain set.
If the user alters the realtime clock (for example by using the "date"
command in the shell), and the node driver uses the realtime clock as
the timerfd clock, then the scheduled graph cycle invocation may not
take place, or may take place much later than planned, because the
timestamp that was passed to spa_system_timerfd_settime() is now invalid.
Configure the timer to automatically be canceled if the realtime clock
is modified so that the graph cycle can be rescheduled with an updated
timestamp that is actually usable with the altered realtime clock.
It uses the onnxruntime library to parse the onnx file and construct a
neural network. It uses the label field to setup the plugin and how to
map the various tensors of the model to input, output, control and
notify ports.
Add an example config for how to use the silero VAD ONNX model with the
noise gate.
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`.
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.
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.
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).
Pass zero-length packets to the codec. BAP/ISO may use these to indicate
missing data.
Fix A2DP codecs to not parse input with spa_return_val_if_fail, that's
meant for assertions. Just return -EINVAL directly, it's normal that
input data may contain garbage.
If packet sequence number jumps ahead, or we would underflow, use
codec-provided packet loss concealment to produce some audio data.
When we produce it during underflow, skip the corresponding number of
sequence numbers of future packets.
If codec doesn't have PLC, keep the previous behavior (pad with zeros,
buffering pauses to wait for data).
LC3 and Opus have built-in support for packet loss concealment.
Add codec interface for that, and implement for LC3.
Extend media_codec interface so that packets not aligned with socket
reads can be handled, as in HFP. This is required for correct sequence
number counting, and for being able to run codec PLC *before* decoding
the next correctly received packet.
Update rate matching only once per process(). This ensures all nodes in
the group update their rate matching in the same way.
Also account for audio data in ISO output buffer in the reference time.
The calculations is in system clock domain, so when converting from
samples/duration to time rate difference should be accounted.
This does not have much effect in practice.
The rate matching calculations are done in the system clock domain. If
the driver ticks at a different rate, the correction factor needs to be
adjusted by the rate_diff.
This fixes ISO streams getting out of sync with each other when target
delay changes. This happens because typically one of them is the driver
and the other follower. Driver adjust clock rate, and follower does its
own adjustment *on top of that* so it rate matches more or less at
double speed. (The DLL of the follower to some degree corrects for
this, but can't do that when hitting RATE_CTL_DIFF_MAX and moreover it
acts with a delay.)