the comment /* Fall through. */ fixes the warning, but gcc-7 seems to be more
picky about the position in the code
pulsecore/sink-input.c: In function ‘pa_sink_input_update_proplist’:
pulsecore/sink-input.c:1531:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
for (state = NULL; (key = pa_proplist_iterate(i->proplist, &state));) {
^~~
pulsecore/sink-input.c:1539:9: note: here
case PA_UPDATE_REPLACE: {
^~~~
Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
EAGAIN is used allover the code rather than EWOULDBLOCK
POSIX allows EAGAIN and EWOULDBLOCK to have the same value (and in fact it is)
don't check for EWOULDBLOCK
modules/raop/raop-client.c: In function ‘send_udp_audio_packet’:
modules/raop/raop-client.c:473:41: warning: logical ‘or’ of equal expressions [-Wlogical-op]
if (written < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
^~
modules/raop/raop-client.c: In function ‘resend_udp_audio_packets’:
modules/raop/raop-client.c:528:45: warning: logical ‘or’ of equal expressions [-Wlogical-op]
if (written < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
^~
Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Under MinGW, LC_MESSAGES is defined in libint.h which is not
included when pulseaudio is configured with nls disabled.
LC_MESSAGES is referenced when setting PA_PROP_APPLICATION_LANGUAGE.
This patch just disables setting that property when ENABLE_NLS
is not defined.
It seems that the intention was to create create write_thread_event on
thread_mainloop instead of main_mainloop (the first parameter of
io_new() is thread_mainloop, io_free() is called on thread_mainloop
etc.).
As long as both mainloops are implemented with pa_mainloop, this bug has
no effect on behaviour, because the io_new() implementation is the same.
And indeed, with the current code base both mainloops are always
pa_mainloops. However, when the tunnel-new modules switches to pa_rtpoll
as the pa_mainloop_api provider, this bug would cause problems.
We're supposed to prioritize USB sound cards over PCI sound cards, but
the priority bonus for the "internal" form factor prevents this from
happening. Not all (if any) USB sound cards have the form factor
property set, whereas at least on my laptop the on-board sound card has
the form factor set to "internal".
The order of the pa_sink_input_put() and pa_sink_put() calls in filter
modules was swapped in commit edc465da77 ("virtual sources and sinks:
Don't double attach a sink input or source output on filter load").
If flat volumes and volume sharing is enabled, the pa_sink_input_put()
call will update volumes of the whole tree of virtual sinks that are
connected to the root sink. The recursive updating procedure tried to
also update the volume of the new sink for which pa_sink_put() had not
yet been called, causing an assertion failure.
This patch tries to make sure that the volume of not-yet-linked sinks
is never changed. pa_sink_put() will set the sink volume correctly, so
it's fine to skip the not-yet-linked sinks during pa_sink_input_put().
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=102549
A race condition prevents the AES non-audio bit from being set
when enabling IEC61937 passthrough on resume with no sink-input
connected (pa_sink_is_passthrough returns false). The non-audio
bit should really be set when opening the sink.
Force the sink to suspend/resume when actually entering passthrough
mode, and likewise force a suspend-resume on leaving passthrough mode.
Tested with E-AC3 streams which do need the AES bit set for my
Onkyon receiver to detect the format instead of playing it as
PCM.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Some modules may only be loaded once, and trying to load them
twice from default.pa makes PulseAudio startup fail. While that could
be considered a user error, it's nicer to not be so strict. It's not
necessarily easy to figure what went wrong, if for example the user
plays with RAOP and adds module-raop-discover to default.pa, which first
works fine, but suddenly stops working when the user at some point
enables RAOP support in paprefs. Enabling RAOP in paprefs makes
module-gconf load the module too, so the module gets loaded twice.
This patch adds a way to differentiate module load errors, and
make cli-command ignore the error when the module is already
loaded.
Users may want to change the parameters of some load-once modules in
~/.config/pulse/default.pa. That should be possible by including
/etc/pulse/default.pa from the per-user configuration file, and then
unloading a module and reloading it with different parameters. However,
that doesn't work, because the unload-module command will not unload the
module immediately, so the subsequent load-module command will fail when
the module can be loaded only once.
This patch makes the module unloading synchronous. "pacmd unload-module
module-cli-protocol-unix" is something that might not like this change,
since the command will unload the code that is processing the command,
but I tested it and it works fine. When pa_module_unload() is called,
that won't yet remove the module code from memory, the lt_dlclose() call
is postponed until it's safe to remove the code from memory.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=102205
module-switch-on-port-available didn't do anything when a port changes
its status if the card didn't have any sinks or sources. This was to
avoid bad things during card initialization, but the if condition also
prevented any profile switches away from the "off" profile, because the
card has no sinks or sources when the "off" profile is active.
pa_card nowadays has the "linked" flag that
module-switch-on-port-available could have checked instead, but since it
doesn't make sense to emit port status change events before the card has
been initialized, I added the check in pa_device_port_set_available()
instead.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=101794
Sources should probably be added to pa_core.sources in pa_source_put(),
but currently they're added in pa_source_new(). A lot of stuff can
happen between the pa_source_new() and pa_source_put() calls, and
it has happened that the default source was updated during this time.
Therefore, pa_core_update_default_source() needs to take it into account
that not every source is necessarily linked.
PA builds fine on MinGW except for the use of the scandir function in
pulsecore/conf-parser.c, so I provided a Win32 implementation. With this
patch the latest code builds on Win32 without problems.
The on_the_fly_snapshot variable contains the amount of bytes that has
been sent from the source IO thread to the main thread, but not yet
pushed to the stream memblockq. The data is in the stream format, but
the bytes-to-usec conversion used the source format, which caused random
latency reporting errors.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=81075
This allows us to restore the default device properly when a
hotpluggable device (e.g. a USB sound card) is set as the default, but
unplugged temporarily. Previously we would forget that the unplugged
device was ever set as the default, because we had to set
configured_default_sink to NULL to avoid having a stale pa_sink pointer,
and also because module-default-device-restore couldn't resolve the name
of a currently-unplugged device to a pa_sink pointer.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=89934
When a filter sink is moving, it's not connected to any master sink, and
therefore it's not connected to any IO thread either. In this situation
trying to move a stream that is connected to the filter sink is likely
to result in crashing, because starting the move involves sending a
message to the IO thread. Sometimes this works by accident (the
asyncmsgq of the filter sink still points to the old master sink's
asyncmsgq), but we really should never attempt it. This patch blocks all
moves where the moving stream is connected to a filter sink that itself
is in the middle of a move.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100277
In sink_put() and source_put(), pa_core_update_default_{sink,source}() was called
before the PA_CORE_HOOK_{SINK,SOURCE}_PUT hook. Therefore module-switch-on-connect
could not correctly determine the old default sink/source if no user default was
set and a sink/source with higher priority than any other sink/source turned up.
This patch corrects the problem by swapping the order of the hook call and the
pa_core_update_default_sink() call.
Additionally it corrects a problem in module-switch-on-connect. If, after the
change above, the new sink/source was the first sink/source to appear, pulseaudio
would crash because module-switch-on-connect assumed that the default sink/source
was not NULL. The patch checks if the default sink/source is NULL and only sets
the new default sink/source in that case.
When sinks are compared during the default sink selection, the active
port's availability is inspected. Therefore, the default sink should be
updated when the active port changes, because the new port may have
different availability status than the old port.
For example, let's say that a laptop has an analog sink with a speaker
and a headphone port, and headphones are initially plugged in, so both
ports can be used[1]. The headphone port is initially the active port.
There's also a null sink in the system. When the headphones are
unplugged, the headphone port becomes unavailable, and the null sink
becomes the new default sink. Then module-switch-on-port-available
changes the analog sink port to speakers. Now the default sink should
change back to the analog sink, but that doesn't happen without this
patch.
[1] Actually we currently mark speakers as unavailable when headphones
are plugged in, but that's not strictly necessary. My example relies on
both ports being available initially, so the bug can't be reproduced
with the current mixer configuration.
It doesn't make sense to use a sink or source whose active port is
unavailable, so let's take this into account when choosing the default
sink and source.
Currently the default sink policy is simple: either the user has
configured it explicitly, in which case we always use that as the
default, or we pick the sink with the highest priority. The sink
priorities are currently static, so there's no need to worry about
updating the default sink when sink priorities change.
I intend to make things a bit more complex: if the active port of a sink
is unavailable, the sink should not be the default sink, and I also want
to make sink priorities dependent on the active port, so changing the
port should cause re-evaluation of which sink to choose as the default.
Currently the default sink choice is done only when someone calls
pa_namereg_get_default_sink(), and change notifications are only sent
when a sink is created or destroyed. That makes it hard to add new rules
to the default sink selection policy.
This patch moves the default sink selection to
pa_core_update_default_sink(), which is called whenever something
happens that can affect the default sink choice. That function needs to
know the previous choice in order to send change notifications as
appropriate, but previously pa_core.default_sink was only set when the
user had configured it explicitly. Now pa_core.default_sink is always
set (unless there are no sinks at all), so pa_core_update_default_sink()
can use that to get the previous choice. The user configuration is saved
in a new variable, pa_core.configured_default_sink.
pa_namereg_get_default_sink() is now unnecessary, because
pa_core.default_sink can be used directly to get the
currently-considered-best sink. pa_namereg_set_default_sink() is
replaced by pa_core_set_configured_default_sink().
I haven't confirmed it, but I expect that this patch will fix problems
in the D-Bus protocol related to default sink handling. The D-Bus
protocol used to get confused when the current default sink gets
removed. It would incorrectly think that if there's no explicitly
configured default sink, then there's no default sink at all. Even
worse, when the D-Bus thinks that there's no default sink, it concludes
that there are no sinks at all, which made it impossible to configure
the default sink via the D-Bus interface. Now that pa_core.default_sink
is always set, except when there really aren't any sinks, the D-Bus
protocol should behave correctly.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=99425
In pa_{source,sink}_new() and pa_{source,sink}_put() the current hardware
volume was miscalculated:
hw volume (dB) = real volume (dB) + soft volume (dB)
was used instead of
hw volume (dB) = real volume (dB) - soft volume (dB)
This lead to a crash in pa_alsa_path_set_volume() if high volumes were
set and the port was changed.
This patch fixes the calculation. Thanks to Tanu for pointing out
the correct solution.
Bug link: https://bugs.freedesktop.org/show_bug.cgi?id=65520
The 'portable' form factor was currently missing meaning it is not
getting any form-factor priority at all and it would therefore always
be ranked lower then internal devices (which receive 400 form factor
priority). The priority 450 is smaller then 'speaker', based on the
idea that a portable device might have less quality then a dedicated
'speaker' device (some Yamaha amplifiers announce themselves as such).
https://bugs.freedesktop.org/show_bug.cgi?id=100579
The reported latency of source or sink is based on measured initial conditions.
If the conditions contain an error, the estimated latency values may become negative.
This does not indicate that the latency is indeed negative but can be considered
merely an offset error. The current get_latency_in_thread() calls and the
implementations of the PA_{SINK,SOURCE}_MESSAGE_GET_LATENCY messages truncate negative
latencies because they do not make sense from a physical point of view. In fact,
the values are truncated twice, once in the message handler and a second time in
the pa_{source,sink}_get_latency_within_thread() call itself.
This leads to two problems for the latency controller within module-loopback:
- Truncating leads to discontinuities in the latency reports which then trigger
unwanted end to end latency corrections.
- If a large negative port latency offsets is set, the reported latency is always 0,
making it impossible to control the end to end latency at all.
This patch is a pre-condition for solving these problems.
It adds a new flag to pa_{sink,source}_get_latency_within_thread() to allow
negative return values. Truncating is also removed in all implementations of the
PA_{SINK,SOURCE}_MESSAGE_GET_LATENCY message handlers. The allow_negative flag
is set to false for all calls of pa_{sink,source}_get_latency_within_thread()
except when used within PA_{SINK,SOURCE}_MESSAGE_GET_LATENCY. This means that the
original behavior is not altered in most cases. Only if a positive latency offset
is set and the message returns a negative value, the reported latency is smaller
because the values are not truncated twice.
Additionally let PA_SOURCE_MESSAGE_GET_LATENCY return -pa_sink_get_latency_within_thread()
for monitor sources because the source gets the data before it is played.
During a move sink_input->sink is not valid. This leads to a crash when
sink_input_set_rate() is called from the moving() callback. This patch
fixes the problem.
The previous patch assumed constant port latency offsets. The offsets can
however be changed by the user, therefore these changes need to be tracked
as well. This patch adds the necessary hooks.
Also the print_msg argument was removed from update_minimum_latency() and
update_latency_boundaries() because the message should always be logged.
The old code makes no sense to me. Why would multiple references mean
that a previously read-only memblock is suddenly writable? I'm pretty
sure that the original intention was to treat multi-referenced blocks
as read-only. I don't have any examples where the old code would have
caused bad behaviour, however.
Currently internal > speaker > headphone and pci > usb > bluetooth.
Invert both of these sets, with the reasoning that a headphone and
speakers are something that a user has actively attached and should
therefore get a higher priority. The same reasoning is applied for
the bus type, i.e. bluetooth and usb should be higher than pci,
because they most likely have been actively attached be a user.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=99222
If pa_sink_input_cork() or pa_source_output_cork() were called without a sink
or source attached, the calls would crash pulseaudio.
This patch fixes the problem, so that a source output or sink input can still
be corked or uncorked while source or sink are invalid. This is needed to
correct the corking logic in module-loopback.
document behaviour of pa_shared_remove() in case name does not exist
Coverity ID: #1380672
thanks to Georg Chini for suggesting to swap patch title and commit message
Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
for example, in case HAVE_MEMFD is #undef, checking with #if HAVE_MEMFD
gives a warning (gcc 5.4.1, Ubuntu)
pulsecore/shm.c: In function 'sharedmem_create':
pulsecore/shm.c:208:5: warning: "HAVE_MEMFD" is not defined [-Wundef]
#if HAVE_MEMFD
use #ifdef or #if defined() to check for presence of a #define
Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Clang didn't like the variable length array:
pulsecore/iochannel.c:358:17: error: fields must have a constant size:
'variable length array in structure' extension will never be supported
uint8_t data[CMSG_SPACE(sizeof(int) * nfd)];
^
Commit 451d1d6762 introduced the variable length array in order to have
the correct value in msg_controllen. This patch reverts that commit and
uses a different way to achieve the same goal.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=99458
the modeling file help to avoid false positives and increase scanning
accuracy by explaining code Coverity can't see (out of tree libraries);
the model file must be uploaded by an admin to:
https://scan.coverity.com/projects/pulseaudio?tab=analysis_settings
the pa_assert_se() macro needs to be rewritten for Coverity so that
the assignment is not declared a side-effect
Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
This serves to explicitly document the various cases we deal with in
pa_sink_update_rate()/pa_source_update_rate() rather than have some of
them hidden behind the initialisation of desired_rate.
This adds an "avoid-resampling" option to daemon.conf that makes the
daemon try to use the stream sample rate if possible (the device needs
to support it, which currently only ALSA does), and there should not be
any other stream connected).
This should enable some of the "audiophile" use-cases where users wish
to play high sample rate audio files without resampling.
We still will do conversion if sample formats don't match, though. This
means that if you want to play 96 kHz/24 bit audio without any
modification the default format will need to be set to be 24-bit as
well. This will force all streams to be upconverted, which, other than
the wasted resources, should be relatively harmless.
This macro compares if the given two strings, with the maximum length
of n, are equal. Useful for strings that are not NULL-terminated.
Reviewed-by: Anton Lundin <glance@acc.umu.se>
pa_socket_client_new_string() did not work as expected when an IPv6
address string like "2001:db8::1" is passed as the "name" parameter.
This is because the name parameter is then passed to pa_parse_address(),
which thinks the last colon as a separator between hostname (or address)
and a port number. To prevent pa_parse_address() from doing this, an IPv6
address must be bracketed with "[]" (e.g. "[2001:db8::1]"). [1]
This patch fixes pa_socket_client_new_string() so that it internally
adds brackets to an IPv6 address. This decision is based on a
discussion at [2].
[1]: http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-October/022010.html
[2]: http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-November/022401.html
Reviewed-by: Anton Lundin <glance@acc.umu.se>
The function isn't used anywhere else than memblockq-test. Also, the
function is confusing, because it defines "missing" differently than
pa_memblockq_pop_missing(). pa_memblockq_missing() calculated the
missing amount like this:
missing = tlength - length,
where "length" is the current queue length. pa_memblockq_pop_missing(),
on the other hand, calculates the missing amount like this:
missing = tlength - length - requested,
where "requested" is an internal variable that keeps track of how much
the server has requested data from the client and how much of the
requests are yet to be fulfilled by the client.
memblockq-test is broken at the moment, because it assumes that
pa_memblockq_pop_missing() calculates "missing" the same way that
pa_memblockq_missing() used to calculate it. A patch for fixing that
will follow.
This reverts commit 74251f0786.
The reverted commit was not intended to make any behavioral changes, but
it broke at least the case where a client writes more data than the
server has requested.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=99211
Streams are detached when they are removed or moved away from a device,
or when a filter device that they're connected to is removed or moved.
If these cases overlap, a crash will happen due to "double-detaching".
This can happen if a filter sink is removed, and a stream connected to
that filter sink removes itself when its sink goes away.
Here are the steps in more detail: When a filter sink is unloaded, first
it will unlink its own sink input. This will cause the filter sink's
input to be detached. The filter sink propagates the detachment to all
inputs connected to it using pa_sink_detach_within_thread(). After the
filter sink is done unlinking its own sink input, it will unlink the
sink. This will cause at least module-combine-sink to remove its sink
input if it had one connected to the removed filter sink. When the
combine sink removes its sink input, that input will get detached again,
and a crash follows.
We can relax the assertions a bit, and skip the detach() call if the
sink input is already detached.
I think a better fix would be to unlink the sink before the sink input
when unloading a filter sink - that way we could avoid the
double-detaching - but that would be a much more complicated change. I
decided to go with this simple fix for now.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=98617