They are emited from the streaming thread and therefore can be emitted
concurrently with the events on the main thread. This can cause crashes
when the hook list is iterated.
Instead, make those events into callbacks that are more efficient,
and threadsafe.
Add a control.ump port property. When true, the port wants UMP and the
mixer will convert to it. When false, the port supports both UMP and
Midi1 and no conversions will happen. When unset, the mixer will always
convert UMP to midi1.
Remove the CONTROL_types property from the filter. This causes problems
because this is the format negotiated with peers, which might not
support the types but can still be linked because the mixer will
convert.
The control.ump port property is supposed to be a temporary fix until we
can negotiate the mixer ports properly with the CONTROL_types.
Remove UMP handling from bluetooth midi, just use the raw Midi1 events
now that the mixer will give those and we are supposed to output our
unconverted format.
Fix midi events in-place in netjack because we can.
Update docs and pw-mididump to note that we are back to midi1 as the
default format.
With this, most of the midi<->UMP conversion should be gone again and we
should be able to avoid conversion problems in ALSA and PipeWire.
Fixes#5183
Since abf37dbdde the param enumeration in
the client-node can return 0 when the parameter is supported but there
are no params uploaded.
When negotiating buffers we need to assume a 0 result as a NULL filter
as well or else we will error.
Avoid doing conversions in the nodes between Midi formats, just assume
the imput is what we expect and output what we naturally produce.
For ALSA this means we produce and consume Midi1 or Midi2 depending on the
configurtation.
All of the other modules (ffado, RTP, netjack and VBAN) really only
produce and consume MIDI1.
Set the default MIDI format to MIDI1 in ALSA.
Whith this change, almost everything now produces and consumes MIDI1
again (previously the buffer format was forced to MIDI2).
The problem is that MIDI2 to and from MIDI1 conversion has problems in
some cases in PipeWire and ALSA and breaks compatibility with some
hardware.
The idea is to let elements produce their prefered format and that the
control mixer also negotiates and converts to the node prefered format.
There is then a mix of MIDI2 and MIDI1 on ports but with the control
port adapting, this should not be a problem.
There is one remaining problem to make this work, the port format is
taken from the node port and not the mixer port, which would then expose
the prefered format on the port and force negotiation to it with the
peer instead of in the mixer.
See #5183
Previously, if a remote node was set to running and immediately reverted
to suspended state, the remote node stayed in running state. This occurred
because suspend_node sent suspend command only when the locally cached
state was "idle" or "running."
Modified to send suspend to a node whenever its pending state is not
"suspended," ensuring the command is sent during state transitions.
Fixes#5026
Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
When the driver changes, the clock position can also change and there
would be a discont in the rtp_timestamp.
This is not usually a problem except in RAOP mode where the base rtp
timestamp is negotiated and anything that deviates too much is to be
discarded.
If we are not using direct_timestamp for the sender, make sure we always
keep the rtp_time aligned to avoid this problem.
See #5167
Going from PLAYING to PAUSED will have basesrc calling unlock and
setting flushing to false. Going back to PLAYING may then fail in
wait_negotiated, as unlock_stop will be called after change_state.
Fix by remove the flushing check, since already in that "state".
This fixes a missing definition error in thread.c:
../src/pipewire/thread.c:129:30: error: use of undeclared identifier 'SCHED_RESET_ON_FORK'
129 | SPA_FLAG_UPDATE(new_policy, SCHED_RESET_ON_FORK, reset_on_fork);
As stated in https://pubs.opengroup.org/onlinepubs/9799919799//basedefs/netinet_in.h.html,
> The <netinet/in.h> header shall define the sockaddr_in structure [...]
This fixes the following build error:
In file included from ../src/modules/module-protocol-native.c:44:
../src/modules/network-utils.h:96:35: error: incomplete definition of type 'struct sockaddr_in'
96 | if (inet_ntop(sa->ss_family, &in->sin_addr, ip, len) == NULL)
| ~~^
NULL tags are never handled and so tags just keeps configured on the
ports. It's also hard to know the direction from the NULL data.
Instead, send an empty Tag with the direction to clear everything.
Don't close an -1 fd in clear_data.
If we let the client allocate buffer, set our fd and data to invalid
values. If the client decides to renegotiate before we get the buffer
data we might otherwise try to clear the mem_id (default 0) or
close the fd (also default 0).
Fixes#5162
If a file descriptor is expected to be closed by the associated `pw_memblock`,
and closing fails, then that usually signals a more serious issue in the memory
accounting. So add a log message when that happens.
Previously when parameters were enumarated, it was checked if at least one
param was known for `id`. If not, `-ENOENT` was returned to signal that
this param id is not supported.
This is not necessarily true, since a param id might be supported, but it
might have zero params at the moment, in which case an unexpected error
would be returned.
Fix that by using `pw_param_info_find()` with the underlying impl object
to check if the param id is actually supported.
If the param enumeration fails, do not set `spa_param_info::user` to 1
indicating that the result is cached. Doing so can lead to the first
(uncached) call failing, while the rest will succeed (with 0 params).
We can only use non-shared memory when both nodes live in the same
process _and_ we can be sure the output port is never going to be linked
to a remote node because it is exclusive.
This fixes the case where a null-sink is loaded inside the process space
of the server and linked to the ALSA sink. This would create a link
without shared mem and then as soon as something else (out of process)
wants to link to the null-sink output, it would get a -22 EINVAL
negotiation error because the memory can't be shared.
Fixes#5159
We keep a mapping between the sndfile formats and the format we would
like to decode them to for encoded formats. Make sure we don't mix up
the sample widths between them.
Make sure we don't send encoded formats as raw.
Debug the uncompressed format name correctly.
Fixes#5155
Add a port.passive = follow mode and the node.passive equivalents
out-follow, in-follow, follow.
This makes it possible to control how a port influences the state of
the peer and how the peer influences the state of the node independently.
In passive mode, the port will not make the peer runnable and will also
not become runnable when the peer activates.
In the follow mode, the port will not make the peer runnable but it will
become runnable when the peer is active.
This makes it possible to do new things like (f for follow):
Source -> (f)loopback1-in|loopback1-out(f) -> Sink
It will not make the source and sink run but when one of them start, all
will become runnable.
Or you can now better do the leak node hack that was previously used:
Source -> (f)pw-record
That will only start running when the source is activated by something
else.
With port.passive = true|false|follow there is a potential 4th case
which would activate the peer but not be activated by the peer, which is
not something that makes sense.
This was a hack around some scheduler issues that we should be able to
handle better now.
One of the cases is:
Source -> (p)pw-record
Which would never work otherwise because pw-record does not activate the
Source and when the Source is activated in any other way, pw-record
would not follow.
This will still fail with the current scheduler, but the leaf check is
not so great because it doesn't work in this case:
Source -> (p)loopback-in|loopback-out(p) -> Sink
What is probably required is a passive mode that doesn't activate but
does follows the peer.
Sink/Source pairs should not have the same link-group otherwise the
session manager will not be able to autoconnect them with a loopback or
some other internally linked stream.
Setting the current clock time when resending buffers is often wrong.
Especially for pseudo-live sources - the default mode - it discards
the original buffer time, which again is used by the base-class to
adjust the timestamps further, ultimately resulting in very wrong
timestamps.
Instead, try to calculate the delta between when we originally got the
buffer and now.
Buffer timestamps get adjusted by the base class, GstBaseSrc, even if we
take an additional ref. Arguably the base class should check if buffers
are writable (gst_buffer_make_writable()), which would trigger a buffer
copy. That is currently not the case, though, thus do so on our side.
Notes:
1. Usually a buffer copy doesn't copy the underlying memory, i.e.
copying is cheap.
2. The copy holds a reference to the copied buffer, preventing the
buffer from getting recycled as before.
We used to skip the runnable state from driver nodes because we assume
that they will be activated from other nodes. We however need to make
this more general to all suspendable nodes.
This makes pw-play -> loopback1-sink loopback1-out -> loopback2-sink
loopback-out -> sink also work correctly because the loopback2-sink does
not activate loopback1-out then.