po/POTFILES.in | 1 src/.gitignore | 1 src/Makefile.am | 18 + src/modules/alsa/alsa-sink.c | 9 src/modules/alsa/alsa-source.c | 9 src/modules/alsa/module-alsa-card.c | 8 src/modules/module-allow-passthrough.c | 312 +++++++++++++++++++++++++++++++++ src/modules/module-ladspa-sink.c | 5 src/pulse/context.c | 14 - src/pulse/internal.h | 6 src/pulsecore/atomic.h | 2 src/pulsecore/core-util.c | 1 src/pulsecore/core-util.h | 4 src/pulsecore/protocol-native.c | 10 - src/pulsecore/pstream.c | 4 src/pulsecore/sink-input.c | 6 src/pulsecore/sink.c | 6 src/pulsecore/source-output.c | 7 src/pulsecore/source.c | 6 src/tests/core-util-test.c | 282 +++++++++++++++++++++++++++++ src/utils/qpaeq | 8 21 files changed, 682 insertions(+), 37 deletions(-)
New commits: commit d7ffbfd1dc210e716c8b744488af9666f36a0389 Author: John Paul Adrian Glaubitz <[email protected]> Date: Mon May 16 20:53:13 2016 +0200 pulsecore: Fix incorrect architecture mapping on sparc64. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=95432 Signed-off-by: John Paul Adrian Glaubitz <[email protected]> Signed-off-by: Arun Raghavan <[email protected]> diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h index 4758c84..7657144 100644 --- a/src/pulsecore/atomic.h +++ b/src/pulsecore/atomic.h @@ -201,7 +201,7 @@ static inline u_int atomic_fetchadd_int(volatile u_int *p, u_int v) { return (v); } -#elif defined(__sparc64__) +#elif defined(__sparc__) && defined(__arch64__) #define atomic_load_acq_64 atomic_load_acq_long #define atomic_fetchadd_int atomic_add_int #elif defined(__ia64__) commit a5f71d1c5453191d1a529633748cbdf69e16f665 Author: Juho Hämäläinen <[email protected]> Date: Fri May 13 17:39:41 2016 +0300 pulsecore: Don't allow unreferencing linked object. Sink(-input) and source(-output) called unlink function when reference count dropped to zero. This would result in unlink hooks being called with an object having a reference count of zero, and this is not a situation we want modules to have to deal with. It is better to just remove the redundant unlinking code from sink(-input) and source(-output) and assert on reference count in unlink functions as well. It is expected that in well behaving code the owner of an object will always unlink the object before unreferencing. Signed-off-by: Arun Raghavan <[email protected]> diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index c7d99ef..a7f6d55 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -645,7 +645,7 @@ void pa_sink_input_unlink(pa_sink_input *i) { bool linked; pa_source_output *o, PA_UNUSED *p = NULL; - pa_assert(i); + pa_sink_input_assert_ref(i); pa_assert_ctl_context(); /* See pa_sink_unlink() for a couple of comments how this function @@ -721,9 +721,7 @@ static void sink_input_free(pa_object *o) { pa_assert(i); pa_assert_ctl_context(); pa_assert(pa_sink_input_refcnt(i) == 0); - - if (PA_SINK_INPUT_IS_LINKED(i->state)) - pa_sink_input_unlink(i); + pa_assert(!PA_SINK_INPUT_IS_LINKED(i->state)); pa_log_info("Freeing input %u \"%s\"", i->index, i->proplist ? pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)) : ""); diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 3f1ef72..9bdf9be 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -669,7 +669,7 @@ void pa_sink_unlink(pa_sink* s) { bool linked; pa_sink_input *i, PA_UNUSED *j = NULL; - pa_assert(s); + pa_sink_assert_ref(s); pa_assert_ctl_context(); /* Please note that pa_sink_unlink() does more than simply @@ -722,9 +722,7 @@ static void sink_free(pa_object *o) { pa_assert(s); pa_assert_ctl_context(); pa_assert(pa_sink_refcnt(s) == 0); - - if (PA_SINK_IS_LINKED(s->state)) - pa_sink_unlink(s); + pa_assert(!PA_SINK_IS_LINKED(s->state)); pa_log_info("Freeing sink %u \"%s\"", s->index, s->name); diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 6af1543..9e951ff 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -548,7 +548,8 @@ static void source_output_set_state(pa_source_output *o, pa_source_output_state_ /* Called from main context */ void pa_source_output_unlink(pa_source_output*o) { bool linked; - pa_assert(o); + + pa_source_output_assert_ref(o); pa_assert_ctl_context(); /* See pa_sink_unlink() for a couple of comments how this function @@ -614,9 +615,7 @@ static void source_output_free(pa_object* mo) { pa_assert(o); pa_assert_ctl_context(); pa_assert(pa_source_output_refcnt(o) == 0); - - if (PA_SOURCE_OUTPUT_IS_LINKED(o->state)) - pa_source_output_unlink(o); + pa_assert(!PA_SOURCE_OUTPUT_IS_LINKED(o->state)); pa_log_info("Freeing output %u \"%s\"", o->index, o->proplist ? pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_MEDIA_NAME)) : ""); diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 98374ae..8a527d8 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -612,7 +612,7 @@ void pa_source_unlink(pa_source *s) { bool linked; pa_source_output *o, PA_UNUSED *j = NULL; - pa_assert(s); + pa_source_assert_ref(s); pa_assert_ctl_context(); /* See pa_sink_unlink() for a couple of comments how this function @@ -661,9 +661,7 @@ static void source_free(pa_object *o) { pa_assert(s); pa_assert_ctl_context(); pa_assert(pa_source_refcnt(s) == 0); - - if (PA_SOURCE_IS_LINKED(s->state)) - pa_source_unlink(s); + pa_assert(!PA_SOURCE_IS_LINKED(s->state)); pa_log_info("Freeing source %u \"%s\"", s->index, s->name); commit be4619e3f7b98a0595418bd7d13b7504ffb5136f Author: Aidan Gauland <[email protected]> Date: Wed May 25 22:26:42 2016 +1200 qpaeq: Don't set font-size on widgets Setting the font-size CSS property on a widget overrides the system font-size, and since qpaeq provides no mechanism for setting the application's font-size, we should not do this. This commit also removes the font-size property from commented-out calls to setStyleSheet() so that if these are ever reinstated, this behaviour is not reintroduced. Signed-off-by: Arun Raghavan <[email protected]> diff --git a/src/utils/qpaeq b/src/utils/qpaeq index 4b00e3a..ac4b9e4 100755 --- a/src/utils/qpaeq +++ b/src/utils/qpaeq @@ -299,7 +299,7 @@ class SliderArray(QtGui.QWidget): def __init__(self,filter_state,parent=None): super(SliderArray,self).__init__(parent) #self.setStyleSheet('padding: 0px; border-width: 0px; margin: 0px;') - #self.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('blue')) + #self.setStyleSheet('font-family: monospace;'+outline%('blue')) self.filter_state=filter_state self.setLayout(QtGui.QHBoxLayout()) self.sub_array=None @@ -367,7 +367,7 @@ class SliderArraySub(QtGui.QWidget): self.slider=[None]*len(self.filter_state.frequencies) self.label=[None]*len(self.slider) #self.setStyleSheet('padding: 0px; border-width: 0px; margin: 0px;') - #self.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('blue')) + #self.setStyleSheet('font-family: monospace;'+outline%('blue')) qt=QtCore.Qt #self.layout().setHorizontalSpacing(1) def add_slider(slider,label, c): @@ -385,7 +385,7 @@ class SliderArraySub(QtGui.QWidget): for i,hz in enumerate(self.filter_state.frequencies): slider,label=create_slider(self.hz2label(hz)) self.slider[i]=slider - #slider.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('red',)) + #slider.setStyleSheet('font-family: monospace;'+outline%('red',)) self.label[i]=label c=i+1 add_slider(slider,label,i+1) @@ -465,7 +465,7 @@ class SliderLabel(QtGui.QLabel): clicked=QtCore.pyqtSignal() def __init__(self,label_text,filter_state,parent=None): super(SliderLabel,self).__init__(parent) - self.setStyleSheet('font-size: 7pt; font-family: monospace;') + self.setStyleSheet('font-family: monospace;') self.setText(label_text) self.setMinimumSize(self.sizeHint()) def mouseDoubleClickEvent(self, event): commit 81c8d380846ffb26d8529abb7a34db6428a2e8ef Author: KimJeongYeon <[email protected]> Date: Thu May 19 11:35:44 2016 +0900 ladspa-sink: avoid to configure invalid format LADSPA allows float format only, but module-ladspa-sink possibly could be loaded with ***any*** 'format' parameter. Therefore noisy sound heard. This patch avoids to be configured as invalid format. Signed-off-by: KimJeongYeon <[email protected]> Signed-off-by: Arun Raghavan <[email protected]> diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index 38b94e3..a6290b9 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -981,6 +981,11 @@ int pa__init(pa_module*m) { goto fail; } + if (ss.format != PA_SAMPLE_FLOAT32) { + pa_log("LADSPA accepts float format only"); + goto fail; + } + if (!(plugin = pa_modargs_get_value(ma, "plugin", NULL))) { pa_log("Missing LADSPA plugin name"); goto fail; commit 111e332556ce98d52a73baad8f0b51e4885b8383 Author: Ulrich Eckhardt <[email protected]> Date: Mon May 16 19:51:05 2016 +0200 core-util: Improve pa_replace() behaviour - Assert that the search string isn't empty. - Add test. - Improve documentation. diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index b6eb85a..f816da9 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -3194,6 +3194,7 @@ char *pa_replace(const char*s, const char*a, const char *b) { pa_assert(s); pa_assert(a); + pa_assert(*a); pa_assert(b); an = strlen(a); diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index d5a2d39..5725ca7 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -249,6 +249,10 @@ void pa_reduce(unsigned *num, unsigned *den); unsigned pa_ncpus(void); +/* Replaces all occurrences of `a' in `s' with `b'. The caller has to free the + * returned string. All parameters must be non-NULL and additionally `a' must + * not be a zero-length string. + */ char *pa_replace(const char*s, const char*a, const char *b); /* Escapes p by inserting backslashes in front of backslashes. chars is a diff --git a/src/tests/core-util-test.c b/src/tests/core-util-test.c index d1470b4..c8e0fae 100644 --- a/src/tests/core-util-test.c +++ b/src/tests/core-util-test.c @@ -228,6 +228,11 @@ START_TEST (modargs_test_escape) { } END_TEST +START_TEST (modargs_test_replace_fail_4) { + pa_replace("abe", "", "bab"); +} +END_TEST + START_TEST (modargs_test_unescape) { char* value; @@ -264,6 +269,7 @@ int main(int argc, char *argv[]) { tcase_add_test_raise_signal(tc, modargs_test_replace_fail_1, SIGABRT); tcase_add_test_raise_signal(tc, modargs_test_replace_fail_2, SIGABRT); tcase_add_test_raise_signal(tc, modargs_test_replace_fail_3, SIGABRT); + tcase_add_test_raise_signal(tc, modargs_test_replace_fail_4, SIGABRT); tcase_add_test(tc, modargs_test_escape); tcase_add_test(tc, modargs_test_unescape); commit c9c8f4285f31fda5d3051832969983dfe0df1cab Author: Ulrich Eckhardt <[email protected]> Date: Mon May 16 19:51:04 2016 +0200 core-util-test: Add tests diff --git a/src/tests/core-util-test.c b/src/tests/core-util-test.c index ae5457c..d1470b4 100644 --- a/src/tests/core-util-test.c +++ b/src/tests/core-util-test.c @@ -21,8 +21,226 @@ #include <check.h> +#include <pulse/xmalloc.h> #include <pulsecore/core-util.h> +START_TEST (modargs_test_parse_boolean) { + ck_assert_int_eq(pa_parse_boolean("true"), true); + ck_assert_int_eq(pa_parse_boolean("yes"), true); + ck_assert_int_eq(pa_parse_boolean("1"), true); + + ck_assert_int_eq(pa_parse_boolean("false"), false); + ck_assert_int_eq(pa_parse_boolean("no"), false); + ck_assert_int_eq(pa_parse_boolean("0"), false); + + ck_assert_int_eq(pa_parse_boolean("maybe"), -1); + ck_assert_int_eq(pa_parse_boolean("42"), -1); +} +END_TEST + +START_TEST (modargs_test_parse_volume) { + pa_volume_t value; + + // dB volumes + ck_assert_int_eq(pa_parse_volume("-20dB", &value), 0); + ck_assert_int_eq(value, 30419); + ck_assert_int_eq(pa_parse_volume("-10dB", &value), 0); + ck_assert_int_eq(value, 44649); + ck_assert_int_eq(pa_parse_volume("-1dB", &value), 0); + ck_assert_int_eq(value, 63069); + ck_assert_int_eq(pa_parse_volume("0dB", &value), 0); + ck_assert_int_eq(value, 65536); + ck_assert_int_eq(pa_parse_volume("1dB", &value), 0); + ck_assert_int_eq(value, 68100); + ck_assert_int_eq(pa_parse_volume("10dB", &value), 0); + ck_assert_int_eq(value, 96194); + + // lowercase db + ck_assert_int_eq(pa_parse_volume("10db", &value), 0); + ck_assert_int_eq(value, 96194); + + // percentage volumes + ck_assert_int_eq(pa_parse_volume("0%", &value), 0); + ck_assert_int_eq(value, 0); + ck_assert_int_eq(pa_parse_volume("50%", &value), 0); + ck_assert_int_eq(value, 32768); + ck_assert_int_eq(pa_parse_volume("100%", &value), 0); + ck_assert_int_eq(value, 65536); + ck_assert_int_eq(pa_parse_volume("150%", &value), 0); + ck_assert_int_eq(value, 98304); + + // integer volumes` + ck_assert_int_eq(pa_parse_volume("0", &value), 0); + ck_assert_int_eq(value, 0); + ck_assert_int_eq(pa_parse_volume("100", &value), 0); + ck_assert_int_eq(value, 100); + ck_assert_int_eq(pa_parse_volume("1000", &value), 0); + ck_assert_int_eq(value, 1000); + ck_assert_int_eq(pa_parse_volume("65536", &value), 0); + ck_assert_int_eq(value, 65536); + ck_assert_int_eq(pa_parse_volume("100000", &value), 0); + ck_assert_int_eq(value, 100000); + + // invalid volumes + ck_assert_int_lt(pa_parse_volume("", &value), 0); + ck_assert_int_lt(pa_parse_volume("-2", &value), 0); + ck_assert_int_lt(pa_parse_volume("on", &value), 0); + ck_assert_int_lt(pa_parse_volume("off", &value), 0); + ck_assert_int_lt(pa_parse_volume("none", &value), 0); +} +END_TEST + +START_TEST (modargs_test_atoi) { + int32_t value; + + // decimal + ck_assert_int_eq(pa_atoi("100000", &value), 0); + ck_assert_int_eq(value, 100000); + ck_assert_int_eq(pa_atoi("-100000", &value), 0); + ck_assert_int_eq(value, -100000); + + // hexadecimal + ck_assert_int_eq(pa_atoi("0x100000", &value), 0); + ck_assert_int_eq(value, 0x100000); + ck_assert_int_eq(pa_atoi("-0x100000", &value), 0); + ck_assert_int_eq(value, -0x100000); + + // invalid values + ck_assert_int_lt(pa_atoi("3.14", &value), 0); + ck_assert_int_lt(pa_atoi("7*8", &value), 0); + ck_assert_int_lt(pa_atoi("false", &value), 0); +} +END_TEST + +START_TEST (modargs_test_atou) { + uint32_t value; + + // decimal + ck_assert_int_eq(pa_atou("100000", &value), 0); + ck_assert_int_eq(value, 100000); + + // hexadecimal + ck_assert_int_eq(pa_atou("0x100000", &value), 0); + ck_assert_int_eq(value, 0x100000); + + // invalid values + ck_assert_int_lt(pa_atou("-100000", &value), 0); + ck_assert_int_lt(pa_atou("-0x100000", &value), 0); + ck_assert_int_lt(pa_atou("3.14", &value), 0); + ck_assert_int_lt(pa_atou("7*8", &value), 0); + ck_assert_int_lt(pa_atou("false", &value), 0); +} +END_TEST + +START_TEST (modargs_test_atol) { + long value; + + // decimal + ck_assert_int_eq(pa_atol("100000", &value), 0); + ck_assert_int_eq(value, 100000l); + ck_assert_int_eq(pa_atol("-100000", &value), 0); + ck_assert_int_eq(value, -100000l); + + // hexadecimal + ck_assert_int_eq(pa_atol("0x100000", &value), 0); + ck_assert_int_eq(value, 0x100000l); + ck_assert_int_eq(pa_atol("-0x100000", &value), 0); + ck_assert_int_eq(value, -0x100000l); + + // invalid values + ck_assert_int_lt(pa_atol("3.14", &value), 0); + ck_assert_int_lt(pa_atol("7*8", &value), 0); + ck_assert_int_lt(pa_atol("false", &value), 0); +} +END_TEST + +START_TEST (modargs_test_atod) { + double value; + double epsilon = 0.001; + + // decimal + ck_assert_int_eq(pa_atod("100000", &value), 0); + ck_assert(value > 100000 - epsilon); + ck_assert(value < 100000 + epsilon); + ck_assert_int_eq(pa_atod("-100000", &value), 0); + ck_assert(value > -100000 - epsilon); + ck_assert(value < -100000 + epsilon); + ck_assert_int_eq(pa_atod("3.14", &value), 0); + ck_assert(value > 3.14 - epsilon); + ck_assert(value < 3.14 + epsilon); + + // invalid values + ck_assert_int_lt(pa_atod("7*8", &value), 0); + ck_assert_int_lt(pa_atod("false", &value), 0); +} +END_TEST + +START_TEST (modargs_test_replace) { + char* value; + + value = pa_replace("abcde", "bcd", "XYZ"); + ck_assert_str_eq(value, "aXYZe"); + pa_xfree(value); + + value = pa_replace("abe", "b", "bab"); + ck_assert_str_eq(value, "ababe"); + pa_xfree(value); + + value = pa_replace("abe", "c", "bab"); + ck_assert_str_eq(value, "abe"); + pa_xfree(value); + + value = pa_replace("abcde", "bcd", ""); + ck_assert_str_eq(value, "ae"); + pa_xfree(value); +} +END_TEST + +START_TEST (modargs_test_replace_fail_1) { + pa_replace(NULL, "b", "bab"); +} +END_TEST + +START_TEST (modargs_test_replace_fail_2) { + pa_replace("abe", NULL, "bab"); +} +END_TEST + +START_TEST (modargs_test_replace_fail_3) { + pa_replace("abcde", "b", NULL); +} +END_TEST + +START_TEST (modargs_test_escape) { + char* value; + + value = pa_escape("abcde", "bcd"); + ck_assert_str_eq(value, "a\\b\\c\\de"); + pa_xfree(value); + + value = pa_escape("\\", "bcd"); + ck_assert_str_eq(value, "\\\\"); + pa_xfree(value); + + value = pa_escape("\\", NULL); + ck_assert_str_eq(value, "\\\\"); + pa_xfree(value); +} +END_TEST + +START_TEST (modargs_test_unescape) { + char* value; + + value = pa_unescape(pa_xstrdup("a\\b\\c\\de")); + ck_assert_str_eq(value, "abcde"); + pa_xfree(value); + + value = pa_unescape(pa_xstrdup("\\\\")); + ck_assert_str_eq(value, "\\"); + pa_xfree(value); +} +END_TEST + int main(int argc, char *argv[]) { int failed = 0; Suite *s; @@ -36,6 +254,18 @@ int main(int argc, char *argv[]) { tc = tcase_create("core-util"); suite_add_tcase(s, tc); + tcase_add_test(tc, modargs_test_parse_boolean); + tcase_add_test(tc, modargs_test_parse_volume); + tcase_add_test(tc, modargs_test_atoi); + tcase_add_test(tc, modargs_test_atou); + tcase_add_test(tc, modargs_test_atol); + tcase_add_test(tc, modargs_test_atod); + tcase_add_test(tc, modargs_test_replace); + tcase_add_test_raise_signal(tc, modargs_test_replace_fail_1, SIGABRT); + tcase_add_test_raise_signal(tc, modargs_test_replace_fail_2, SIGABRT); + tcase_add_test_raise_signal(tc, modargs_test_replace_fail_3, SIGABRT); + tcase_add_test(tc, modargs_test_escape); + tcase_add_test(tc, modargs_test_unescape); sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); commit e1bc4791104ce3814aa6963a539e98e6aec00b8a Author: Ulrich Eckhardt <[email protected]> Date: Mon May 16 19:51:03 2016 +0200 core-util-test: Add boilerplate diff --git a/src/.gitignore b/src/.gitignore index 8a5dfb0..bfe74bd 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -35,6 +35,7 @@ asyncq-test channelmap-test close-test connect-stress +core-util-test cpulimit-test cpulimit-test2 cpu-sconv-test diff --git a/src/Makefile.am b/src/Makefile.am index adaa38b..a311575 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -240,6 +240,7 @@ endif noinst_LTLIBRARIES = TESTS_default = \ + core-util-test \ mainloop-test \ strlist-test \ close-test \ @@ -355,6 +356,11 @@ check-daemon: endif +core_util_test_SOURCES = tests/core-util-test.c +core_util_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS) +core_util_test_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@[email protected] +core_util_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS) + mainloop_test_SOURCES = tests/mainloop-test.c mainloop_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS) mainloop_test_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@[email protected] diff --git a/src/tests/core-util-test.c b/src/tests/core-util-test.c new file mode 100644 index 0000000..ae5457c --- /dev/null +++ b/src/tests/core-util-test.c @@ -0,0 +1,46 @@ +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <check.h> + +#include <pulsecore/core-util.h> + +int main(int argc, char *argv[]) { + int failed = 0; + Suite *s; + TCase *tc; + SRunner *sr; + + if (!getenv("MAKE_CHECK")) + pa_log_set_level(PA_LOG_DEBUG); + + s = suite_create("Core-Util"); + + tc = tcase_create("core-util"); + suite_add_tcase(s, tc); + + sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} commit 6f0e39d30f54d1f98802ea97d9cfbcfc64dd6076 Author: Tanu Kaskinen <[email protected]> Date: Wed May 25 14:13:42 2016 +0300 pstream: fix revoke callback setting While investigating bug 95352, I noticed that pa_pstream_set_revoke_callback() and pa_pstream_set_release_callback() were identical - both set the release callback. pa_pstream_set_revoke_callback() was obviously broken - it was setting the wrong callback. The only place where set_revoke_callback() is called is in protocol-native.c. The code there looks like this: pa_pstream_set_revoke_callback(c->pstream, pstream_revoke_callback, c); pa_pstream_set_release_callback(c->pstream, pstream_release_callback, c); Since set_release_callback() is called last, the release callback gets set correctly. The only problem is that the revoke callback stays unset. What are the consequences of that? The code that calls the revoke callback looks like this: if (p->revoke_callback) p->revoke_callback(p, block_id, p->revoke_callback_userdata); else pa_pstream_send_revoke(p, block_id); So the intended callback is replaced with a pa_pstream_send_revoke() call. What does the intended callback, that doesn't get called, do? if (!(q = pa_thread_mq_get())) pa_pstream_send_revoke(p, block_id); else pa_asyncmsgq_post(q->outq, PA_MSGOBJECT(userdata), CONNECTION_MESSAGE_REVOKE, PA_UINT_TO_PTR(block_id), 0, NULL, NULL); So the native protocol's revoke callback is anyway going to call pa_pstream_send_revoke() when called from the main thread. If the revoking is done from an IO thread, an asynchronous message is sent to the main thread instead, and the message handler will then call pa_pstream_send_revoke(). In conclusion, the only effect of this bug was that pa_pstream_send_revoke() was sometimes being called from an IO thread when it should have been called from the main thread. I don't know if this caused the crash in bug 95352. Probably not. diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index bbff2f6..2c9e452 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -1119,8 +1119,8 @@ void pa_pstream_set_revoke_callback(pa_pstream *p, pa_pstream_block_id_cb_t cb, pa_assert(p); pa_assert(PA_REFCNT_VALUE(p) > 0); - p->release_callback = cb; - p->release_callback_userdata = userdata; + p->revoke_callback = cb; + p->revoke_callback_userdata = userdata; } bool pa_pstream_is_pending(pa_pstream *p) { commit 768c80f3c35da28f10a293ffa62c0e092db65db5 Author: Alexander E. Patrakov <[email protected]> Date: Sun May 22 02:03:21 2016 +0500 alsa: reread configuration when opening new devices If a card has been hot-plugged after pulseaudio start, alsa-lib still has old configuration in memory, which doesn't have PCM definitions for the new card. Thus, this error appears, and the device doesn't work: I: [pulseaudio] (alsa-lib)confmisc.c: Unable to find definition 'cards.USB-Audio.pcm.front.0:CARD=0' I: [pulseaudio] (alsa-lib)conf.c: function snd_func_refer returned error: No such file or directory I: [pulseaudio] (alsa-lib)conf.c: Evaluate error: No such file or directory I: [pulseaudio] (alsa-lib)pcm.c: Unknown PCM front:0 I: [pulseaudio] alsa-util.c: Error opening PCM device front:0: No such file or directory The snd_config_update_free_global() function makes alsa-lib forget any cached configuration and reparse all PCM definitions from scratch next time it is told to open anything. The trick has been copied from Phonon. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=54029 Signed-off-by: Alexander E. Patrakov <[email protected]> diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 2fdebe0..63674e2 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -2146,6 +2146,15 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca b = use_mmap; d = use_tsched; + /* Force ALSA to reread its configuration if module-alsa-card didn't + * do it for us. This matters if our device was hot-plugged after ALSA + * has already read its configuration - see + * https://bugs.freedesktop.org/show_bug.cgi?id=54029 + */ + + if (!card) + snd_config_update_free_global(); + if (mapping) { if (!(dev_id = pa_modargs_get_value(ma, "device_id", NULL))) { diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 4683dfe..0820b48 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -1854,6 +1854,15 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p b = use_mmap; d = use_tsched; + /* Force ALSA to reread its configuration if module-alsa-card didn't + * do it for us. This matters if our device was hot-plugged after ALSA + * has already read its configuration - see + * https://bugs.freedesktop.org/show_bug.cgi?id=54029 + */ + + if (!card) + snd_config_update_free_global(); + if (mapping) { if (!(dev_id = pa_modargs_get_value(ma, "device_id", NULL))) { diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c index e5cc4ae..adb942b 100644 --- a/src/modules/alsa/module-alsa-card.c +++ b/src/modules/alsa/module-alsa-card.c @@ -715,6 +715,14 @@ int pa__init(pa_module *m) { } pa_modargs_get_value_boolean(u->modargs, "use_ucm", &u->use_ucm); + + /* Force ALSA to reread its configuration. This matters if our device + * was hot-plugged after ALSA has already read its configuration - see + * https://bugs.freedesktop.org/show_bug.cgi?id=54029 + */ + + snd_config_update_free_global(); + if (u->use_ucm && !pa_alsa_ucm_query_profiles(&u->ucm, u->alsa_card_index)) { pa_log_info("Found UCM profiles"); commit 4c42b3ef7c3fca21d9decfe8a1ea283665796329 Author: Arun Raghavan <[email protected]> Date: Mon May 9 07:47:19 2016 +0530 i18n: Add module-allow-passthrough to POTFILES.in diff --git a/po/POTFILES.in b/po/POTFILES.in index 0903741..e2d6d11 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -22,6 +22,7 @@ src/modules/gconf/module-gconf.c src/modules/jack/module-jack-sink.c src/modules/jack/module-jack-source.c src/modules/macosx/module-coreaudio-device.c +src/modules/module-allow-passthrough.c src/modules/module-always-sink.c src/modules/module-cli.c src/modules/module-combine.c commit 0985a717f30faff74657eb292aac7f73e59eb162 Author: Arun Raghavan <[email protected]> Date: Sat May 7 13:42:34 2016 +0530 allow-passthrough: Use pa_module_hook_connect() Signed-off-by: Arun Raghavan <[email protected]> diff --git a/src/modules/module-allow-passthrough.c b/src/modules/module-allow-passthrough.c index 3b56c1f..4b801e4 100644 --- a/src/modules/module-allow-passthrough.c +++ b/src/modules/module-allow-passthrough.c @@ -51,12 +51,6 @@ struct userdata { * its streams. */ pa_hashmap *null_sinks; - pa_hook_slot - *sink_input_new_slot, - *sink_input_unlink_slot, - *sink_input_move_start_slot, - *sink_input_move_finish_slot; - bool moving; }; @@ -281,10 +275,10 @@ int pa__init(pa_module*m) { u->null_sinks = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - u->sink_input_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_new_cb, u); - u->sink_input_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_unlink_cb, u); - u->sink_input_move_start_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_start_cb, u); - u->sink_input_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_finish_cb, u); + pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_new_cb, u); + pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_unlink_cb, u); + pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_start_cb, u); + pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_finish_cb, u); u->moving = false; @@ -308,15 +302,6 @@ void pa__done(pa_module*m) { if (!(u = m->userdata)) return; - if (u->sink_input_new_slot) - pa_hook_slot_free(u->sink_input_new_slot); - if (u->sink_input_unlink_slot) - pa_hook_slot_free(u->sink_input_unlink_slot); - if (u->sink_input_move_start_slot) - pa_hook_slot_free(u->sink_input_move_start_slot); - if (u->sink_input_move_finish_slot) - pa_hook_slot_free(u->sink_input_move_finish_slot); - if (m->core->state != PA_CORE_SHUTDOWN) unload_all_null_sink_modules(u, m->core); commit 14804ba1ca4cfb58f2e8a9afa9ca87b309fa8d42 Author: Guillaume Desmottes <[email protected]> Date: Fri Mar 18 15:28:12 2016 +0100 allow-passthrough: Add module to allow passthrough streams always go through For various use-cases a passthrough stream should have priority over all other streams and get exclusive access to the sink regardless of whether any other streams are playing. An example use-case is ensuring Kodi can successfully start video playback (with passthrough) even if an external notification sound happened to be playing at the same time. Signed-off-by: Arun Raghavan <[email protected]> diff --git a/src/Makefile.am b/src/Makefile.am index b600dfb..adaa38b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1205,7 +1205,8 @@ modlibexec_LTLIBRARIES += \ module-switch-on-port-available.la \ module-filter-apply.la \ module-filter-heuristics.la \ - module-role-ducking.la + module-role-ducking.la \ + module-allow-passthrough.la if HAVE_ESOUND modlibexec_LTLIBRARIES += \ @@ -1548,7 +1549,8 @@ SYMDEF_FILES = \ module-switch-on-connect-symdef.h \ module-switch-on-port-available-symdef.h \ module-filter-apply-symdef.h \ - module-filter-heuristics-symdef.h + module-filter-heuristics-symdef.h \ + module-allow-passthrough-symdef.h if HAVE_ESOUND SYMDEF_FILES += \ @@ -2207,6 +2209,12 @@ module_rygel_media_server_la_LDFLAGS = $(MODULE_LDFLAGS) module_rygel_media_server_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) libprotocol-http.la module_rygel_media_server_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) +# Allow passthrough module +module_allow_passthrough_la_SOURCES = modules/module-allow-passthrough.c +module_allow_passthrough_la_LDFLAGS = $(MODULE_LDFLAGS) +module_allow_passthrough_la_LIBADD = $(MODULE_LIBADD) +module_allow_passthrough_la_CFLAGS = $(AM_CFLAGS) + ################################### # Some minor stuff # ################################### diff --git a/src/modules/module-allow-passthrough.c b/src/modules/module-allow-passthrough.c new file mode 100644 index 0000000..3b56c1f --- /dev/null +++ b/src/modules/module-allow-passthrough.c @@ -0,0 +1,327 @@ +/*** + This file is part of PulseAudio. + + Copyright (C) 2014 Collabora Ltd. <http://www.collabora.co.uk/> + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <pulse/xmalloc.h> + +#include <pulsecore/core.h> +#include <pulsecore/i18n.h> +#include <pulsecore/sink-input.h> +#include <pulsecore/source-output.h> +#include <pulsecore/modargs.h> +#include <pulsecore/log.h> +#include <pulsecore/namereg.h> +#include <pulsecore/core-util.h> + +#include "module-allow-passthrough-symdef.h" + +PA_MODULE_AUTHOR("Guillaume Desmottes"); +PA_MODULE_DESCRIPTION("When a passthrough stream is requested, route all the other streams to a dummy device"); +PA_MODULE_VERSION(PACKAGE_VERSION); +PA_MODULE_LOAD_ONCE(true); + +static const char* const valid_modargs[] = { + NULL, +}; + +struct userdata { + /* (pa_sink *) -> (pa_sink *) + * Map the 'real' muted sink to the null-sink currently being used to play + * its streams. */ + pa_hashmap *null_sinks; + + pa_hook_slot + *sink_input_new_slot, + *sink_input_unlink_slot, + *sink_input_move_start_slot, + *sink_input_move_finish_slot; + + bool moving; +}; + +static pa_sink *ensure_null_sink_for_sink(struct userdata *u, pa_sink *s, pa_core *c) { + char *t; + pa_module *m; + pa_sink *sink; + uint32_t idx; + const char *name; + + sink = pa_hashmap_get(u->null_sinks, s); + if (sink != NULL) { + /* We already have a null-sink for this sink */ + return sink; + } + + name = pa_proplist_gets(s->proplist, PA_PROP_MEDIA_NAME); + + t = pa_sprintf_malloc("sink_name=allow_passthrough_null_%s sink_properties='device.description=\"%s\"'", + name ? name : "", _("Dummy Output")); + m = pa_module_load(c, "module-null-sink", t); + pa_xfree(t); + + if (m == NULL) + return NULL; + + PA_IDXSET_FOREACH(sink, c->sinks, idx) { + if (sink->module->index == m->index) { + pa_hashmap_put(u->null_sinks, s, sink); + return sink; + } + } + + return NULL; +} + +static void unload_null_sink_module_for_sink(struct userdata *u, pa_sink *s, pa_core *c) { + pa_sink *null_sink; + + null_sink = pa_hashmap_get(u->null_sinks, s); + if (null_sink == NULL) + return; + + pa_module_unload_request_by_index(c, null_sink->module->index, true); + + pa_hashmap_remove(u->null_sinks, s); +} + +static void move_stream(struct userdata *u, pa_sink_input *i, pa_sink *target) { + u->moving = true; + if (pa_sink_input_move_to(i, target, false) < 0) + pa_log_info("Failed to move sink input %u \"%s\" to %s.", i->index, + pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), target->name); + else + pa_log_info("Successfully moved sink input %u \"%s\" to %s.", i->index, + pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), target->name); + u->moving = false; +} + +/* Check if @sink has any passthrough stream, ignoring @ignore */ +static bool sink_has_passthrough_stream(pa_sink *sink, pa_sink_input *ignore) +{ + pa_sink_input *stream; + uint32_t idx; + + PA_IDXSET_FOREACH(stream, sink->inputs, idx) { + if (stream == ignore) + continue; + + if (pa_sink_input_is_passthrough(stream)) + return true; + } + + return false; +} + +static pa_hook_result_t new_passthrough_stream(struct userdata *u, pa_core *c, pa_sink *sink, pa_sink_input *i) { + uint32_t idx; + pa_sink_input *stream; + pa_sink *null_sink; + + if (sink_has_passthrough_stream(sink, i)) { + pa_log_info("Dropping playing a passthrough stream; ignoring"); + /* PulseAudio will reject the stream itself */ + return PA_HOOK_OK; + } + + pa_log_info("Just received a passthrough stream; pause all the others streams so it can play"); + + null_sink = ensure_null_sink_for_sink(u, sink, c); + if (null_sink == NULL) + return PA_HOOK_OK; + + PA_IDXSET_FOREACH(stream, sink->inputs, idx) { + /* We don't want to move the stream which just moved to the sink and trigger this re-routing */ + if (stream != i) + move_stream(u, stream, null_sink); + } + + return PA_HOOK_OK; +} + +/* return a null sink for the new stream if it needs to be re-routed */ +static pa_sink * new_normal_stream(struct userdata *u, pa_core *c, pa_sink *sink) { + if (!sink_has_passthrough_stream(sink, NULL)) + return NULL; + + /* A passthrough stream is already playing on this sink, re-route to a null sink */ + return ensure_null_sink_for_sink(u, sink, c); +} + +static pa_hook_result_t sink_input_new_cb(pa_core *core, pa_sink_input_new_data *new_data, struct userdata *u) { + pa_sink *null_sink; + + pa_core_assert_ref(core); + /* This is a bit of a hack, to determine whether the input stream will use + * a passthrough stream, the sink should have been selected and a format + * renegotiated. This can either happen by an earlier module (e.g. one + * doing routing or other policies) and if not pulseaudio core will setup + * the defaults after all hooks for this event have been processed. + * + * Unfortunately if no other module decides on sink/format before this hook + * runs, pulse core doing it is too late, so if a sink and/or stream format + * haven't been setup & configured just yet do so now using the same code + * as pulsecore would use (default sink and higher priority negotiated + * format). */ + if (!new_data->sink) { + pa_sink *sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK); + pa_return_val_if_fail(sink, -PA_ERR_NOENTITY); + pa_sink_input_new_data_set_sink(new_data, sink, false); + } + + if (!new_data->format && new_data->nego_formats && !pa_idxset_isempty(new_data->nego_formats)) + new_data->format = pa_format_info_copy(pa_idxset_first(new_data->nego_formats, NULL)); + + if (pa_sink_input_new_data_is_passthrough(new_data)) + return new_passthrough_stream(u, core, new_data->sink, NULL); + + null_sink = new_normal_stream(u, core, new_data->sink); + + if (null_sink) { + pa_log_info("Already playing a passthrough stream; re-routing new stream to the null sink"); + pa_sink_input_new_data_set_sink(new_data, null_sink, false); + } + + return PA_HOOK_OK; +} + +static pa_hook_result_t passthrough_stream_removed(struct userdata *u, pa_core *c, pa_sink_input *i) { + uint32_t idx; + pa_sink_input *stream; + pa_sink *null_sink; + + pa_assert(i->sink); + + null_sink = pa_hashmap_get(u->null_sinks, i->sink); + if (null_sink == NULL) + return PA_HOOK_OK; + + pa_log_info("Passthrough stream removed; restore all streams"); + + PA_IDXSET_FOREACH(stream, null_sink->inputs, idx) { + move_stream(u, stream, i->sink); + } + + unload_null_sink_module_for_sink(u, i->sink, c); + + return PA_HOOK_OK; +} + +static pa_hook_result_t sink_input_removed(pa_core *core, pa_sink_input *i, struct userdata *u) { + pa_sink_input_assert_ref(i); + + if (pa_sink_input_is_passthrough(i)) + return passthrough_stream_removed(u, core, i); + + return PA_HOOK_OK; +} + +static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, struct userdata *u) { + return sink_input_removed(core, i, u); +} + +static pa_hook_result_t sink_input_move_start_cb(pa_core *core, pa_sink_input *i, struct userdata *u) { + if (u->moving) + return PA_HOOK_OK; + + return sink_input_removed(core, i, u); +} + +static pa_hook_result_t sink_input_move_finish_cb(pa_core *core, pa_sink_input *i, struct userdata *u) { + pa_sink *null_sink; + + if (u->moving) + return PA_HOOK_OK; + + if (pa_sink_input_is_passthrough(i)) + /* Passthrough stream has been moved to a new sink */ + return new_passthrough_stream(u, core, i->sink, i); + + null_sink = new_normal_stream(u, core, i->sink); + if (null_sink) { + pa_log_info("Already playing a passthrough stream; re-routing moved stream to the null sink"); + move_stream(u, i, null_sink); + } + + return PA_HOOK_OK; +} + +int pa__init(pa_module*m) { + pa_modargs *ma; + struct userdata *u; + + pa_assert(m); + + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + pa_log("Failed to parse module arguments"); + return -1; + } + + m->userdata = u = pa_xnew(struct userdata, 1); + + u->null_sinks = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + + u->sink_input_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_new_cb, u); + u->sink_input_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_unlink_cb, u); + u->sink_input_move_start_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_start_cb, u); + u->sink_input_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_finish_cb, u); + + u->moving = false; + + pa_modargs_free(ma); + return 0; +} + +static void unload_all_null_sink_modules(struct userdata *u, pa_core *c) { + void *state = NULL; + pa_sink *null_sink; + + PA_HASHMAP_FOREACH(null_sink, u->null_sinks, state) + pa_module_unload_request_by_index(c, null_sink->module->index, true); +} + +void pa__done(pa_module*m) { + struct userdata *u; + + pa_assert(m); + + if (!(u = m->userdata)) + return; + + if (u->sink_input_new_slot) + pa_hook_slot_free(u->sink_input_new_slot); + if (u->sink_input_unlink_slot) + pa_hook_slot_free(u->sink_input_unlink_slot); + if (u->sink_input_move_start_slot) + pa_hook_slot_free(u->sink_input_move_start_slot); + if (u->sink_input_move_finish_slot) + pa_hook_slot_free(u->sink_input_move_finish_slot); + + if (m->core->state != PA_CORE_SHUTDOWN) + unload_all_null_sink_modules(u, m->core); + + if (u->null_sinks) + pa_hashmap_free(u->null_sinks); + + pa_xfree(u); +} commit 7ac5390042e0bc2c060bb29bceef0b0d8344f4b7 Author: Arun Raghavan <[email protected]> Date: Mon Apr 25 18:12:39 2016 +0530 client, protocol-native: Use macros for protocol version/flag access This makes it easier to read and cleaner in general. diff --git a/src/pulse/context.c b/src/pulse/context.c index 69be5f4..c39cbe7 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -504,17 +504,17 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t /* Starting with protocol version 13 the MSB of the version tag reflects if shm is available for this connection or not. */ - if (c->version >= 13) { - shm_on_remote = !!(c->version & 0x80000000U); + if ((c->version & PA_PROTOCOL_VERSION_MASK) >= 13) { + shm_on_remote = !!(c->version & PA_PROTOCOL_FLAG_SHM); /* Starting with protocol version 31, the second MSB of the version * tag reflects whether memfd is supported on the other PA end. */ - if (c->version >= 31) - memfd_on_remote = !!(c->version & 0x40000000U); + if ((c->version & PA_PROTOCOL_VERSION_MASK) >= 31) + memfd_on_remote = !!(c->version & PA_PROTOCOL_FLAG_MEMFD); /* Reserve the two most-significant _bytes_ of the version tag * for flags. */ - c->version &= 0x0000FFFFU; + c->version &= PA_PROTOCOL_VERSION_MASK; } pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION); @@ -629,8 +629,8 @@ static void setup_context(pa_context *c, pa_iochannel *io) { /* Starting with protocol version 13 we use the MSB of the version * tag for informing the other side if we could do SHM or not. * Starting from version 31, second MSB is used to flag memfd support. */ - pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? 0x80000000U : 0) | - (c->memfd_on_local ? 0x40000000 : 0)); + pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? PA_PROTOCOL_FLAG_SHM : 0) | + (c->memfd_on_local ? PA_PROTOCOL_FLAG_MEMFD: 0)); pa_tagstruct_put_arbitrary(t, cookie, sizeof(cookie)); #ifdef HAVE_CREDS diff --git a/src/pulse/internal.h b/src/pulse/internal.h index 9bbb903..01d2b6e 100644 --- a/src/pulse/internal.h +++ b/src/pulse/internal.h @@ -49,6 +49,12 @@ #define DEFAULT_TIMEOUT (30) +#define PA_PROTOCOL_FLAG_MASK 0xFFFF0000U +#define PA_PROTOCOL_VERSION_MASK 0x0000FFFFU + +#define PA_PROTOCOL_FLAG_SHM 0x80000000U +#define PA_PROTOCOL_FLAG_MEMFD 0x40000000U + struct pa_context { PA_REFCNT_DECLARE; diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 5619b9c..594617e 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2718,17 +2718,17 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta /* Starting with protocol version 13 the MSB of the version tag reflects if shm is available for this pa_native_connection or not. */ - if (c->version >= 13) { - shm_on_remote = !!(c->version & 0x80000000U); + if ((c->version & PA_PROTOCOL_VERSION_MASK) >= 13) { + shm_on_remote = !!(c->version & PA_PROTOCOL_FLAG_SHM); /* Starting with protocol version 31, the second MSB of the version * tag reflects whether memfd is supported on the other PA end. */ - if (c->version >= 31) - memfd_on_remote = !!(c->version & 0x40000000U); + if ((c->version & PA_PROTOCOL_VERSION_MASK) >= 31) + memfd_on_remote = !!(c->version & PA_PROTOCOL_FLAG_MEMFD); /* Reserve the two most-significant _bytes_ of the version tag * for flags. */ - c->version &= 0x0000FFFFU; + c->version &= PA_PROTOCOL_VERSION_MASK; } pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION);
_______________________________________________ pulseaudio-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/pulseaudio-commits
