`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.
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.
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.
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.
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.
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.
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.
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.
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.
We need to be sure that the compiler does not perform invented loads
after we checked the pod size. Otherwise we could have found that the
size was ok, only to be overwritten by an invalid size.
One way of avoiding this is to surround the memcpy with a barrier.
See #4822
When interpolating with rate correction != 1.0, don't floor the
resulting input rate to the nearest smallest integer.
This allows rate corrections < 1/in_rate to have some effect, and
reduces jumps in the response. One of the jumps is inconveniently
between rate=1.0 and rate=1.0+eps and will cause rate corrections to
oscillate if target rate varies close to 1.0.
If phase is float, calculations in impl_native_in_len/out_len can
produce wrong results due to rounding error.
It's probably better to not be in the business of predicting
floating-point rounding, so replace this by fixed-point arithmetic.
Also make sure `offset+1` cannot overflow data->filter array in
do_resample_inter* due to float multiplication possibly rounding up.
If phase is float, calculations in impl_native_in_len/out_len don't
necessarily match with do_resample, because e.g.
float phase0 = 7999.99;
float phase = phase0;
int frac = 8000, out_rate = 8000, n = 64, count = 0;
for (int j = 0; j < n; ++j) {
phase += frac;
if (phase >= out_rate) {
phase -= out_rate;
count++;
}
}
printf("count = %d\n", count); /* count = 64 */
count = (int)(phase0 + n*frac) / out_rate;
printf("count = %d\n", count); /* count = 65 */
don't give the same result.
Also add test where floating point multiplication rounding up to nearest
in
float ph = phase * pm;
uint32_t offset = (uint32_t)floorf(ph);
computation results to offset+1 > data->n_phases, accessing filter array
beyond bounds. (The accessed value is still inside allocated memory
block, but contains unrelated values; the test passes silently.)
Using the parser for the spa_pod_sequence in the data buffers is
required in order to safely read the pods while there could be
concurrent writes.
See #4822
Make a new body.h file with some functions to deal with pod and their
body. Make the iter.h functions use mostly this.
Rework the parser so that it only uses body.h functions. With the separation
of pod+body, we can read and verify the pod once and then use the
verified copy to handle the rest of the body safely.
We do this because iter.h only works in pods in memory that doesn't change
because it is vulnerable to modifications of the data after verifying it.
The new parser is not vulnerable to this and will not cause invalid
memory access when used on shared memory. There is however no need for
atomic operations to read the headers, whever is read is either valid
and useable of invalid and rejected.
See #4822
Use get_string() to get a pointer to the string in the pod so that we
also check if it has a 0 terminator.
Fix the test case now that is_string returns true even for non
zero-terminated strings.
The _is_type() macros should simply check the type in the header and if
the size is large enough to look into the type specifics. Further
validation of the values should be done when the value is retrieved.
Following this logic, the String zero byte check should be done in the
get_string() function.
We already know that we could succesfully allocate enough space for the
bytes because we checked that before so simply move to the body of the
new bytes pod. We don't need to do the extensive checks we do in deref.
Add a function that can build a pod from a pod definition, a body data
and a suffix.
We can use this to build strings and bytes and arrays like the other
primitives, which makes it possible to add them to choices or arrays.
Fixes#4588
SPA does not respect the C strict aliasing rules at all, so any code
that uses it must be built with -fno-strict-aliasing. Furthermore,
there is code in SPA that compares pointers that point to different
objects, so -fno-strict-overflow is also needed.
We don't actually need to calculate the GCD for each resampler rate
update. The GCD is only used to scale the in/out rates when using the
full resampler and this we can cache and reuse when we did the setup.
The interpolating resampler can work perfectly fine with a GCD of 1 and
so we can just assume that.