[pulseaudio-commits] 7 commits - src/modules src/pulsecore
Tanu Kaskinen
tanuk at kemper.freedesktop.org
Tue Oct 30 07:39:29 PDT 2012
src/modules/module-combine-sink.c | 8 +++-----
src/modules/module-loopback.c | 14 +++++---------
src/modules/module-match.c | 10 +++++-----
src/modules/module-virtual-surround-sink.c | 4 ++--
src/pulsecore/memblockq.c | 2 +-
src/pulsecore/memblockq.h | 4 ++--
src/pulsecore/resampler.c | 12 ++++++------
7 files changed, 24 insertions(+), 30 deletions(-)
New commits:
commit 0a8634f03e64a84f594bc8533235998e969eda66
Author: Tanu Kaskinen <tanuk at iki.fi>
Date: Thu Sep 27 16:41:59 2012 +0300
match: Use the SINK_INPUT_FIXATE hook instead of NEW.
The callback relies on the sample spec being finalized, which is not
true with the NEW hook.
In case you're wondering about the "hook EARLY - 1, to match before
stream-restore" comment that was not changed even though the code that
the comment concerned was changed: the comment was apparently written
at a time when module-stream-restore used the NEW hook too, and later
stream-restore has been changed to use the FIXATE hook. So, the
comment was wrong/nonsensical before this patch. Since these two
modules now use the same hook again, the comment makes sense again.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=55135
diff --git a/src/modules/module-match.c b/src/modules/module-match.c
index c94ef79..e42f44e 100644
--- a/src/modules/module-match.c
+++ b/src/modules/module-match.c
@@ -80,7 +80,7 @@ struct rule {
struct userdata {
struct rule *rules;
char *property_key;
- pa_hook_slot *sink_input_new_hook_slot;
+ pa_hook_slot *sink_input_fixate_hook_slot;
};
static int load_rules(struct userdata *u, const char *filename) {
@@ -213,7 +213,7 @@ finish:
return ret;
}
-static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *si, struct userdata *u) {
+static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_input_new_data *si, struct userdata *u) {
struct rule *r;
const char *n;
@@ -264,7 +264,7 @@ int pa__init(pa_module*m) {
goto fail;
/* hook EARLY - 1, to match before stream-restore */
- u->sink_input_new_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_EARLY - 1, (pa_hook_cb_t) sink_input_new_hook_callback, u);
+ u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY - 1, (pa_hook_cb_t) sink_input_fixate_hook_callback, u);
pa_modargs_free(ma);
return 0;
@@ -286,8 +286,8 @@ void pa__done(pa_module*m) {
if (!(u = m->userdata))
return;
- if (u->sink_input_new_hook_slot)
- pa_hook_slot_free(u->sink_input_new_hook_slot);
+ if (u->sink_input_fixate_hook_slot)
+ pa_hook_slot_free(u->sink_input_fixate_hook_slot);
if (u->property_key)
pa_xfree(u->property_key);
commit 0da87df4ec0e568a54f4560814e31dfdec4c5b50
Author: Tanu Kaskinen <tanuk at iki.fi>
Date: Thu Sep 20 09:42:18 2012 +0300
combine: Keep the timer active in the null mode only when running.
Previously thread_func() used PA_SINK_IS_OPENED() to check whether
some data should be rendered. process_render_null() used a different
check: it would return immediately if the sink was not in the RUNNING
state. This caused a busy loop when the sink was in the IDLE state,
because process_render_null() didn't update the timestamp, and
thread_func() still kept the timer active using the old timestamp.
pa_rtpoll_run() would return immediately because of the old timestamp.
This is fixed by using the same check in both thread_func() and
process_render_null(). Since the checks are the same, it's actually
redundant to have the check in process_render_null(), so it is now an
assertion.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=54779
diff --git a/src/modules/module-combine-sink.c b/src/modules/module-combine-sink.c
index dec2279..1afdc12 100644
--- a/src/modules/module-combine-sink.c
+++ b/src/modules/module-combine-sink.c
@@ -257,11 +257,9 @@ static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct tim
static void process_render_null(struct userdata *u, pa_usec_t now) {
size_t ate = 0;
- pa_assert(u);
- /* If we are not running, we cannot produce any data */
- if (!pa_atomic_load(&u->thread_info.running))
- return;
+ pa_assert(u);
+ pa_assert(u->sink->thread_info.state == PA_SINK_RUNNING);
if (u->thread_info.in_null_mode)
u->thread_info.timestamp = now;
@@ -312,7 +310,7 @@ static void thread_func(void *userdata) {
pa_sink_process_rewind(u->sink, 0);
/* If no outputs are connected, render some data and drop it immediately. */
- if (PA_SINK_IS_OPENED(u->sink->thread_info.state) && !u->thread_info.active_outputs) {
+ if (u->sink->thread_info.state == PA_SINK_RUNNING && !u->thread_info.active_outputs) {
pa_usec_t now;
now = pa_rtclock_now();
commit 3adbb5ad034684ff751def0144764be8442fb15c
Author: Tanu Kaskinen <tanuk at iki.fi>
Date: Wed Aug 22 09:00:25 2012 +0300
virtual-surround-sink: Fix setting max_request and max_rewind.
The sink has different frame size than the sink input, so
the max_request and max_rewind values of the sink input need
to be converted when setting the sink max_request and
max_rewind values.
The conversion is already done correctly in
sink_input_update_max_request_cb() and
sink_input_update_max_rewind_cb().
diff --git a/src/modules/module-virtual-surround-sink.c b/src/modules/module-virtual-surround-sink.c
index e5c5dc1..4915278 100644
--- a/src/modules/module-virtual-surround-sink.c
+++ b/src/modules/module-virtual-surround-sink.c
@@ -382,11 +382,11 @@ static void sink_input_attach_cb(pa_sink_input *i) {
pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
- pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i));
+ pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i) * u->sink_fs / u->fs);
/* FIXME: Too small max_rewind:
* https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
- pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
+ pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i) * u->sink_fs / u->fs);
pa_sink_attach_within_thread(u->sink);
}
commit 1fc2cf8425eff768e117bb4eff659204fdaf81dc
Author: Tanu Kaskinen <tanu.kaskinen at digia.com>
Date: Tue Aug 14 17:08:35 2012 +0300
loopback: Don't fix the source output format/rate/channels.
Once the sink input has been routed in pa_sink_input_new(),
the sample spec and channel map have already become fixed.
The sink input and source output must use the same stream
format, because the data is copied as-is.
diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index d80494a..461c4a7 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -887,15 +887,6 @@ int pa__init(pa_module *m) {
if (!remix)
source_output_data.flags |= PA_SOURCE_OUTPUT_NO_REMIX;
- if (!format_set)
- source_output_data.flags |= PA_SOURCE_OUTPUT_FIX_FORMAT;
-
- if (!rate_set)
- source_output_data.flags |= PA_SOURCE_OUTPUT_FIX_RATE;
-
- if (!channels_set)
- source_output_data.flags |= PA_SOURCE_OUTPUT_FIX_CHANNELS;
-
source_dont_move = FALSE;
if (pa_modargs_get_value_boolean(ma, "source_dont_move", &source_dont_move) < 0) {
pa_log("source_dont_move= expects a boolean argument.");
commit a68652a42c14e6d2136601d4a34ad1a2e7336e92
Author: Tanu Kaskinen <tanu.kaskinen at digia.com>
Date: Tue Aug 14 17:08:34 2012 +0300
loopback: Use the real sample spec once it's known.
When module-loopback is loaded without arguments, the ss and
map variables are initialized with dummy values. This caused
a problem, because also pa_memblockq_new() was called with
the dummy values, making it work incorrectly. The base was
set to 1 instead of the real frame size, which in turn
caused alignment related crashes.
diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index 26d2e6a..d80494a 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -845,6 +845,11 @@ int pa__init(pa_module *m) {
if (!u->sink_input)
goto fail;
+ /* If format, rate or channels were originally unset, they are set now
+ * after the pa_sink_input_new() call. */
+ ss = u->sink_input->sample_spec;
+ map = u->sink_input->channel_map;
+
u->sink_input->parent.process_msg = sink_input_process_msg_cb;
u->sink_input->pop = sink_input_pop_cb;
u->sink_input->process_rewind = sink_input_process_rewind_cb;
commit e4adf9c4d8a33509828b9b7658d4cccc7f5af563
Author: Tanu Kaskinen <tanuk at iki.fi>
Date: Mon Jul 9 10:07:05 2012 +0300
resampler: Make sure that there are no overflows when multiplying potentially big numbers.
This fixes at least one crash that has been observed. The
multiplication in trivial_resample() overflowed when
resampling from 96 kHz to 48 kHz, causing an assertion
error:
Assertion 'o_index * fz < pa_memblock_get_length(output->memblock)' failed at pulsecore/resampler.c:1521, function trivial_resample(). Aborting.
Without the assertion, the memcpy() after the assertion
would have overwritten some random heap memory.
diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 17f1783..38c5202 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -389,7 +389,7 @@ size_t pa_resampler_request(pa_resampler *r, size_t out_length) {
* loops. When the leftover is ignored here, such loops would eventually
* terminate, because the leftover would grow each round, finally
* surpassing the minimum input threshold of the resampler. */
- return (((((out_length + r->o_fz-1) / r->o_fz) * r->i_ss.rate) + r->o_ss.rate-1) / r->o_ss.rate) * r->i_fz;
+ return ((((uint64_t) ((out_length + r->o_fz-1) / r->o_fz) * r->i_ss.rate) + r->o_ss.rate-1) / r->o_ss.rate) * r->i_fz;
}
size_t pa_resampler_result(pa_resampler *r, size_t in_length) {
@@ -405,7 +405,7 @@ size_t pa_resampler_result(pa_resampler *r, size_t in_length) {
if (r->remap_buf_contains_leftover_data)
frames += r->remap_buf.length / (r->w_sz * r->o_ss.channels);
- return ((frames * r->o_ss.rate + r->i_ss.rate - 1) / r->i_ss.rate) * r->o_fz;
+ return (((uint64_t) frames * r->o_ss.rate + r->i_ss.rate - 1) / r->i_ss.rate) * r->o_fz;
}
size_t pa_resampler_max_block_size(pa_resampler *r) {
@@ -434,7 +434,7 @@ size_t pa_resampler_max_block_size(pa_resampler *r) {
if (r->remap_buf_contains_leftover_data)
frames -= r->remap_buf.length / (r->w_sz * r->o_ss.channels);
- return (frames * r->i_ss.rate / max_ss.rate) * r->i_fz;
+ return ((uint64_t) frames * r->i_ss.rate / max_ss.rate) * r->i_fz;
}
void pa_resampler_reset(pa_resampler *r) {
@@ -1519,7 +1519,7 @@ static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned
dst = pa_memblock_acquire_chunk(output);
for (o_index = 0;; o_index++, r->trivial.o_counter++) {
- i_index = (r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate;
+ i_index = ((uint64_t) r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate;
i_index = i_index > r->trivial.i_counter ? i_index - r->trivial.i_counter : 0;
if (i_index >= in_n_frames)
@@ -1580,11 +1580,11 @@ static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned i
src = pa_memblock_acquire_chunk(input);
dst = pa_memblock_acquire_chunk(output);
- i = (r->peaks.o_counter * r->i_ss.rate) / r->o_ss.rate;
+ i = ((uint64_t) r->peaks.o_counter * r->i_ss.rate) / r->o_ss.rate;
i = i > r->peaks.i_counter ? i - r->peaks.i_counter : 0;
while (i_end < in_n_frames) {
- i_end = ((r->peaks.o_counter+1) * r->i_ss.rate) / r->o_ss.rate;
+ i_end = ((uint64_t) (r->peaks.o_counter + 1) * r->i_ss.rate) / r->o_ss.rate;
i_end = i_end > r->peaks.i_counter ? i_end - r->peaks.i_counter : 0;
pa_assert_fp(o_index * r->w_sz * r->o_ss.channels < pa_memblock_get_length(output->memblock));
commit 9bcb9f1a62bf25a24b97fc34aef55eca10202344
Author: Tanu Kaskinen <tanuk at iki.fi>
Date: Sat Apr 28 18:54:11 2012 +0300
memblockq: Fix the order of setting minreq and prebuf.
diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c
index 18066f7..23bb772 100644
--- a/src/pulsecore/memblockq.c
+++ b/src/pulsecore/memblockq.c
@@ -936,8 +936,8 @@ void pa_memblockq_apply_attr(pa_memblockq *bq, const pa_buffer_attr *a) {
pa_memblockq_set_maxlength(bq, a->maxlength);
pa_memblockq_set_tlength(bq, a->tlength);
- pa_memblockq_set_prebuf(bq, a->prebuf);
pa_memblockq_set_minreq(bq, a->minreq);
+ pa_memblockq_set_prebuf(bq, a->prebuf);
}
void pa_memblockq_get_attr(pa_memblockq *bq, pa_buffer_attr *a) {
diff --git a/src/pulsecore/memblockq.h b/src/pulsecore/memblockq.h
index 08c0bf0..83a5415 100644
--- a/src/pulsecore/memblockq.h
+++ b/src/pulsecore/memblockq.h
@@ -164,8 +164,8 @@ int64_t pa_memblockq_get_write_index(pa_memblockq *bq);
/* Change metrics. Always call in order. */
void pa_memblockq_set_maxlength(pa_memblockq *memblockq, size_t maxlength); /* might modify tlength, prebuf, minreq too */
void pa_memblockq_set_tlength(pa_memblockq *memblockq, size_t tlength); /* might modify minreq, too */
-void pa_memblockq_set_prebuf(pa_memblockq *memblockq, size_t prebuf); /* might modify minreq, too */
-void pa_memblockq_set_minreq(pa_memblockq *memblockq, size_t minreq);
+void pa_memblockq_set_minreq(pa_memblockq *memblockq, size_t minreq); /* might modify prebuf, too */
+void pa_memblockq_set_prebuf(pa_memblockq *memblockq, size_t prebuf);
void pa_memblockq_set_maxrewind(pa_memblockq *memblockq, size_t maxrewind); /* Set the maximum history size */
void pa_memblockq_set_silence(pa_memblockq *memblockq, pa_memchunk *silence);
More information about the pulseaudio-commits
mailing list