For merger setup (consuming a source) we want to expose the channelmap
of the remixed signal (to the application/sink).
For splitter setup (providing data) we want to expose the channelmap
of the original source (before remixing to sink).
Hide the merge channel props because they contain the channelmap before
mising and we want to expose the remixed signal in merger mode.
This fixes some weird volume issues when an input stream is linked
to a source and is remixing, like when a stereo stream is captured
from a mono source.
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
Keep track of the format as given in the PortConfig.
Instead of blindly fixating the negotiated format to whatever default,
use the PortConfig format to fixate to something better.
This makes the channels/position, rate or format match the PortConfig
format when this is possible and results in the least amount of conversions.
It mostly improves the handling of wildcard formats, were a stream only
specifies some fields and leaves the other free.
A concrete case is WINE that uses the pulseaudio FIX flags to omit the
number of channels and rate. With this change, the stream will negotiate
to the format of the linked sink and obtain the channelmap from it.
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.
This reverts commit c474846c42.
In addition, `s->loop` is also checked before dispatching a source.
The destroy list is needed in the presence of threads. The
issue is that a source may be destroyed between `epoll_wait()`
returning and thread loop lock being acquired. If this
source is active, then a use-after-free will be triggered
when the thread loop acquires the lock and starts dispatching
the sources.
thread 1 thread 2
---------- ----------
loop_iterate
spa_loop_control_hook_before
// release lock
pw_thread_loop_lock
spa_system_pollfd_wait
// assume it returns with source A
pw_loop_destroy_source(..., A)
// frees storage of A
pw_thread_loop_unlock
spa_loop_control_hook_after
// acquire the lock
for (...) {
struct spa_source *s = ep[i].data;
s->rmask = ep[i].events;
// use-after-free if `s` refers to
// the previously freed `A`
Fixes#2147
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.
Older gcc versions seem to require the members to appear in the
designated initializer in the order they are in the definition of
the struct when compiling C++.
otherwise compilation fails with:
../spa/plugins/aec/aec-webrtc.cpp:167:1: sorry, unimplemented:
non-trivial designated initializers not supported
};
^