diff --git a/SOURCES/0001-alsa-mixer-Add-path-for-Headset-Microphone.patch b/SOURCES/0001-alsa-mixer-Add-path-for-Headset-Microphone.patch new file mode 100644 index 0000000..917cecc --- /dev/null +++ b/SOURCES/0001-alsa-mixer-Add-path-for-Headset-Microphone.patch @@ -0,0 +1,210 @@ +From 6452f86519c487a4bb4d6f048b0efd558d88814f Mon Sep 17 00:00:00 2001 +From: David Henningsson +Date: Thu, 14 Mar 2013 09:14:34 +0100 +Subject: [PATCH 1/2] alsa-mixer: Add path for Headset Microphone + +In kernel 3.10, some devices will have the "Headset Microphone" name +to indicate that the mic is part of a mic + headphone combo, i e, a headset. +--- + src/Makefile.am | 1 + + src/modules/alsa/alsa-mixer.c | 1 + + .../alsa/mixer/paths/analog-input-headset-mic.conf | 99 ++++++++++++++++++++++ + src/modules/alsa/mixer/profile-sets/default.conf | 4 +- + .../alsa/mixer/profile-sets/extra-hdmi.conf | 4 +- + 5 files changed, 105 insertions(+), 4 deletions(-) + create mode 100644 src/modules/alsa/mixer/paths/analog-input-headset-mic.conf + +diff --git a/src/Makefile.am b/src/Makefile.am +index d360201..6d4425d 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1176,6 +1176,7 @@ dist_alsapaths_DATA = \ + modules/alsa/mixer/paths/analog-input-dock-mic.conf \ + modules/alsa/mixer/paths/analog-input-front-mic.conf \ + modules/alsa/mixer/paths/analog-input-headphone-mic.conf \ ++ modules/alsa/mixer/paths/analog-input-headset-mic.conf \ + modules/alsa/mixer/paths/analog-input-internal-mic.conf \ + modules/alsa/mixer/paths/analog-input-internal-mic-always.conf \ + modules/alsa/mixer/paths/analog-input-rear-mic.conf \ +diff --git a/src/Makefile.in b/src/Makefile.in +index d360201..6d4425d 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -2615,6 +2615,7 @@ am__dist_alsapaths_DATA_DIST = \ + modules/alsa/mixer/paths/analog-input-dock-mic.conf \ + modules/alsa/mixer/paths/analog-input-front-mic.conf \ + modules/alsa/mixer/paths/analog-input-headphone-mic.conf \ ++ modules/alsa/mixer/paths/analog-input-headset-mic.conf \ + modules/alsa/mixer/paths/analog-input-internal-mic.conf \ + modules/alsa/mixer/paths/analog-input-internal-mic-always.conf \ + modules/alsa/mixer/paths/analog-input-rear-mic.conf \ +@@ -3607,6 +3608,7 @@ libavahi_wrap_la_LIBADD = $(AM_LIBADD) $ + @HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/analog-input-dock-mic.conf \ + @HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/analog-input-front-mic.conf \ + @HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/analog-input-headphone-mic.conf \ ++@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/analog-input-headset-mic.conf \ + @HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/analog-input-internal-mic.conf \ + @HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/analog-input-internal-mic-always.conf \ + @HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/analog-input-rear-mic.conf \ +diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c +index 761aae1..ee80d25 100644 +--- a/src/modules/alsa/alsa-mixer.c ++++ b/src/modules/alsa/alsa-mixer.c +@@ -2336,6 +2336,7 @@ static int path_verify(pa_alsa_path *p) { + { "analog-input-microphone-rear", N_("Rear Microphone") }, + { "analog-input-microphone-dock", N_("Dock Microphone") }, + { "analog-input-microphone-internal", N_("Internal Microphone") }, ++ { "analog-input-microphone-headset", N_("Headset Microphone") }, + { "analog-input-linein", N_("Line In") }, + { "analog-input-radio", N_("Radio") }, + { "analog-input-video", N_("Video") }, +diff --git a/src/modules/alsa/mixer/paths/analog-input-headset-mic.conf b/src/modules/alsa/mixer/paths/analog-input-headset-mic.conf +new file mode 100644 +index 0000000..c5aff1c +--- /dev/null ++++ b/src/modules/alsa/mixer/paths/analog-input-headset-mic.conf +@@ -0,0 +1,99 @@ ++# 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, write to the Free Software Foundation, ++# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ++ ++; For devices where a 'Headset Mic' or 'Headset Mic Boost' element exists ++; ++; See analog-output.conf.common for an explanation on the directives ++ ++[General] ++priority = 87 ++name = analog-input-microphone-headset ++ ++[Jack Headset Mic] ++required-any = any ++ ++[Jack Headset Mic Phantom] ++state.plugged = unknown ++state.unplugged = unknown ++required-any = any ++ ++[Element Headset Mic Boost] ++required-any = any ++switch = select ++volume = merge ++override-map.1 = all ++override-map.2 = all-left,all-right ++ ++[Element Headset Mic] ++required-any = any ++switch = mute ++volume = merge ++override-map.1 = all ++override-map.2 = all-left,all-right ++ ++[Element Capture] ++switch = mute ++volume = merge ++override-map.1 = all ++override-map.2 = all-left,all-right ++ ++[Element Input Source] ++enumeration = select ++ ++[Option Input Source:Headset Mic] ++name = Headset Microphone ++required-any = any ++ ++[Element Capture Source] ++enumeration = select ++ ++[Option Capture Source:Headset Mic] ++name = Headset Microphone ++required-any = any ++ ++[Element Front Mic] ++switch = off ++volume = off ++ ++[Element Internal Mic] ++switch = off ++volume = off ++ ++[Element Rear Mic] ++switch = off ++volume = off ++ ++[Element Dock Mic] ++switch = off ++volume = off ++ ++[Element Dock Mic Boost] ++switch = off ++volume = off ++ ++[Element Internal Mic Boost] ++switch = off ++volume = off ++ ++[Element Front Mic Boost] ++switch = off ++volume = off ++ ++[Element Rear Mic Boost] ++switch = off ++volume = off ++ ++.include analog-input-mic.conf.common +diff --git a/src/modules/alsa/mixer/profile-sets/default.conf b/src/modules/alsa/mixer/profile-sets/default.conf +index b040036..c805d36 100644 +--- a/src/modules/alsa/mixer/profile-sets/default.conf ++++ b/src/modules/alsa/mixer/profile-sets/default.conf +@@ -102,14 +102,14 @@ auto-profiles = yes + device-strings = hw:%f + channel-map = mono + paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono +-paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line ++paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headset-mic + priority = 1 + + [Mapping analog-stereo] + device-strings = front:%f hw:%f + channel-map = left,right + paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono +-paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic ++paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic + priority = 10 + + [Mapping analog-surround-40] +diff --git a/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf b/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf +index 7075314..aaf4d91 100644 +--- a/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf ++++ b/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf +@@ -28,14 +28,14 @@ auto-profiles = yes + device-strings = hw:%f + channel-map = mono + paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono +-paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line ++paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headset-mic + priority = 1 + + [Mapping analog-stereo] + device-strings = front:%f hw:%f + channel-map = left,right + paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono +-paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic ++paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic + priority = 10 + + [Mapping analog-surround-40] +-- +1.8.5.3 + diff --git a/SOURCES/0001-bluetooth-skip-audio-in-smaller-chunks.patch b/SOURCES/0001-bluetooth-skip-audio-in-smaller-chunks.patch new file mode 100644 index 0000000..e4c2db7 --- /dev/null +++ b/SOURCES/0001-bluetooth-skip-audio-in-smaller-chunks.patch @@ -0,0 +1,45 @@ +From 2ead0a39408cb335749dedca9b18b330a0af8d26 Mon Sep 17 00:00:00 2001 +From: Wim Taymans +Date: Mon, 24 Feb 2014 09:45:52 +0100 +Subject: [PATCH] bluetooth: skip audio in smaller chunks + +Render audio in smaller chunks, the amount of data to mix is not bounded +and we might end up hitting the maximum memory limit (96M). + +Fixes rhbz#989552 +--- + src/modules/bluetooth/module-bluetooth-device.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c +index 6c0c746..d06f669 100644 +--- a/src/modules/bluetooth/module-bluetooth-device.c ++++ b/src/modules/bluetooth/module-bluetooth-device.c +@@ -1116,15 +1116,19 @@ static void thread_func(void *userdata) { + skip_bytes = pa_usec_to_bytes(skip_usec, &u->sample_spec); + + if (skip_bytes > 0) { +- pa_memchunk tmp; +- + pa_log_warn("Skipping %llu us (= %llu bytes) in audio stream", + (unsigned long long) skip_usec, + (unsigned long long) skip_bytes); ++ do { ++ pa_memchunk tmp; ++ uint64_t to_skip = MIN (skip_bytes, 65535); ++ ++ pa_sink_render_full(u->sink, to_skip, &tmp); ++ pa_memblock_unref(tmp.memblock); + +- pa_sink_render_full(u->sink, skip_bytes, &tmp); +- pa_memblock_unref(tmp.memblock); +- u->write_index += skip_bytes; ++ u->write_index += to_skip; ++ skip_bytes -= to_skip; ++ } while (skip_bytes > 0); + + if (u->profile == PROFILE_A2DP) + a2dp_reduce_bitpool(u); +-- +1.8.5.3 + diff --git a/SOURCES/0001-core-Add-an-internal-suspend-cause.patch b/SOURCES/0001-core-Add-an-internal-suspend-cause.patch new file mode 100644 index 0000000..cc077b0 --- /dev/null +++ b/SOURCES/0001-core-Add-an-internal-suspend-cause.patch @@ -0,0 +1,106 @@ +From de2320bdcce51adcc11958b9f1b7e998e9ef730f Mon Sep 17 00:00:00 2001 +From: Arun Raghavan +Date: Mon, 23 Jul 2012 14:20:05 +0530 +Subject: [PATCH] core: Add an "internal" suspend cause + +This lets us suspend devices from within the core for short periods +without having to overload one of the existing suspend causes. + +https://bugs.freedesktop.org/show_bug.cgi?id=64118 +--- + src/pulsecore/core.h | 1 + + src/pulsecore/sink.c | 11 ++++++++--- + src/pulsecore/source.c | 11 ++++++++--- + 3 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h +index cf7cc11..6b5b16a 100644 +--- a/src/pulsecore/core.h ++++ b/src/pulsecore/core.h +@@ -36,6 +36,7 @@ typedef enum pa_suspend_cause { + PA_SUSPEND_IDLE = 4, /* Used by module-suspend-on-idle */ + PA_SUSPEND_SESSION = 8, /* Used by module-hal for mark inactive sessions */ + PA_SUSPEND_PASSTHROUGH = 16, /* Used to suspend monitor sources when the sink is in passthrough mode */ ++ PA_SUSPEND_INTERNAL = 32, /* This is used for short period server-internal suspends, such as for sample rate updates */ + PA_SUSPEND_ALL = 0xFFFF /* Magic cause that can be used to resume forcibly */ + } pa_suspend_cause_t; + +diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c +index 4512470..1522e60 100644 +--- a/src/pulsecore/sink.c ++++ b/src/pulsecore/sink.c +@@ -1337,6 +1337,8 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) { + /* Called from main thread */ + pa_bool_t pa_sink_update_rate(pa_sink *s, uint32_t rate, pa_bool_t passthrough) + { ++ pa_bool_t ret = FALSE; ++ + if (s->update_rate) { + uint32_t desired_rate = rate; + uint32_t default_rate = s->default_sample_rate; +@@ -1395,7 +1397,7 @@ pa_bool_t pa_sink_update_rate(pa_sink *s, uint32_t rate, pa_bool_t passthrough) + if (!passthrough && pa_sink_used_by(s) > 0) + return FALSE; + +- pa_sink_suspend(s, TRUE, PA_SUSPEND_IDLE); /* needed before rate update, will be resumed automatically */ ++ pa_sink_suspend(s, TRUE, PA_SUSPEND_INTERNAL); + + if (s->update_rate(s, desired_rate) == TRUE) { + /* update monitor source as well */ +@@ -1408,10 +1410,13 @@ pa_bool_t pa_sink_update_rate(pa_sink *s, uint32_t rate, pa_bool_t passthrough) + pa_sink_input_update_rate(i); + } + +- return TRUE; ++ ret = TRUE; + } ++ ++ pa_sink_suspend(s, FALSE, PA_SUSPEND_INTERNAL); + } +- return FALSE; ++ ++ return ret ; + } + + /* Called from main thread */ +diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c +index e9c3669..5c264e0 100644 +--- a/src/pulsecore/source.c ++++ b/src/pulsecore/source.c +@@ -955,6 +955,8 @@ void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk * + /* Called from main thread */ + pa_bool_t pa_source_update_rate(pa_source *s, uint32_t rate, pa_bool_t passthrough) + { ++ pa_bool_t ret = FALSE; ++ + if (s->update_rate) { + uint32_t desired_rate = rate; + uint32_t default_rate = s->default_sample_rate; +@@ -1006,7 +1008,7 @@ pa_bool_t pa_source_update_rate(pa_source *s, uint32_t rate, pa_bool_t passthrou + if (!passthrough && pa_source_used_by(s) > 0) + return FALSE; + +- pa_source_suspend(s, TRUE, PA_SUSPEND_IDLE); /* needed before rate update, will be resumed automatically */ ++ pa_source_suspend(s, TRUE, PA_SUSPEND_INTERNAL); + + if (s->update_rate(s, desired_rate) == TRUE) { + pa_log_info("Changed sampling rate successfully "); +@@ -1015,10 +1017,13 @@ pa_bool_t pa_source_update_rate(pa_source *s, uint32_t rate, pa_bool_t passthrou + if (o->state == PA_SOURCE_OUTPUT_CORKED) + pa_source_output_update_rate(o); + } +- return TRUE; ++ ret = TRUE; + } ++ ++ pa_source_suspend(s, FALSE, PA_SUSPEND_INTERNAL); + } +- return FALSE; ++ ++ return ret; + } + + /* Called from main thread */ +-- +1.9.3 + diff --git a/SOURCES/0001-core-Fix-resource-leak-in-core-util.patch b/SOURCES/0001-core-Fix-resource-leak-in-core-util.patch new file mode 100644 index 0000000..c8cf8d1 --- /dev/null +++ b/SOURCES/0001-core-Fix-resource-leak-in-core-util.patch @@ -0,0 +1,42 @@ +From 9c6e30f14e252fde87f7c851233180d03e29dcd3 Mon Sep 17 00:00:00 2001 +From: Peter Meerwald +Date: Mon, 16 Dec 2013 16:35:50 +0100 +Subject: [PATCH 1/3] core: Fix resource leak in core-util + +https://scan7.coverity.com:8443/reports.htm#v10205/p10016/fileInstanceId=8477&defectInstanceId=3693&mergedDefectId=591269 + +Signed-off-by: Peter Meerwald +--- + src/pulsecore/core-util.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c +index 2685c78..bdfafd0 100644 +--- a/src/pulsecore/core-util.c ++++ b/src/pulsecore/core-util.c +@@ -278,16 +278,20 @@ again: + goto fail; + } + +- if (!update_perms) ++ if (!update_perms) { ++ pa_assert_se(pa_close(fd) >= 0); + return 0; ++ } + + #ifdef HAVE_FCHOWN + if (uid == (uid_t) -1) + uid = getuid(); + if (gid == (gid_t) -1) + gid = getgid(); +- if (fchown(fd, uid, gid) < 0) ++ if (fchown(fd, uid, gid) < 0) { ++ pa_assert_se(pa_close(fd) >= 0); + goto fail; ++ } + #endif + + #ifdef HAVE_FCHMOD +-- +1.9.3 + diff --git a/SOURCES/0001-tests-Fix-potential-out-of-bound-access-violation-in.patch b/SOURCES/0001-tests-Fix-potential-out-of-bound-access-violation-in.patch new file mode 100644 index 0000000..e574f50 --- /dev/null +++ b/SOURCES/0001-tests-Fix-potential-out-of-bound-access-violation-in.patch @@ -0,0 +1,32 @@ +From 1d1a26eec5020a7029fdd2e359c3922a6d9a34e8 Mon Sep 17 00:00:00 2001 +From: Peter Meerwald +Date: Wed, 30 Jan 2013 11:03:57 +0100 +Subject: [PATCH] tests: Fix potential out-of-bound access violation in svolume + cpu-test + +nsamples should be forced to be a multiple of channels; do so correctly +and don't make nsamples larger than it actually is + +Signed-off-by: Peter Meerwald +--- + src/tests/cpu-test.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/tests/cpu-test.c b/src/tests/cpu-test.c +index 8e196e5..98a6e92 100644 +--- a/src/tests/cpu-test.c ++++ b/src/tests/cpu-test.c +@@ -84,8 +84,8 @@ static void run_volume_test(pa_do_volume_func_t func, pa_do_volume_func_t orig_f + samples_orig = s_orig + (8 - align); + nsamples = SAMPLES - (8 - align); + if (nsamples % channels) +- nsamples += nsamples % channels; +- size = nsamples * sizeof(*samples); ++ nsamples -= nsamples % channels; ++ size = nsamples * sizeof(int16_t); + + pa_random(samples, size); + memcpy(samples_ref, samples, size); +-- +1.9.3 + diff --git a/SOURCES/0002-alsa-mixer-Add-more-jack-detection-for-Headset-mic-p.patch b/SOURCES/0002-alsa-mixer-Add-more-jack-detection-for-Headset-mic-p.patch new file mode 100644 index 0000000..96cd162 --- /dev/null +++ b/SOURCES/0002-alsa-mixer-Add-more-jack-detection-for-Headset-mic-p.patch @@ -0,0 +1,39 @@ +From 725b1cdc0b58b4015a7dd5526f05a9d1b2d458cf Mon Sep 17 00:00:00 2001 +From: David Henningsson +Date: Fri, 12 Apr 2013 11:56:17 +0200 +Subject: [PATCH 2/2] alsa-mixer: Add more jack detection for Headset mic path + +On some machines which has a headset jack, the headset mic does not have its own +jack detection. Then we can look at the headphone jack to get some indication: +We know that if the headphone is unplugged, so is the headset mic. The opposite +is not guaranteed since the user might have plugged in a headphone, not a headset. + +Also, there exist multi-function jacks which support both Headphone, Mic in headphone jack +and Headset Mic. In this case the jack name will be "Headphone Mic", not "Headphone", so +we need to include this name too. + +Signed-off-by: David Henningsson +--- + src/modules/alsa/mixer/paths/analog-input-headset-mic.conf | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/modules/alsa/mixer/paths/analog-input-headset-mic.conf b/src/modules/alsa/mixer/paths/analog-input-headset-mic.conf +index c5aff1c..83f7d29 100644 +--- a/src/modules/alsa/mixer/paths/analog-input-headset-mic.conf ++++ b/src/modules/alsa/mixer/paths/analog-input-headset-mic.conf +@@ -30,6 +30,12 @@ state.plugged = unknown + state.unplugged = unknown + required-any = any + ++[Jack Headphone] ++state.plugged = unknown ++ ++[Jack Headphone Mic] ++state.plugged = unknown ++ + [Element Headset Mic Boost] + required-any = any + switch = select +-- +1.8.5.3 + diff --git a/SOURCES/0002-combine-sink-rework-output-add-remove.patch b/SOURCES/0002-combine-sink-rework-output-add-remove.patch new file mode 100644 index 0000000..acaa3cb --- /dev/null +++ b/SOURCES/0002-combine-sink-rework-output-add-remove.patch @@ -0,0 +1,87 @@ +From b920e008f405232114750ee2419a059ccc7b8858 Mon Sep 17 00:00:00 2001 +From: Wim Taymans +Date: Tue, 27 May 2014 21:37:02 +0200 +Subject: [PATCH 2/7] combine-sink: rework output add/remove + +Add the output from its sink-input attached callback and remove it +again from the detach callback. This simplifies some output_enable +and we can also avoid posting 2 messages for the sink. +--- + src/modules/module-combine-sink.c | 27 +++++++++++---------------- + 1 file changed, 11 insertions(+), 16 deletions(-) + +diff --git a/src/modules/module-combine-sink.c b/src/modules/module-combine-sink.c +index 488f69f..2730891 100644 +--- a/src/modules/module-combine-sink.c ++++ b/src/modules/module-combine-sink.c +@@ -516,8 +516,9 @@ static void sink_input_attach_cb(pa_sink_input *i) { + c = pa_sink_get_requested_latency_within_thread(i->sink); + pa_atomic_store(&o->requested_latency, (int) (c == (pa_usec_t) -1 ? 0 : c)); + +- pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_MAX_REQUEST, NULL, 0, NULL, NULL); +- pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_REQUESTED_LATENCY, NULL, 0, NULL, NULL); ++ /* We register the output. That means that the sink will start to pass data to ++ * this output. */ ++ pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_ADD_OUTPUT, o, 0, NULL); + } + + /* Called from I/O thread context */ +@@ -527,6 +528,10 @@ static void sink_input_detach_cb(pa_sink_input *i) { + pa_sink_input_assert_ref(i); + pa_assert_se(o = i->userdata); + ++ /* We unregister the output. That means that the sink doesn't ++ * pass any further data to this output */ ++ pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); ++ + if (o->inq_rtpoll_item_read) { + pa_rtpoll_item_free(o->inq_rtpoll_item_read); + o->inq_rtpoll_item_read = NULL; +@@ -709,6 +714,7 @@ static void output_add_within_thread(struct output *o) { + + /* Called from thread context of the io thread */ + static void output_remove_within_thread(struct output *o) { ++ + pa_assert(o); + pa_sink_assert_io_context(o->sink); + +@@ -957,18 +963,11 @@ static void output_enable(struct output *o) { + if (output_create_sink_input(o) >= 0) { + + if (pa_sink_get_state(o->sink) != PA_SINK_INIT) { +- +- /* First we register the output. That means that the sink +- * will start to pass data to this output. */ +- pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_ADD_OUTPUT, o, 0, NULL); +- +- /* Then we enable the sink input. That means that the sink ++ /* Enable the sink input. That means that the sink + * is now asked for new data. */ + pa_sink_input_put(o->sink_input); + +- } else +- /* Hmm the sink is not yet started, do things right here */ +- output_add_within_thread(o); ++ } + } + + o->ignore_state_change = FALSE; +@@ -981,14 +980,10 @@ static void output_disable(struct output *o) { + if (!o->sink_input) + return; + +- /* First we disable the sink input. That means that the sink is ++ /* We disable the sink input. That means that the sink is + * not asked for new data anymore */ + pa_sink_input_unlink(o->sink_input); + +- /* Then we unregister the output. That means that the sink doesn't +- * pass any further data to this output */ +- pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); +- + /* Now deallocate the stream */ + pa_sink_input_unref(o->sink_input); + o->sink_input = NULL; +-- +1.9.3 + diff --git a/SOURCES/0002-core-util-Call-fchown-only-when-necessary.patch b/SOURCES/0002-core-util-Call-fchown-only-when-necessary.patch new file mode 100644 index 0000000..ef45db7 --- /dev/null +++ b/SOURCES/0002-core-util-Call-fchown-only-when-necessary.patch @@ -0,0 +1,28 @@ +From 428010b2358fc493feab702c736610028cd9a31a Mon Sep 17 00:00:00 2001 +From: Bradley Broom +Date: Fri, 25 Apr 2014 13:00:00 +0300 +Subject: [PATCH 2/3] core-util: Call fchown() only when necessary + +This reportedly fixes some cases where the home directory is on NFS. + +BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=45656 +--- + src/pulsecore/core-util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c +index bdfafd0..c8827ac 100644 +--- a/src/pulsecore/core-util.c ++++ b/src/pulsecore/core-util.c +@@ -288,7 +288,7 @@ again: + uid = getuid(); + if (gid == (gid_t) -1) + gid = getgid(); +- if (fchown(fd, uid, gid) < 0) { ++ if (((st.st_uid != uid) || (st.st_gid != gid)) && fchown(fd, uid, gid) < 0) { + pa_assert_se(pa_close(fd) >= 0); + goto fail; + } +-- +1.9.3 + diff --git a/SOURCES/0003-combine-sink-add-support-for-DYNAMIC_LATENCY.patch b/SOURCES/0003-combine-sink-add-support-for-DYNAMIC_LATENCY.patch new file mode 100644 index 0000000..b82b74e --- /dev/null +++ b/SOURCES/0003-combine-sink-add-support-for-DYNAMIC_LATENCY.patch @@ -0,0 +1,337 @@ +From 12ef9f32c15604f958a4b913d8f45685dd284ff8 Mon Sep 17 00:00:00 2001 +From: Wim Taymans +Date: Tue, 10 Jun 2014 21:38:28 +0200 +Subject: [PATCH 3/7] combine-sink: add support for DYNAMIC_LATENCY + +Mark the sink as DYNAMIC_LATENCY and implement update_sink_latency_range +on its sink-input to collect the combined latency range of all sinks. + +Implement update_requested_latency on the sink to configure the final +latency by combining the sink-input requested latencies. This makes us +honour the client latency request. + +Also add more debug log. + +Fixes https://bugs.freedesktop.org/show_bug.cgi?id=47899 +--- + src/modules/module-combine-sink.c | 142 ++++++++++++++++++++++++++++---------- + 1 file changed, 107 insertions(+), 35 deletions(-) + +diff --git a/src/modules/module-combine-sink.c b/src/modules/module-combine-sink.c +index 2730891..cf318c5 100644 +--- a/src/modules/module-combine-sink.c ++++ b/src/modules/module-combine-sink.c +@@ -104,7 +104,8 @@ struct output { + + /* For communication of the stream parameters to the sink thread */ + pa_atomic_t max_request; +- pa_atomic_t requested_latency; ++ pa_atomic_t max_latency; ++ pa_atomic_t min_latency; + + PA_LLIST_FIELDS(struct output); + }; +@@ -131,6 +132,8 @@ struct userdata { + pa_resample_method_t resample_method; + + pa_usec_t block_usec; ++ pa_usec_t default_min_latency; ++ pa_usec_t default_max_latency; + + pa_idxset* outputs; /* managed in main context */ + +@@ -150,11 +153,12 @@ enum { + SINK_MESSAGE_NEED, + SINK_MESSAGE_UPDATE_LATENCY, + SINK_MESSAGE_UPDATE_MAX_REQUEST, +- SINK_MESSAGE_UPDATE_REQUESTED_LATENCY ++ SINK_MESSAGE_UPDATE_LATENCY_RANGE + }; + + enum { + SINK_INPUT_MESSAGE_POST = PA_SINK_INPUT_MESSAGE_MAX, ++ SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY + }; + + static void output_disable(struct output *o); +@@ -463,35 +467,44 @@ static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) { + return; + + pa_atomic_store(&o->max_request, (int) nbytes); ++ pa_log_debug("Sink input update max request %lu", (unsigned long) nbytes); + pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_MAX_REQUEST, NULL, 0, NULL, NULL); + } + + /* Called from thread context */ +-static void sink_input_update_sink_requested_latency_cb(pa_sink_input *i) { ++static void sink_input_update_sink_latency_range_cb(pa_sink_input *i) { + struct output *o; +- pa_usec_t c; ++ pa_usec_t min, max, fix; + + pa_assert(i); + + pa_sink_input_assert_ref(i); + pa_assert_se(o = i->userdata); + +- c = pa_sink_get_requested_latency_within_thread(i->sink); +- +- if (c == (pa_usec_t) -1) +- c = i->sink->thread_info.max_latency; ++ fix = i->sink->thread_info.fixed_latency; ++ if (fix > 0) { ++ min = fix; ++ max = fix; ++ } else { ++ min = i->sink->thread_info.min_latency; ++ max = i->sink->thread_info.max_latency; ++ } + +- if (pa_atomic_load(&o->requested_latency) == (int) c) ++ if ((pa_atomic_load(&o->min_latency) == (int) min) && ++ (pa_atomic_load(&o->max_latency) == (int) max)) + return; + +- pa_atomic_store(&o->requested_latency, (int) c); +- pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_REQUESTED_LATENCY, NULL, 0, NULL, NULL); ++ pa_atomic_store(&o->min_latency, (int) min); ++ pa_atomic_store(&o->max_latency, (int) max); ++ pa_log_debug("Sink input update latency range %lu %lu", (unsigned long) min, (unsigned long) max); ++ pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_LATENCY_RANGE, NULL, 0, NULL, NULL); + } + + /* Called from I/O thread context */ + static void sink_input_attach_cb(pa_sink_input *i) { + struct output *o; +- pa_usec_t c; ++ pa_usec_t fix, min, max; ++ size_t nbytes; + + pa_sink_input_assert_ref(i); + pa_assert_se(o = i->userdata); +@@ -511,10 +524,20 @@ static void sink_input_attach_cb(pa_sink_input *i) { + + pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE); + +- pa_atomic_store(&o->max_request, (int) pa_sink_input_get_max_request(i)); ++ nbytes = pa_sink_input_get_max_request(i); ++ pa_atomic_store(&o->max_request, (int) nbytes); ++ pa_log_debug("attach max request %lu", (unsigned long) nbytes); + +- c = pa_sink_get_requested_latency_within_thread(i->sink); +- pa_atomic_store(&o->requested_latency, (int) (c == (pa_usec_t) -1 ? 0 : c)); ++ fix = i->sink->thread_info.fixed_latency; ++ if (fix > 0) { ++ min = max = fix; ++ } else { ++ min = i->sink->thread_info.min_latency; ++ max = i->sink->thread_info.max_latency; ++ } ++ pa_atomic_store(&o->min_latency, (int) min); ++ pa_atomic_store(&o->max_latency, (int) max); ++ pa_log_debug("attach latency range %lu %lu", (unsigned long) min, (unsigned long) max); + + /* We register the output. That means that the sink will start to pass data to + * this output. */ +@@ -541,6 +564,7 @@ static void sink_input_detach_cb(pa_sink_input *i) { + pa_rtpoll_item_free(o->outq_rtpoll_item_write); + o->outq_rtpoll_item_write = NULL; + } ++ + } + + /* Called from main context */ +@@ -578,6 +602,14 @@ static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64 + pa_memblockq_flush_write(o->memblockq, TRUE); + + return 0; ++ ++ case SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY: { ++ pa_usec_t latency = (pa_usec_t) offset; ++ ++ pa_sink_input_set_requested_latency_within_thread(o->sink_input, latency); ++ ++ return 0; ++ } + } + + return pa_sink_input_process_msg(obj, code, data, offset, chunk); +@@ -666,31 +698,42 @@ static void update_max_request(struct userdata *u) { + if (max_request <= 0) + max_request = pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec); + ++ pa_log_debug("Sink update max request %lu", (unsigned long) max_request); + pa_sink_set_max_request_within_thread(u->sink, max_request); + } + + /* Called from IO context */ +-static void update_fixed_latency(struct userdata *u) { +- pa_usec_t fixed_latency = 0; ++static void update_latency_range(struct userdata *u) { ++ pa_usec_t min_latency = 0, max_latency = (pa_usec_t) -1; + struct output *o; + + pa_assert(u); + pa_sink_assert_io_context(u->sink); + +- /* Collects the requested_latency values of all streams and sets +- * the largest one as fixed_latency locally */ +- ++ /* Collects the latency_range values of all streams and sets ++ * the max of min and min of max locally */ + PA_LLIST_FOREACH(o, u->thread_info.active_outputs) { +- pa_usec_t rl = (size_t) pa_atomic_load(&o->requested_latency); ++ pa_usec_t min = (size_t) pa_atomic_load(&o->min_latency); ++ pa_usec_t max = (size_t) pa_atomic_load(&o->max_latency); + +- if (rl > fixed_latency) +- fixed_latency = rl; ++ if (min > min_latency) ++ min_latency = min; ++ if (max_latency == (pa_usec_t) -1 || max < max_latency) ++ max_latency = max; ++ } ++ if (max_latency == (pa_usec_t) -1) { ++ /* no outputs, use block size */ ++ min_latency = u->default_min_latency; ++ max_latency = u->default_max_latency; + } ++ else if (max_latency < min_latency) ++ max_latency = min_latency; + +- if (fixed_latency <= 0) +- fixed_latency = u->block_usec; ++ /* never go below the min_latency or BLOCK_USEC */ ++ max_latency = MIN (max_latency, MAX (min_latency, BLOCK_USEC)); + +- pa_sink_set_fixed_latency_within_thread(u->sink, fixed_latency); ++ pa_log_debug("Sink update latency range %lu %lu", min_latency, max_latency); ++ pa_sink_set_latency_range_within_thread(u->sink, min_latency, max_latency); + } + + /* Called from thread context of the io thread */ +@@ -714,7 +757,6 @@ static void output_add_within_thread(struct output *o) { + + /* Called from thread context of the io thread */ + static void output_remove_within_thread(struct output *o) { +- + pa_assert(o); + pa_sink_assert_io_context(o->sink); + +@@ -731,6 +773,28 @@ static void output_remove_within_thread(struct output *o) { + } + } + ++/* Called from sink I/O thread context */ ++static void sink_update_requested_latency(pa_sink *s) { ++ struct userdata *u; ++ struct output *o; ++ ++ pa_sink_assert_ref(s); ++ pa_assert_se(u = s->userdata); ++ ++ u->block_usec = pa_sink_get_requested_latency_within_thread(s); ++ ++ if (u->block_usec == (pa_usec_t) -1) ++ u->block_usec = s->thread_info.max_latency; ++ ++ pa_log_debug("Sink update requested latency %0.2f", (double) u->block_usec / PA_USEC_PER_MSEC); ++ ++ /* Just hand this one over to all sink_inputs */ ++ PA_LLIST_FOREACH(o, u->thread_info.active_outputs) { ++ pa_asyncmsgq_post(o->inq, PA_MSGOBJECT(o->sink_input), SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, NULL, u->block_usec, NULL, NULL); ++ } ++} ++ ++ + /* Called from thread context of the io thread */ + static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u = PA_SINK(o)->userdata; +@@ -769,13 +833,13 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse + case SINK_MESSAGE_ADD_OUTPUT: + output_add_within_thread(data); + update_max_request(u); +- update_fixed_latency(u); ++ update_latency_range(u); + return 0; + + case SINK_MESSAGE_REMOVE_OUTPUT: + output_remove_within_thread(data); + update_max_request(u); +- update_fixed_latency(u); ++ update_latency_range(u); + return 0; + + case SINK_MESSAGE_NEED: +@@ -801,9 +865,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse + update_max_request(u); + break; + +- case SINK_MESSAGE_UPDATE_REQUESTED_LATENCY: +- update_fixed_latency(u); ++ case SINK_MESSAGE_UPDATE_LATENCY_RANGE: ++ update_latency_range(u); + break; ++ + } + + return pa_sink_process_msg(o, code, data, offset, chunk); +@@ -875,7 +940,7 @@ static int output_create_sink_input(struct output *o) { + o->sink_input->process_rewind = sink_input_process_rewind_cb; + o->sink_input->update_max_rewind = sink_input_update_max_rewind_cb; + o->sink_input->update_max_request = sink_input_update_max_request_cb; +- o->sink_input->update_sink_requested_latency = sink_input_update_sink_requested_latency_cb; ++ o->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb; + o->sink_input->attach = sink_input_attach_cb; + o->sink_input->detach = sink_input_detach_cb; + o->sink_input->kill = sink_input_kill_cb; +@@ -966,7 +1031,6 @@ static void output_enable(struct output *o) { + /* Enable the sink input. That means that the sink + * is now asked for new data. */ + pa_sink_input_put(o->sink_input); +- + } + } + +@@ -1129,6 +1193,7 @@ int pa__init(pa_module*m) { + uint32_t idx; + pa_sink_new_data data; + uint32_t adjust_time_sec; ++ size_t nbytes; + + pa_assert(m); + +@@ -1257,7 +1322,7 @@ int pa__init(pa_module*m) { + pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Simultaneous Output"); + } + +- u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY); ++ u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY); + pa_sink_new_data_done(&data); + + if (!u->sink) { +@@ -1267,13 +1332,20 @@ int pa__init(pa_module*m) { + + u->sink->parent.process_msg = sink_process_msg; + u->sink->set_state = sink_set_state; ++ u->sink->update_requested_latency = sink_update_requested_latency; + u->sink->userdata = u; + + pa_sink_set_rtpoll(u->sink, u->rtpoll); + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); + + u->block_usec = BLOCK_USEC; +- pa_sink_set_max_request(u->sink, pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec)); ++ nbytes = pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec); ++ pa_sink_set_max_request(u->sink, nbytes); ++ pa_sink_set_latency_range(u->sink, 0, u->block_usec); ++ /* pulse clamps the range, get the real values */ ++ u->default_min_latency = u->sink->thread_info.min_latency; ++ u->default_max_latency = u->sink->thread_info.max_latency; ++ + + if (!u->automatic) { + const char*split_state; +-- +1.9.3 + diff --git a/SOURCES/0003-core-util-Remove-redundant-check-of-directory-permis.patch b/SOURCES/0003-core-util-Remove-redundant-check-of-directory-permis.patch new file mode 100644 index 0000000..37bb8d9 --- /dev/null +++ b/SOURCES/0003-core-util-Remove-redundant-check-of-directory-permis.patch @@ -0,0 +1,69 @@ +From 8a71a8694dfbb79db4c66ae116d2f325d292d541 Mon Sep 17 00:00:00 2001 +From: "Alexander E. Patrakov" +Date: Sun, 20 Apr 2014 21:58:19 +0600 +Subject: [PATCH 3/3] core-util: Remove redundant check of directory + permissions + +Initially (in commit ef422fa4ae626e9638ca70d1c56f27e701dd69c2), +pa_make_secure_dir followed a simple principle: "make a directory, or, +if it exists, check that it is suitable". Later this evolved into "make +a directory, or, if it exists, ensure that it is suitable". But the +check remained. + +The check is now neither sufficient nor necessary. On POSIX-compliant +systems, the fstat results being checked are actually post-conditions of +fchmod and fchown. And on systems implementing POSIX ACLs, fstat only +reflects a part of the information relevant to the security of the +directory permissions, so PulseAudio could accept an existing insecure +directory anyway. + +Also, the check still fires on non-POSIX-compliant filesystems like CIFS. +As a user cannot do anything to fix it, just accept insecure permissions +in this case. +--- + src/pulsecore/core-util.c | 24 +++++------------------- + 1 file changed, 5 insertions(+), 19 deletions(-) + +diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c +index c8827ac..b72541c 100644 +--- a/src/pulsecore/core-util.c ++++ b/src/pulsecore/core-util.c +@@ -295,30 +295,16 @@ again: + #endif + + #ifdef HAVE_FCHMOD +- (void) fchmod(fd, m); ++ if (fchmod(fd, m) < 0) { ++ pa_assert_se(pa_close(fd) >= 0); ++ goto fail; ++ }; + #endif + + pa_assert_se(pa_close(fd) >= 0); + } +-#endif +- +-#ifdef HAVE_LSTAT +- if (lstat(dir, &st) < 0) +-#else +- if (stat(dir, &st) < 0) +-#endif +- goto fail; +- +-#ifndef OS_IS_WIN32 +- if (!S_ISDIR(st.st_mode) || +- (st.st_uid != uid) || +- (st.st_gid != gid) || +- ((st.st_mode & 0777) != m)) { +- errno = EACCES; +- goto fail; +- } + #else +- pa_log_warn("Secure directory creation not supported on Win32."); ++ pa_log_warn("Secure directory creation not supported on this platform."); + #endif + + return 0; +-- +1.9.3 + diff --git a/SOURCES/0004-combine-sink-Make-the-latency-range-calculation-easi.patch b/SOURCES/0004-combine-sink-Make-the-latency-range-calculation-easi.patch new file mode 100644 index 0000000..1ae61e9 --- /dev/null +++ b/SOURCES/0004-combine-sink-Make-the-latency-range-calculation-easi.patch @@ -0,0 +1,45 @@ +From 37225b927ecd3ab7780b9769dfda9136d26f6b5e Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Tue, 17 Jun 2014 12:17:58 +0300 +Subject: [PATCH 4/7] combine-sink: Make the latency range calculation easier + to read + +I think this is much easier to understand. This should not result in +any functional change. +--- + src/modules/module-combine-sink.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/src/modules/module-combine-sink.c b/src/modules/module-combine-sink.c +index cf318c5..37c2c79 100644 +--- a/src/modules/module-combine-sink.c ++++ b/src/modules/module-combine-sink.c +@@ -722,15 +722,20 @@ static void update_latency_range(struct userdata *u) { + max_latency = max; + } + if (max_latency == (pa_usec_t) -1) { +- /* no outputs, use block size */ ++ /* No outputs, use default limits. */ + min_latency = u->default_min_latency; + max_latency = u->default_max_latency; + } +- else if (max_latency < min_latency) +- max_latency = min_latency; + +- /* never go below the min_latency or BLOCK_USEC */ +- max_latency = MIN (max_latency, MAX (min_latency, BLOCK_USEC)); ++ /* As long as we don't support rewinding, we should limit the max latency ++ * to a conservative value. */ ++ if (max_latency > u->default_max_latency) ++ max_latency = u->default_max_latency; ++ ++ /* Never ever try to set lower max latency than min latency, it just ++ * doesn't make sense. */ ++ if (max_latency < min_latency) ++ max_latency = min_latency; + + pa_log_debug("Sink update latency range %lu %lu", min_latency, max_latency); + pa_sink_set_latency_range_within_thread(u->sink, min_latency, max_latency); +-- +1.9.3 + diff --git a/SOURCES/0005-combine-sink-Add-a-convenience-variable.patch b/SOURCES/0005-combine-sink-Add-a-convenience-variable.patch new file mode 100644 index 0000000..45d4c76 --- /dev/null +++ b/SOURCES/0005-combine-sink-Add-a-convenience-variable.patch @@ -0,0 +1,50 @@ +From 7fb7a68d3153d7b4cc1d1f8696be9aa69812b93f Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Tue, 17 Jun 2014 14:01:15 +0300 +Subject: [PATCH 5/7] combine-sink: Add a convenience variable + +--- + src/modules/module-combine-sink.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/src/modules/module-combine-sink.c b/src/modules/module-combine-sink.c +index 37c2c79..8a2e43b 100644 +--- a/src/modules/module-combine-sink.c ++++ b/src/modules/module-combine-sink.c +@@ -915,6 +915,7 @@ static void update_description(struct userdata *u) { + } + + static int output_create_sink_input(struct output *o) { ++ struct userdata *u; + pa_sink_input_new_data data; + + pa_assert(o); +@@ -922,18 +923,20 @@ static int output_create_sink_input(struct output *o) { + if (o->sink_input) + return 0; + ++ u = o->userdata; ++ + pa_sink_input_new_data_init(&data); + pa_sink_input_new_data_set_sink(&data, o->sink, FALSE); + data.driver = __FILE__; + pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME, "Simultaneous output on %s", pa_strnull(pa_proplist_gets(o->sink->proplist, PA_PROP_DEVICE_DESCRIPTION))); + pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "filter"); +- pa_sink_input_new_data_set_sample_spec(&data, &o->userdata->sink->sample_spec); +- pa_sink_input_new_data_set_channel_map(&data, &o->userdata->sink->channel_map); +- data.module = o->userdata->module; +- data.resample_method = o->userdata->resample_method; ++ pa_sink_input_new_data_set_sample_spec(&data, &u->sink->sample_spec); ++ pa_sink_input_new_data_set_channel_map(&data, &u->sink->channel_map); ++ data.module = u->module; ++ data.resample_method = u->resample_method; + data.flags = PA_SINK_INPUT_VARIABLE_RATE|PA_SINK_INPUT_DONT_MOVE|PA_SINK_INPUT_NO_CREATE_ON_SUSPEND; + +- pa_sink_input_new(&o->sink_input, o->userdata->core, &data); ++ pa_sink_input_new(&o->sink_input, u->core, &data); + + pa_sink_input_new_data_done(&data); + +-- +1.9.3 + diff --git a/SOURCES/0006-combine-sink-Fix-the-initial-requested-latency-of-ne.patch b/SOURCES/0006-combine-sink-Fix-the-initial-requested-latency-of-ne.patch new file mode 100644 index 0000000..f614918 --- /dev/null +++ b/SOURCES/0006-combine-sink-Fix-the-initial-requested-latency-of-ne.patch @@ -0,0 +1,28 @@ +From 84bf0fd954489069c171137db24d5ccb43cb2e93 Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Tue, 17 Jun 2014 14:04:43 +0300 +Subject: [PATCH 6/7] combine-sink: Fix the initial requested latency of new + outputs + +If the combine-sink is running with low latency, and a new output is +added, the new output was not configured with low latency. +--- + src/modules/module-combine-sink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/modules/module-combine-sink.c b/src/modules/module-combine-sink.c +index 8a2e43b..0436e34 100644 +--- a/src/modules/module-combine-sink.c ++++ b/src/modules/module-combine-sink.c +@@ -954,7 +954,7 @@ static int output_create_sink_input(struct output *o) { + o->sink_input->kill = sink_input_kill_cb; + o->sink_input->userdata = o; + +- pa_sink_input_set_requested_latency(o->sink_input, BLOCK_USEC); ++ pa_sink_input_set_requested_latency(o->sink_input, pa_sink_get_requested_latency(u->sink)); + + return 0; + } +-- +1.9.3 + diff --git a/SOURCES/0007-combine-sink-Rearrange-block_usec-initialization.patch b/SOURCES/0007-combine-sink-Rearrange-block_usec-initialization.patch new file mode 100644 index 0000000..1afc2aa --- /dev/null +++ b/SOURCES/0007-combine-sink-Rearrange-block_usec-initialization.patch @@ -0,0 +1,37 @@ +From 898b04cfc537325edd5e5d052c544bc004f9918d Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Tue, 17 Jun 2014 14:13:21 +0300 +Subject: [PATCH 7/7] combine-sink: Rearrange block_usec initialization + +block_usec should be determined by the sink max latency, not the other +way around. This change doesn't cause any change in behaviour, but +makes the code more logical. Further updates to block_usec are already +done correctly, so this is the only place that needs modification. +--- + src/modules/module-combine-sink.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/modules/module-combine-sink.c b/src/modules/module-combine-sink.c +index 0436e34..127d0b1 100644 +--- a/src/modules/module-combine-sink.c ++++ b/src/modules/module-combine-sink.c +@@ -1346,13 +1346,13 @@ int pa__init(pa_module*m) { + pa_sink_set_rtpoll(u->sink, u->rtpoll); + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); + +- u->block_usec = BLOCK_USEC; +- nbytes = pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec); ++ nbytes = pa_usec_to_bytes(BLOCK_USEC, &u->sink->sample_spec); + pa_sink_set_max_request(u->sink, nbytes); +- pa_sink_set_latency_range(u->sink, 0, u->block_usec); ++ pa_sink_set_latency_range(u->sink, 0, BLOCK_USEC); + /* pulse clamps the range, get the real values */ + u->default_min_latency = u->sink->thread_info.min_latency; + u->default_max_latency = u->sink->thread_info.max_latency; ++ u->block_usec = u->sink->thread_info.max_latency; + + + if (!u->automatic) { +-- +1.9.3 + diff --git a/SOURCES/pulseaudio-multilib.patch b/SOURCES/pulseaudio-multilib.patch index 013cffe..1fb69d2 100644 --- a/SOURCES/pulseaudio-multilib.patch +++ b/SOURCES/pulseaudio-multilib.patch @@ -18,10 +18,10 @@ diff -up pulseaudio-3.0/src/utils/padsp.in.multlib pulseaudio-3.0/src/utils/pads + if [ x"$LD_PRELOAD" = x ] ; then - LD_PRELOAD="@pkglibdir@/libpulsedsp.so" -+ LD_PRELOAD="$LIBDIR/pulseaudio/libpulsedsp.so" ++ LD_PRELOAD="$LIB_DIR/pulseaudio/libpulsedsp.so" else - LD_PRELOAD="$LD_PRELOAD @pkglibdir@/libpulsedsp.so" -+ LD_PRELOAD="$LD_PRELOAD $LIBDIR/pulseaudio/libpulsedsp.so" ++ LD_PRELOAD="$LD_PRELOAD $LIB_DIR/pulseaudio/libpulsedsp.so" fi export LD_PRELOAD diff --git a/SPECS/pulseaudio.spec b/SPECS/pulseaudio.spec index 63c31cd..ecf08ae 100644 --- a/SPECS/pulseaudio.spec +++ b/SPECS/pulseaudio.spec @@ -10,7 +10,7 @@ Name: pulseaudio Summary: Improved Linux Sound Server Version: %{pa_major}%{?pa_minor:.%{pa_minor}} -Release: 22%{?dist} +Release: 30%{?dist} License: LGPLv2+ URL: http://www.freedesktop.org/wiki/Software/PulseAudio Source0: http://freedesktop.org/software/pulseaudio/releases/pulseaudio-%{version}.tar.xz @@ -29,6 +29,20 @@ Patch110: 0001-daemon-Remove-deprecated-Encoding-from-.desktop-file.patch Patch111: 0001-update-translations.-Related-1030374.patch Patch112: 0001-Add-korean-translation.patch Patch113: 0001-man-improve-man-page-and-help-for-cmdline-options.patch +Patch114: 0001-alsa-mixer-Add-path-for-Headset-Microphone.patch +Patch115: 0002-alsa-mixer-Add-more-jack-detection-for-Headset-mic-p.patch +Patch116: 0001-core-Add-an-internal-suspend-cause.patch +Patch117: 0001-bluetooth-skip-audio-in-smaller-chunks.patch +Patch118: 0002-combine-sink-rework-output-add-remove.patch +Patch119: 0003-combine-sink-add-support-for-DYNAMIC_LATENCY.patch +Patch120: 0004-combine-sink-Make-the-latency-range-calculation-easi.patch +Patch121: 0005-combine-sink-Add-a-convenience-variable.patch +Patch122: 0006-combine-sink-Fix-the-initial-requested-latency-of-ne.patch +Patch123: 0007-combine-sink-Rearrange-block_usec-initialization.patch +Patch124: 0001-core-Fix-resource-leak-in-core-util.patch +Patch125: 0002-core-util-Call-fchown-only-when-necessary.patch +Patch126: 0003-core-util-Remove-redundant-check-of-directory-permis.patch +Patch127: 0001-tests-Fix-potential-out-of-bound-access-violation-in.patch BuildRequires: m4 BuildRequires: libtool-ltdl-devel @@ -222,6 +236,20 @@ This package contains GDM integration hooks for the PulseAudio sound server. %patch111 -p1 -b .111 %patch112 -p1 -b .112 %patch113 -p1 -b .113 +%patch114 -p1 -b .114 +%patch115 -p1 -b .115 +%patch116 -p1 -b .116 +%patch117 -p1 -b .117 +%patch118 -p1 -b .118 +%patch119 -p1 -b .119 +%patch120 -p1 -b .120 +%patch121 -p1 -b .121 +%patch122 -p1 -b .122 +%patch123 -p1 -b .123 +%patch124 -p1 -b .124 +%patch125 -p1 -b .125 +%patch126 -p1 -b .126 +%patch127 -p1 -b .127 ## kill rpaths %if "%{_libdir}" != "/usr/lib" @@ -504,6 +532,38 @@ exit 0 %attr(0600, gdm, gdm) %{_localstatedir}/lib/gdm/.pulse/default.pa %changelog +* Thu Nov 20 2014 Wim Taymans - 3.0-30 +- Fix unit-test buffer overrun +- Resolves: rhbz#1166069 + +* Mon Oct 20 2014 Wim Taymans - 3.0-29 +- Fix multilib patch +- Resolves: rhbz#1154072 + +* Tue Sep 02 2014 Wim Taymans - 3.0-28 +- core-util: Remove redundant check of directory permissions +- core-util: Call fchown() only when necessary +- core: Fix resource leak in core-util +- Resolves: rhbz#1136330 + +* Mon Aug 11 2014 Wim Taymans - 3.0-27 +- Add DYNAMIC latency for module-combine +- Resolves: rhbz#1116346 + +* Mon Aug 11 2014 Wim Taymans - 3.0-26 +- Skip audio in smaller chunks to avoid hitting memory limit +- Resolves: #989552 + +* Tue Aug 05 2014 Wim Taymans - 3.0-25 +- add patch to fix sample rate change when suspend-on-idle is + disabled. +- Resolves: #1116319 + +* Wed Jul 30 2014 Wim Taymans - 3.0-24 +- Add more jack detection for Headset mic path +- Fix dist of new files +- Related #982682 + * Thu Feb 06 2014 Wim Taymans - 3.0-22 - Fix man page and cmdline help - Related #948585