Use the timer queue for scheduling stream and object data timeouts.
This avoids allocating timerfds for these timeouts and the timer queue
can handle many timeouts more efficiently.
If we don't get a link on a stream, we might never send a create stream
reply. The client handles this fine by timing out after 30s and dropping
the stream, but the server holds on to the pw_stream forever (or until
the client quits).
Let's add a timer to clean up such streams on the server.
Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4901
Only send out SUSPENDED event when there is a change in the suspended
state. This avoids sending out unsuspend events when we simply uncork.
Implement the fail_on_suspend flag for capture and playback streams.
Instead of suspending those streams, we need to kill them.
When we simply need to change some state for the code executed in the
loop, we can use locked() instead of invoke(). This is more efficient
and avoids some context switches in the normal case.
Set the corked state on streams so that we can use this in sink-input
and source-output info without guessing.
The problem is that when a stream starts un-corked, the state is less
than RUNNING and so before this patch, pulse-server reports a corked
stream, which is not what pulseaudio reports.
When a client is not sending any data when it should be and causes an
underrun, mark it as idle and record the timestamp.
When a client is idle for pulse.idle.timeout seconds, set the stream
as inactive. When more data is received, set it back to active.
Add a pulse.idle.timeout option to set a global server default or
a per-stream value. Set the server default to 5 seconds. A value of 0
can be used to disable this feature.
With this change, badly behaving clients that are not sending any data
will be paused so that the sinks can suspend to save battery power.
Fixes#2839
Make a method to pause and resume a stream and keep track of the paused
state of the stream. Use this function instead of setting the stream
inactive/active so that we get nice logging for each state change.
A client can sometimes send more data than we requested. PulseAudio
keeps the extra data around, it just asks for more data when it consumed
some of it.
PipeWire however always tries to keep tlength worth of data, as
specified in the PulseAudio docs... Keep track of how much extra data
has been sent and keep this around as well. Make sure we flush this
extra data as well.
Fixes#2626
Based on patch from Barnabás Pőcze <pobrn@protonmail.com>
Instead of trying to keep track of the missing bytes ourselves, use the
simple tlength - avail - requested formula to request more bytes from
the client.
Fixes#1981
Only call `spa_list_remove()` in `stream_free()` if the
stream is pending. `spa_list_remove()` does not reinitialize
the list node, therefore calling `spa_list_remove()` again
after the stream has been removed from the pending list
will corrupt the pending list of the client.
Always reevaluate the tlength or total buffered samples when the
quantum changes, even for the first sample because it is possible that
we completely miscalculated the length when we started, like when the
quantum is force high and the requested latency is low.
Also only increase the calculated tlength, for smaller sizes we don't
need to do anything, we can keep the latency as is it.
See #1930
Keep track of the current quantum and recalculate the tlength in the
same way that pulseaudio does.
Send a bufferattr changed message to a client when we change the
parameters.
This fixes the case where the quantum is increased and there needs to be
more buffering to keep the stream going.
When the client adapter is configured in passthrough mode, the stream param
changed event in pipewire-pulse is emitted before the session manager creates
the link, and not after. Therfore, the peer can never be found when replying
create stream, and the pulseaudio application receives a stream error.
This patch delays the create stream reply until the link is added if the peer
cannot be found, fixing the above race conditon to allow passthrough mode to
work with pulseaudio applications.
If a log message is rate limited, we only need to know about it if we
are actually interested in that log level. We therefore add an argument
to the ratelimit_test function to set the log level of the message
printed if a message is skipped
Change-Id: I5ccd4a78bf7e972fe8b0e7133cd7e08c1e38835f