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.
While not a reserved keyword, MSVC `#define interface struct`[1]
which causes a compile error when including the `spa/support/plugin.h`
header. While this can be worked around by `#undef interface`, it's
also easy to just rename the local variable.
[1]: https://stackoverflow.com/questions/25234203/what-is-the-interface-keyword-in-msvc
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.
Keep track of the sync nodes we added to a driver and bring in the other
nodes from the same sync group, group or link groups. This makes it
possible to have disjoint sync groups each with their own driver.
When checking for the nodes to collect with a driver, don't just skip
checking the other nodes when the driver is not in the sync group.
Instead collect all nodes that have the same group and link group as
the driver first and then check the sync groups.
Fixes export in ardour8
Fixes#4083
When the node activation.required was incremented because it was a
driver, only decrement it in that case, regardless of the current driver
state of the node.
This fixes the case of KODI where the required field gets out of sync
and things become unschedulable.
Fixes#4087
When spa-plugins is enabled, the gio-2.0 global dependency is
overwritten.
When bluez support is enabled, OR when gsettings is enabled, the gio-2.0
dependency is then detected as found. This means that
pipewire-module-protocol-pulse can end up enabling gsettings support
even if it has been forcibly turned off.
Rename the meson variables to ensure they are looked up separately.
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 way the compiler is able to detect cases when
a pointer is specified instead of an array.
Furthermore, incompatible pointer types can also
be diagnosed in `SPA_FOR_EACH_ELEMENT()`.
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
A driver can't be async, we always need to be able to trigger it
to start it so increment the required field.
Fixes an issue with asunc drivers such as the video-src example or gnome
screen sharing.
32 bits are enough, and additionally this also fixes an incorrect
format string, which caused the default `audio.rate` to be
incorrectly set on some platforms, such as 32-bit arm ones.
Fixes#4080
This commit moves the check that determines whether the mode
argument of `open*()` exists into a separate function.
With that, the check is fixed because previously it failed to
account for the fact that `O_TMPFILE` is not a power of two.
Furthermore, add `assert()`s in the fortified variants that
ensure that no mode is required by the specified flags.
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 prints changed state, props and params when run with -m and running
the `info` command. We try to print only things that have changed. It
would probably be good to make the props (and params) print a diff of
what's changed as well.
If the sender is reset, the RTP stream may return, but may no longer
correspond to the stream for which we loaded this instance of
module-rtp-source. A power cycle or network reset on Dante devices
causes a new SDP and SSRC to be selected, for example.
So let's make sure we don't consider invalid receives while tracking our
"receiving" state. Arguable, we should bail entirely if this happens.
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.
PipeWire expects the SPA_TYPE_OBJECT_ParamBuffers to be valid after
setting SPA_PARAM_Format. The pipewiresink knows the final buffer size
only after the pipewirepool has been activated.
There is a race between PipeWire asking the pipewiresink for the buffers
and GStreamer activating the buffer pool. If GStreamer has not activated
the buffer pool before PipeWire asks for the Buffer params, PipeWire
won't allocate buffers with the correct type and size.
The chance of hitting this window increases, if the upstream GStreamer
element doesn't use the buffer pool. In this case the buffer pool is
activated by the first buffer that arrives at the pipewiresink, which
may take some time.
Instead of not updating the Buffer params when the buffer pool is not
active, wait for the buffer pool to become active.
Add a helper function for updating the params instead of handling it in
the pool_activated callback. This allows to explicitly set the params
from the element.
roc-toolkit commit 03d29eb97211ca87593566998c5087590c1bae38 [0]
("Add sample_format() and pcm_format() to SampleSpec") made
a change in how the packet encoding is determined. Specifically:
This commit introduces small breaking change in C API:
when we search for packet_encoding compatible with
frame_encoding, we now take into account format too.
It means that if you use ROC_FORMAT_PCM_FLOAT32 in frame_encoding,
ROC_PACKET_ENCODING_AVP_L16_STEREO will not be selected automatically
anymore, and you need to specify it manually via packet_encoding.
This causes module-roc-sink to fail to set up the ROC sender:
roc_api: bad configuration: failed to select packet_encoding matching frame_encoding, set roc_sender_config.packet_encoding manually
So specify `ROC_PACKET_ENCODING_AVP_L16_STEREO` explicitly
as the packet encoding. This seems to work with roc-toolkit 0.3,
so the required version is not changed.
Fixes#4070
[0]: 03d29eb972
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.
Print the state of the stream not only as the numeric value, but also
print the name of the state to help the reader.
While at it, add the sink element to the log output to be able to
identify the sink that received the state change.
There isn't a good way to surface this information to the module owner
yet, so let's publish the information on the stream so we can try to
manage things in policy.