update_delay is called primarily when the stream format or latency changes,
and from playback thread, if stream reports different delay as before.
This function calculates the number of compensate samples for each stream
based on the latencies of other streams (which must be in a streaming state).
During the first playback on a new format, update_delay is called multiple times
due to format or latency changes. The delay is calculated only from streams
that are currently streaming. If some streams are not yet streaming, their
latencies are ignored, and the delay is updated later in the processing
thread. The processing thread also stores the stream delay in a local variable
(accessed only from that thread, thus requiring no locking).
On a subsequent playback using the same format, update_delay is still called a
few times, and the delay is updated based on the currently streaming streams.
If some streams are not streaming, their latencies are ignored.
However, this time, the processing thread fails to update the delay for the
previously non-streaming streams. Because the format didn't change, the streams
delay matches the last stored delay from the previous playback. As a
result, the compensate samples are not recalculated.
To properly update the compensate samples, update_delay must also be called
when a stream's state changes to streaming (avoiding the need to clear the
thread-buffered value, which would require locking in the processing
thread).
In multiple cases the `flags` member of `spa_dict` is left unitialized,
so try to avoid that. For example in `fill_node_info_proplist()` it is
accessed in `spa_dict_lookup_item()`.
This also modifies `collect_props()` to not depend on a partially initialized
`dict` parameter.
Commit b1b565339 ("sendspin: negotiate the first raw format") says that
FLAC and Opus are not supported yet. The receiver also only advertises
PCM formats in its player support.
Reject non-PCM stream/start codecs in the receiver. Otherwise
parse_player() accepts FLAC or Opus without setting client->stride,
while the receive path later uses client->stride as a raw frame size.
Signed-off-by: Wang Yu <wangyu@uniontech.com>
Because our midi messages already have a size, we don't need the 0xf0
continuation terminator. Also having the terminator optionally requires
you to check and strip it if it's there.
The easiest algorithm is to check the first byte for start (0xf0) or
continuation (0xf7) and the last byte for end (0xf7) and that should be
enough to process the messages without having to ever stip the last
byte.
Bring the port to INIT before going to CONFIGURE when we do the suspend
logic.
This is to ensure that there always is a state change to emit the state
change notification. This was, the link can detect the suspend case and
cancel any pending results.
One of the problem with suspend is that the state changes on the ports
are done from different places; the port and link. This causes issues
like:
1. do_negotiate calls pw_port_set_param(Format,..) with the negotiated
format. This returns async and the link queues a complete_ready
callback.
2. The node is suspended, pw_impl_port_set_param(Format, NULL) is called
to clear the port format. This bypasses the link.
3. The reply from step 2 arrives and triggers complete_ready, this
brings the port state to READY and the link state to ALLOCATING.
4. The link continues allocating and sets buffers on the port. This then
fails because the last format set was NULL.
Ideally all port states should be managed in one place and the async
port state changes should be kept in the port itself as well but this
will need some more work.
Fixes#3547
Thse should not be portal clients and can go directly to rtkit.
The reason is that there is a locking problem in the portal rt
implementation that cause timeouts for some reason.
Retrieve the connecting client's supplementary group list via
SO_PEERGROUPS and store it as the "pipewire.sec.gids" property.
This allows access-control policies in wireplumber to match on
all groups and not just the primary.