Add a new SPA_TYPE_OBJECT_ParamDict object that contains a struct with
key/value pairs. We're using something similar for Tags but this is a
more generic version.
Make a new Capability param that uses the ParamDict object. This is
meant to be used to describe capabilities with the generic key/value
struct.
Make a new PeerParam object where the keys are generic ids of the peer
objects and the values any Pod. The idea is to use this object to store
a peer objects. Make some helpers to iterate the peers and their
objects.
Add a new PeerCapability param that uses the PeerParam object with
Capability objects. This can be used to send the collection of
Capabilities from all peers to a port. This is a bit like the tags but
in a more generic way. The tags could also be implemented in this new
generic way later.
Make the PeerFormats use the same PeerParam of Format objects.
The Capability param is set on ports. impl-link will collect all
Capability objects into a PeerCapability object and send this to the
peer. The difference with the Tag param is that these Capability params
are not in any way forwared on the node automatically (like what is done
in the loopback module) because they represent the capabilities of the
ports betweem the link.
Unknown preprocessor symbols are replaced with 0 in preprocessor
conditionals, so if `__has_attribute()` is not supported, then
the condition will be the following:
if 0 && 0(__cleanup__)
which is syntactically incorrect.
So split the condition and only check `__has_attribute()` if
it exists.
Fixes: 65d949558b ("spa: utils: add scope based resource cleanup")
Fixes#4962
spa_json_init assumes that we start in an object and always requires a
key/value pair. If the last part is a key, it returns and error and does
not want to return the key value.
This causes problems when parsing AUX0,AUX1,AUX2 or any relaxed array
withand odd number of elements.
Make a new spa_json_init_relax that takes the type of the container
we're assuming we're in and set the state of the parser to array when we
are parsing a relaxed array.
Fixes#4944
The body code didn't use atomic loads, so it had undefined behavior if
the body was concurrently modified. Use atomic loads to fix this.
Since the memory order is __ATOMIC_RELAXED this has no runtime overhead.
Also add barriers around a strncpy call and cast to volatile before
checking for a NUL terminator, though NUL-terminated strings in shared
memory are unuseable. There are some places where bytewise atomic
memcpy(), which doesn't currently exist, is needed. Instead, try to
fake it by using two barriers around memcpy().
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
Including C headers inside of `extern "C"` breaks use from C++. Hoist
the includes of standard C headers above the block so we don't try
to mangle the stdlib.
I initially tried to scope this with a targeted change but it's too
hard to do correctly that way. This way, we avoid whack-a-mole.
Firefox is working around this in their e21461b7b8b39cc31ba53c47d4f6f310c673ff2f
commit.
Bug: https://bugzilla.mozilla.org/1953080
This allows to use the library in projects that use `-Wswitch-default`
without any
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-default"
#pragma GCC diagnostic pop
This is useful as as the header is being pulled in via
pipewire/wireplumber headers into projects that might have this warning
enabled and would otherwise fail to build with -Werror.
Signed-off-by: Guido Günther <agx@sigxcpu.org>
When api.alsa.split-enable=true for ACP device, instruct UCM to not
use alsa-lib plugins for SplitPCM devices.
Grab the information from UCM for the intended channel remapping, and
add the splitting information to the nodes emitted.
Session manager can then look at that, and load nodes to do the channel
splitting.
What may be NULL in these methods is the pointer to the object
containing the spa_interface, not the interface pointer itself.
Fixes spa-acp-tool crashing with NULL deref in spa_i18n.
Make a function that can initialize raw audio info from a dict and fill
in the defaults. We can use this in many of the modules when the audio
format is parsed.
Use the helper instead of duplicating the same code.
Also add some helpers to parse a json array of uint32_t
Move some functions to convert between type name and id.
This gets the next key and value from an object. This function is better
because it will skip key/value pairs that don't fit in the array to hold
the key.
The previous code patter would stop parsing the object as soon as a key
larger than the available space was found.
Add spa_json_begin_array/object to replace
spa_json_init+spa_json_begin_array/object
This function is better because it does not waste a useless spa_json
structure as an iterator. The relaxed versions also error out when the
container is mismatched because parsing a mismatched container is not
going to give any results anyway.
The cleanup handlers like free(), close(), etc. aren't necessarily
guaranteed to preserve errno, so do it explicitly.
This allows for usage in functions that return NULL + errno to signal
errors.
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.
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()`.
Add macro SPA_CMP to do 3-way comparisons safely, and use it to avoid
signed integer overflows.
Fix also float/double comparisons (previously 0.1 == 0.8 since cast to
return type int).
Fix Id/Bool comparisons so they can return negative value.
Like the location, the orientation is a static property of libcamera
devices. While the rotation is already exposed as buffer transform,
knowing the property can be handy for applications in various ways.
See also: cd8ac5c1a ("libcamera: add camera location property on nodes")
Add struct spa_error_location that holds information about some parsing
context such as the line and column number, error and line fragment
with the error.
Make spa_json_get_error() fill in the spa_error_location instead. Add
some error codes to the error state and use this to add a parsing reason
to the location.
Add a debug function to log the error location in a nice way. Also
add a FILE based debug context to log to any FILE.
Replace pw_properties_check_string() with
pw_properties_update_string_checked() and add
pw_properties_new_string_checked(). The check string behaviour can still
be done by setting props to NULL but the main purpose is to be able to
avoid parsing the json file twice in the future.
When using the old pw_properties_update_string(), log a warning to the
log when we fail to parse the complete string.
Use the new checked functions and the debug functions to report about
parsing errors in the tools and conf parsing.
This gives errors like:
```
> pw-loopback --playback-props '{ foo = [ f : g ] }'
error: syntax error in --playback-props: Invalid array separator
line: 1 | { foo = [ f : g ] }
col: 14 | ^
```
Check each object key is associated with value. Disallow object or
array valued keys.
Add flag tracking whether the parser is at global top-level or not, as
there we may either be in object context or in a single-value context.
Save depth=0 array flag bit in state, so that spa_json_next preserves
its complete state across calls. The higher-depth flag bits can be in
temporary stack as they are not needed across calls.
Control characters probably are an error. We also are not validating any
utf8 here, so disallow bare utf8 too --- one likely should use strings
for such content anyway as spaces are not allowed otherwise.
Successful return is always >= 2 since it includes {} or [], so use 0 to
indicate error.
Since there's existing code that doesn't check the return value, it's
better to use 0 for errors as it'll likely to just lead to producing an
empty string if the value is not checked.
Disallow = and : as bare items in [] containers, as that likely is
"[ { foo = bar } ]" mistyped as "[ foo = bar ]".
Disallow nesting errors, eg. "[ foo bar" or "[ foo bar }".
Fix handling of ", \ and # in bare strings.
Fix ignoring trailing comments.
Add a fixed-size stack (128 levels) to the tokenizer, so that it can
check these at levels below its depth.
When the tokenizer encounters an error, make it and its parents enter
error state where no further input will be processed. This allows caller
to check for parse errors later as convenient.
The error state can be queried using spa_json_get_error, which also
looks up the error line/column position.
spa_json_parse_float/int receive non nul-terminated string, so calling
string functions assuming nul-termination is invalid.
Fix by copying data to a buffer before doing parsing.