Some complex camera pipelines, like the IPU6 can involve many /dev/video#
nodes (32 in the IPU6 case) and the current size of 128 chars is not enough
to hold all /dev/video# nodes in this cases causing SPA_KEY_DEVICE_DEVIDS
to get truncated, which in turn breaks the filtering of V4L2 devices which
are used by a libcamera driven camera in wireplumber.
Fix this by increasing the size of devices_str[] to 256.
This fixes wireplumber adding a bunch of non-function V4L2 video sources,
e.g. before this "wpctl status" outputs the following video sources:
Video
├─ Devices:
...
├─ Sources:
│ 90. ov2740
│ * 115. ipu6 (V4L2)
...
│ 135. ipu6 (V4L2)
│
├─ Filters:
After this fix the output is:
Video
├─ Devices:
...
├─ Sources:
│ * 92. ov2740
│
├─ Filters:
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
When the queue is full, before this patch we used to go into usleep in
the hope that the other thread will run and empty the queue and that we
can retry after the usleep.
This however does not always work because the other thread might be waiting
for the thread that does the invoke call and we lock forever.
Therefore we should always try to make progress in some way. Instead of
waiting, allocate an (or use the previously allocated) overflow queue and
write to that one. We can chain multiple overflow queues together as many
as we need (but we might want to bound that as well).
The loop.retry-timeout property is now deprecated.
See #4114
The control hooks of a loop are called before the loop starts polling
and after it has finished polling. Currently, this is used to implement
the locking in pw_thread_loop. This is used to guarantee that the thread
loop's lock is taken while the thread loop is dispatching, and that
the lock can be taken while the loop is polling, when it is running
no user-space code.
However, calling the thread control hooks of thread A when doing an
blocking invoke from thread B serves little purpose, and in fact
can cause issues: for example, issuing a blocking invoke on a
pw_thread_loop does not work unless the lock thereof is taken.
This behaviour, of calling the control hooks from other threads,
is also not documented, and goes contrary to what is currently
stated in the loop.h header file:
/** Executed right before waiting for events. It is typically used to
* release locks. */
...
/** Executed right after waiting for events. It is typically used to
* reacquire locks. */
At the moment the implementation allows any thread to queue invoke
items on any other thread without restrictions; calling the control
hooks only places extra restrictions on the usability of this mechanism
(in case of pw_thread_loop, having to take the loop's lock).
So do not call the control hooks when doing a blocking invoke.
A new 'broadcasting' state is to be added in BlueZ. It is
functionally similar to 'pending', but for the Broadcast scenario.
Until now, on Broadcast sink side, the transports associated with a
scanned source would automatically be switched to pending. PipeWire
then acquired any transport that was pending.
This is to be changed, transports will now remain in 'idle' state
until the user calls transport.select on them from bluetoothctl.
This changes the state to 'broadcasting'. PipeWire will then acquire
these selected transports.
This way, the user can select to which sink he wishes to sync.
While the spec allows for 1ppm changes, our rate matching logic applies
these changes quite often, which can be spammy on USB. I haven't seen
hosts mind this, but it seems like it might be a problem at some point.
Additionally, if we also have bind ctls enabled, every pitch update is
also a wakeup for ourselves (whether or not we're listening for the
pitch ctls, since the mixer fd does not distinguish between ctls, those
are filtered after we wake up).
The 10ppm threshold is empirically tested as being not "too noisy" (i.e.
when updates happen, I can see them scroll by with `amixer events`).
If necessary, we can make this configurable in the future.
Use the new UMP alsa sequencer API to make it produce UMP packets.
Set the alsa sequencer to MIDI2.0, which will make it convert all
messages to MIDI-2.0 UMP automatically. We can copy this straight into
the control buffers.
This also solves some problems with large sysex messages that are now
nicely split into chunks with UMP.
The IO_Buffers is used in the data thread to check if the port should be
scheduled or not. Make sure it is only set after we set buffers on the
port and cleared before the buffers are cleared.
Make sure we sync the port->io with the data thread.
See #4094
Due to the how the kernel part of BlueZ computes the extended
advertising interval for a Broadcast Source, a sync_factor smaller
than 2 will result in an invalid interval value (too small).
When using Open Broadcaster Software with Pipewire and a libcamera
camera node, changing the ExposureTime doesn't work.
The commit introducing the camera control setting has commented out the
integer case: ef4b9745b2 ("libcamera: handle canceled requests")
But as it doesn't give a reson for the comment, it looks like an
oversight.
Therefore removing the comment to allow setting the ExposureTime integer.
Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
The Pipewire libcamera spa plugin exposes multiple camera properties.
Unlike v4l2, libcamera usually exposes these as normalized floating
point values. But as the SPA_PROP types are based on v4l2, they are
currently set to integers.
This causes a problem when using pw-cli to change the properties,
as the spa_json_to_pod_part function casts the properties according
to their spa_type_info. Other software that doesn't depend on the
spa_type_info can correctly set the properties, as the values are
encoded in the spa_pod type and therefore also carry a type.
As the limited range from switching integers to floats is likely not a
problem, the affected spa properties were changed to the Float type.
This will cause pw-cli to also generate spa_pod values of type float
when setting v4l2 properties. Therefore the v4l2 spa plugin is also
adapted to allow floating point properties and cast these to integers.
Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
Make a new flag that is set when the process function is called because
of a recover from a graph xrun.
Use this flag in the freewheel driver to detect a recover and to avoid
scheduling a new timeout. We should schedule a new timeout only when the
process function was called after completion.
This fixes export in ardour some more when the initial driver timeout
didn't complete (when, for example, some nodes were still starting up).
Use dynamic pod builder so that we can also build complex formats.
Make sure we zero the format before we parse it or else we end up with
potentially uninitialized values.
When ENUM_FRAMESIZES or VIDIOC_ENUM_FRAMEINTERVALS return EINVAL for the
first index, make a dummy result and continue with that. This will
trigger an intersect withe filter so that we end up with something valid
instead of nothing.
Handle 0 framerates without crashing.
See #4063
ACP allows multiple %f in device strings (cf pa_alsa_open_by_template),
but we replace only one of them when emitting the nodes. The a52
profiles in default.conf use multiple %f and probably don't work.
Fix to replace also multiple %f when emitting ACP device nodes.
`:` is a reserved character on Windows filesystems.
As far as I can tell from looking through both PulseAudio and PipeWire
commit history the files under `alsa/mixer/samples` are not used or
installed by anything.
See #2474.
This provides access to GNU C library-style endian and byteswap functions.
Windows doesn't provide pre-processor defines for endianness, but
all current Windows architectures (X32, X64, ARM) are little-endian.
The `LoopUtils` interface can be used on platforms that don't
support the Linux-specific `timerfd` interface.
Added `local-videotestsrc` to validate the plugin still functions.
Restructured the SDL event loop as the window would not update
under WSL2, resulting in a black window being shown. All rendering
in SDL2 must happen on the same thread that originally created the
renderer.
To prevent the SDL event loop from being starved, we make sure to
poll it at least every 100 ms.
I believe the intent here is that if a `interval` is provided
but `value` is unset, then `value` should default to `period`
so the timer first fires after one `interval`.
Since `interval` is always a relative duration, `value` should
be interpreted as a relative duration, not an absolute one.
This is somewhat similar to the S32->F32 conversion improvements,
but here things a bit more tricky...
The main consideration is that the limits to which we clamp
must be valid 32-bit signed integers, but not all such integers
are exactly losslessly representable in `float32_t`.
For example it we'd clamp to `2147483647`,
that is actually a `2147483648.0f`,
and `2147483648` is not a valid 32-bit signed integer,
so the post-clamp conversion would basically be UB.
We don't have this problem for negative bound, though.
But as we know, any 25-bit signed integer is losslessly
round-trippable through float32_t, and since multiplying by 2
only changes the float's exponent, we can clamp to `2147483520`!
The algorithm of selection of the pre-clamping scale is unaffected.
This additionally avoids right-shift, and thus is even faster.
As `test_lossless_s32_lossless_subset` shows,
if the integer is in the form of s25+shift,
the maximal absolute error is finally zero.
Without going through `float`->`double`->`int`,
i'm not sure if the `float`->`int` conversion
can be improved further.
There's really no point in doing that s25_32 intermediate step,
to be honest i don't have a clue why the original implementation
did that \_(ツ)_/¯.
Both `S25_SCALE` and `S32_SCALE` are powers of two,
and thus are both exactly representable as floats,
and reprocial of power-of-two is also exactly representable,
so it's not like that rescaling results in precision loss.
This additionally avoids right-shift, and thus is even faster.
As `test_lossless_s32_lossless_subset` shows,
if the integer is in the form of s25+shift,
the maximal absolute error became even lower,
but not zero, because F32->S32 still goes through S25 intermediate.
I think we could theoretically do better,
but then the clamping becomes pretty finicky,
so i don't feel like touching that here.
At the very least, we should go through s25_32 intermediate
instead of s24_32, to avoid needlessly loosing 1 LSB precision bit.
That being said, i suspect it's still not doing the right thing.
Why are we silently dropping those 7 LSB bits?
Is that really the way to do it?
At the very least, we should go through s25_32 intermediate
instead of s24_32, to avoid needlessly loosing 1 LSB precision bit.
FIXME: the noise codepath is not covered with tests.
The largest integer that 32-bit floating point can exactly represent
is actually `(2^24)-1`, not`(2^23)-1` like the code assumes.
This means, whenever we use s24 as an intermediate step
to go between f32 and s32, we lose a bit of precision.
s25_32 is really a i32 with highest byte always being a sign byte.
Printing was done by adding
```
for(int e = 0; e != 13; ++e)
fprintf(stderr, "%16.32e,", ((float*)m1)[e]);
```
to `compare_mem`. I don't like how these tests work.
https://godbolt.org/z/abe94sedT
Can be used to group ports together. Mostly because they are all from
the same stream and split into multiple ports by audioconvert/adapter.
Also useful for the alsa sequence to group client ports together.
Also interesting when pw-filter would be able to handle streams in the
future to find out what ports belong to what streams.
This fixes the endianness of the parsed broadcast code. It also
fixes pontetial out-of-bouns write by using a bigger, temporary
bcode string, then, after checking it's length, copying it's content
to big_entry->broadcast_code.
It's not used anymore because it does work so well.
The problem is that while it transparently proxies param enums on
ports to peers, it fails to emit events when those peer
params change in a way that would make the enum result change as well.
This makes it quite hard to use this correctly.