Most feature checks already use #ifdef, and do not care about
the value of the macro. Convert all feature checks to do that,
and simplify the meson build scripts by replacing
if cond
cdata.set('X', 1)
endif
with
cdata.set('X', cond)
When the pulse server context is being freed, only a single reference
should be alive to each sample because the pending samples
are all destroyed beforehand.
Clean everything up when the context is destroyed to avoid
problems stemming from the destruction order of objects
in the context.
Furthermore, free messages after all clients have been freed
because `client_free()` may very well call `message_free()`
which would lead to memory leaks if `impl->free_messages` were
processed first.
A stream's lifetime is tied to that of the client, it cannot outlive
the client object. Streams also do not increase the client's reference
count. It is not possible for a stream to exist after the corresponding
client has been destroyed.
Hence it is not necessary to manage the client's reference count
or lifetime in `do_destroy_stream()`. All works related to a particular
stream are cancelled in `stream_free()`, which is called
before the client is destroyed.
When the `done` flag was first added in
9f9be7d7f2, it was
actually needed because cleanup was implemented
using a per-client eventfd which was signalled when
something related to the particular client needed
to be freed. The function that ran, then, checked
each stream's `done` flag, and freed them as necessary.
However, since c70a5de526,
the stream cleanup is done using a work queue, and as
a consequence, the `done` flag is no longer needed.
When the `disconnecting` flag was first added in
d44fdabea1, a client's
streams were not explicitly destroyed when it was freed,
instead, only the client's pw_core was disconnected,
which then caused all related streams to be destroyed.
Thus there needed to be a way to determine why the stream's
state changed to PW_STREAM_STATE_UNCONNECTED as it may have
been because the client is disconnecting or because the
stream has been "killed" in some other way.
The `COMMAND_{PLAYBACK,RECORD}_STREAM_KILLED` command
only needed to be sent to the client in the second case.
However, at the moment, all streams of a client are explicitly
destroyed before it's pw_core is disconnected. This makes the
`disconnecting` flag unnecessary, thus it can be removed.
Move the reference counting from `pending_sample_free()`
into `on_sample_done()` so that the client's references
are managed in a single place.
The reason why `pending_sample_free()` cannot simply call
`client_unref()` is that `client_free()` may be called from
`manager_disconnect()` regardless of the reference count,
and, in turn, `pending_sample_free()` may be called,
which could then lead to a recursive call to `client_free()`.
We should always advance the read pointer when we are underrun and
not corked. This will request more bytes from the client to make
things advance.
Fixes#2041
Use the lower 32 bits of the object serial as the index. When there is
an overflow, use an invalid index, which will probably result in a
protocol error.
Don't use max_quantum as the upper quantum limit, this is now scaled
with the rate. Use quantum_limit instead. We don't really care about the
max_quantum anymore so get rid of the field.
Parse the quantum_limit parameters and use this to scale the buffers so
that they can contain the maximum allowed samples instead of the
hardcoded 8192 value.
See #1931
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
Make the alignment parameter optional when negotiating buffers.
Default to a 16 bytes alignment and adjust for the max cpu
alignment.
Remove the useless align buffer parameter in plugins, we always
set it to 16 anyway.
For example, pulseaudio.js[1] immediately sends a
GET_SERVER_INFO request after AUTH, and only later
issues a SET_CLIENT_NAME.
See #1966.
[1]: https://github.com/janakj/pulseaudio.js
By default require that a client is authenticated and
has a manager to be allowed to run a command.
Specially:
* AUTH requires nothing
* SET_CLIENT_NAME and STAT only require authentication
Previously, when a sample is "committed" from an upload stream,
its reference count is set to 1. This is problematic if,
when the sample is committed for a second time, there are
streams playing the sample as the reference count will go out
of sync.
The problem can be easily triggered, especially with longer samples:
pactl upload-sample a-long-sample.ogg
pactl play-sample a-long-sample
pactl play-sample a-long-sample
pactl upload-sample a-long-sample.ogg # while playing
When the first stream finishes playing, it will free the sample,
which can cause problems e.g. for the second stream playing the
sample at that very moment.
Fix that by decoupling the buffer from the sample and making
the buffer reference counted. And remove the reference counting
from the samples as it is no longer needed.
Futhermore, previously, the reference counts were ignored
when the removal of a sample was requested. That is fixed
as well.
The previous issue can be triggered easily as well:
pactl upload-sample a-long-sample.ogg
pactl play-sample a-long-sample
pactl remove-sample a-long-sample # while playing
Fixes#1953
Create a new event for modules ('destroy') which is emitted from
`module_free()`. It is used by the module loading logic, to handle
when a module is destroyed without properly loading first.
Store the modules whose load has been initiated by a particular
client in the `pending_modules` list of the client. When the
client disconnects, "detach" the client from the pending module
objects. This way the reference count need not be increased
for asynchronous module loads.
Furthermore, if the module can load synchronously, do not create
the pending module object at all.
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.
When we can't fill a complete block, report the amount of data that we
used in missing/played instead of the complete missing part.
Fixes audio breaking up when looping in mpv.
Fixes#1132
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
When we are draining or underrunning, read whatever we have in the
ringbuffer instead of silence. This places the last samples before
the drain into the sink, padded with 0.
Fixes#1549
When we have a fix_* flag set, make an extra format description with the
wildcards. This makes it possible for the session manager to fall back
to something when selecting a target and format.
Also only advertize the valid pulseaudio formats for the wildcards.
Fixes#1912