We now translate device.description to node.description when parsing
the properties so check for node.description and generate one when
it's not available.
Fixes#2166
Use invoke to set the zero-denormals flag from the data thread when
explicitly set. The flag is per thread and should really only be set on
the data thread and only when explicitly enabled.
Fixes#2160
We need to create fake channels when parsing the IEC958 format or
else we get an invalid format and IEC958 passthrough doesn't work.
Ignore the IEC958 formats when collecting formats for the device or else
the fake channels mess with the real channels of the device.
See #1442
PulseAudio will convert the samplespec/channelmap to a format_info
and omits the input format/rate/channels when the fix flags are set. It
does not use the input values at all.
Do the same in pipewire-pulse, make a single format description without
the requested fields.
This also needs a session manager fix to make it deal with those missing
fields.
See #876
Wait the reply to be sent and the sample to complete playback before
freeing the sample. Otherwise it might have been possible that the
sample completes before the reply can be sent.
If the sample finished playing before we finished the roundtrip to
get the sink_index, it will be destroyed. When the roundtrip completes,
it will try to use invalid memoryy and crash.
Make sure we destroy all pending replies before destroying the sample
to avoid this problem.
Fixes#2151
There's an assumption that marshaled messages consist of a single POD,
since we now tag on a footer after it. This is true for the
protocol-native implementations, which all wrap the message in a single
POD Struct.
To catch protocol-native implementation bugs here later, add assert that
marshaling produces a single POD.
Some client messages have bare ids (as opposed to proxies/resources),
eg. as in pw_registry_bind/destroy. If the client is processing
messages late, these may refer to an object that was already removed,
and the id may now refers to a differnt objects. I.e. the following
race condition needs to be resolved:
server client
Global 1 (gen. 1)
Global 1
Global 1 remove
Global 1 (gen. 2)
Bind/destroy 1
Where the client would bind/destroy the wrong global, since it did not
yet see the messages for the second one.
To keep track of which object the client means, the server keeps track of
the "generation number" of its global registry, and what generation
the client is at.
Each global remembers at what generation of registry they were
registered. When processing the messages that use bare ids, check the
registry generation of the client, to know whether the message refers to
a stale global that was already removed.
Messages where client sends bare ids to server are:
pw_registry_bind, pw_registry_destroy, metadata_set_property
In pw_registry_* do the staleness check directly. Also add staleness
check in pw_impl_client_check_permissions, so that also the metadata
case is handled.
The generation numbers are passed around in message footers, but only if
they have changed. When the generation number changes on server, we
send the updated value to the client in a message footer. When client
has received an update value, it will send the value back in the footer
of the next message it sends to the server.
Based on: Wim Taymans <wtaymans@redhat.com> "impl-core: check serial number"
Extend version 3 protocol with message footers, which are for passing
around global state data that is not addressed to a specific object.
The extension is backward compatible with previous v3 clients, and won't
e.g. result to error spam in logs.
The footer is a single SPA POD, appended after the main message POD.
Because both the protocol message and the message POD record their
length, it's possible to append trailing data. Earlier clients will
ignore any data trailing the message POD.
The footer POD contains a sequence [Id opcode, Struct {...}]*,
so there is room to extend with new opcodes later as necessary.
There are separate marshal/demarshal routines for messages aimed at
resources and proxies.
Unfortunately, libX11 has global error and I/O error handlers,
which make it inconvenient to use them from library code.
Since libX11 1.7.0, there is a per-display "exit_handler" which
is called from `_XIOError()`, however, the global I/O error
handler is still called before that, and that - by default -
calls `exit(1)` in `_XDefaultIOError()` after printing the error
to stderr.
To avoid exiting, custom handlers will be registered when
libpipewire-module-x11-bell.so is loaded given that at
that moment the default handlers are installed.
When the shared object is unloaded, the handlers will
be reset to the default ones given that the currently
registered handlers are the ones that were registered
when the module was loaded.
The logic only works correctly if there are no concurrent
calls to `XSet{IO}ErrorHandler()` while `{set,restore}_x11_handlers()`
is running. Since module-x11-bell is probably mostly going to
be loaded in `pipewire-pulse`, this seems like a reasonable
assumption to make.
Add `pw_impl_module_schedule_destroy()` which will
schedule a call to `pw_impl_module_destroy()` on
the module's context's work queue.
For now, do not add it to the public impl-module.h header,
only private.h.
Many modules cannot load without a work queue,
neither links nor nodes can be created without it.
It's probably better to try to create it immediately
when the context is created. This elliminates the
need for checking whether `pw_context_get_work_queue`
succeeded or not.
`x11_close()` is no longer needed since X11 errors
are now considered fatal, so `module_destroy()` will
be called if `x11_connect()` fails, which means that
the code from `x11_close()` can be moved there.
Place the methods on the interface so that we can call them.
Rename create to init because that is what it does.
Add support for listener and events so that we can signal property
changes later.
Move all backends to dynamic libaries loaded with spa_plugin_loader so
new backends not needs changes in pipewire or pipewire dependency to
external code
Change-Id: I702ce047598d0c318d6dc6ac8248062a5c12f643
In some cases it is possible for `pw_context_conf_section_for_each()`
to not set `res` at all, which leads to an indeterminate value being returned.
Fix that by setting `res` to 0 initially.
module-combine-sink should become loaded only after its input stream,
and all explicitly specified output sink stream nodes appear. Since
output sinks may appear on the manager after a delay, wait for them only
up to a timeout, and fail load after that.
Fail load if there are errors in input stream, or in an explicitly
specified output.
This is needed for Zoom sound sharing to work. Pulseaudio additionally
fails the module load if streams fail to connect, but we do not do that
here at the moment.
Operations sync manager, so use that.
On Pulseaudio, module unload is async procedure. However, this race
condition may be hard to hit in practice, whereas on pipewire-pulse it's
not hard. E.g. Zoom appears to assume that modules are unloaded
synchronously.
Sync client's manager, before returning from module load, also for async
module loads. This is because the module load may have its own core, so
even though it has made changes on server, the client manager might not
see them yet.
Fix this by syncing client->manager before operation return.