Merge branch 'master' into dbus-work

Conflicts:
	src/daemon/daemon-conf.c
This commit is contained in:
Tanu Kaskinen 2009-10-02 17:24:44 +03:00
commit 019331d25b
130 changed files with 24774 additions and 14714 deletions

View file

@ -328,7 +328,7 @@ static int pa_cli_command_source_outputs(pa_core *c, pa_tokenizer *t, pa_strbuf
static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
char ss[PA_SAMPLE_SPEC_SNPRINT_MAX];
char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
char s[256];
char bytes[PA_BYTES_SNPRINT_MAX];
const pa_mempool_stat *stat;
unsigned k;
pa_sink *def_sink;
@ -352,22 +352,22 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_allocated),
pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->allocated_size)));
pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->allocated_size)));
pa_strbuf_printf(buf, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_accumulated),
pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->accumulated_size)));
pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->accumulated_size)));
pa_strbuf_printf(buf, "Memory blocks imported from other processes: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_imported),
pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->imported_size)));
pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->imported_size)));
pa_strbuf_printf(buf, "Memory blocks exported to other processes: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_exported),
pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->exported_size)));
pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->exported_size)));
pa_strbuf_printf(buf, "Total sample cache size: %s.\n",
pa_bytes_snprint(s, sizeof(s), (unsigned) pa_scache_total_size(c)));
pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_scache_total_size(c)));
pa_strbuf_printf(buf, "Default sample spec: %s\n",
pa_sample_spec_snprint(ss, sizeof(ss), &c->default_sample_spec));
@ -529,7 +529,7 @@ static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *bu
return -1;
}
pa_cvolume_set(&cvolume, sink->sample_spec.channels, volume);
pa_cvolume_set(&cvolume, 1, volume);
pa_sink_set_volume(sink, &cvolume, TRUE, TRUE);
return 0;
}
@ -571,7 +571,7 @@ static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strb
return -1;
}
pa_cvolume_set(&cvolume, si->sample_spec.channels, volume);
pa_cvolume_set(&cvolume, 1, volume);
pa_sink_input_set_volume(si, &cvolume, TRUE, TRUE);
return 0;
}
@ -607,7 +607,7 @@ static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *
return -1;
}
pa_cvolume_set(&cvolume, source->sample_spec.channels, volume);
pa_cvolume_set(&cvolume, 1, volume);
pa_source_set_volume(source, &cvolume, TRUE);
return 0;
}
@ -1549,7 +1549,7 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
pa_sink *sink;
pa_source *source;
pa_card *card;
int nl;
pa_bool_t nl;
uint32_t idx;
char txt[256];
time_t now;
@ -1567,7 +1567,7 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime(&now));
#endif
for (m = pa_idxset_first(c->modules, &idx); m; m = pa_idxset_next(c->modules, &idx)) {
PA_IDXSET_FOREACH(m, c->modules, idx) {
pa_strbuf_printf(buf, "load-module %s", m->name);
@ -1577,58 +1577,58 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
pa_strbuf_puts(buf, "\n");
}
nl = 0;
for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) {
nl = FALSE;
PA_IDXSET_FOREACH(sink, c->sinks, idx) {
if (!nl) {
pa_strbuf_puts(buf, "\n");
nl = 1;
nl = TRUE;
}
pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_avg(pa_sink_get_volume(sink, FALSE)));
pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_max(pa_sink_get_volume(sink, FALSE)));
pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink, FALSE)));
pa_strbuf_printf(buf, "suspend-sink %s %s\n", sink->name, pa_yes_no(pa_sink_get_state(sink) == PA_SINK_SUSPENDED));
}
for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) {
nl = FALSE;
PA_IDXSET_FOREACH(source, c->sources, idx) {
if (!nl) {
pa_strbuf_puts(buf, "\n");
nl = 1;
nl = TRUE;
}
pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_avg(pa_source_get_volume(source, FALSE)));
pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_max(pa_source_get_volume(source, FALSE)));
pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source, FALSE)));
pa_strbuf_printf(buf, "suspend-source %s %s\n", source->name, pa_yes_no(pa_source_get_state(source) == PA_SOURCE_SUSPENDED));
}
for (card = pa_idxset_first(c->cards, &idx); card; card = pa_idxset_next(c->cards, &idx)) {
nl = FALSE;
PA_IDXSET_FOREACH(card, c->cards, idx) {
if (!nl) {
pa_strbuf_puts(buf, "\n");
nl = 1;
nl = TRUE;
}
if (card->active_profile)
pa_strbuf_printf(buf, "set-card-profile %s %s\n", card->name, card->active_profile->name);
}
nl = 0;
nl = FALSE;
if ((sink = pa_namereg_get_default_sink(c))) {
if (!nl) {
pa_strbuf_puts(buf, "\n");
nl = 1;
nl = TRUE;
}
pa_strbuf_printf(buf, "set-default-sink %s\n", sink->name);
}
if ((source = pa_namereg_get_default_source(c))) {
if (!nl) {
if (!nl)
pa_strbuf_puts(buf, "\n");
nl = 1;
}
pa_strbuf_printf(buf, "set-default-source %s\n", source->name);
}
@ -1813,8 +1813,6 @@ int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, pa_b
ret = pa_cli_command_execute_file_stream(c, f, buf, fail);
ret = 0;
fail:
if (f)
fclose(f);

View file

@ -113,7 +113,7 @@ static int parse_line(const char *filename, unsigned line, char **section, const
return 0;
if (pa_startswith(b, ".include ")) {
char *path, *fn;
char *path = NULL, *fn;
int r;
fn = strip(b+9);

View file

@ -132,6 +132,8 @@ struct timeval* pa_rtclock_from_wallclock(struct timeval *tv) {
pa_assert(tv);
/* pa_timeval_sub() saturates on underflow! */
if (pa_timeval_cmp(&wc_now, tv) < 0)
pa_timeval_add(&rt_now, pa_timeval_diff(tv, &wc_now));
else
@ -144,13 +146,29 @@ struct timeval* pa_rtclock_from_wallclock(struct timeval *tv) {
}
pa_usec_t pa_timespec_load(const struct timespec *ts) {
pa_assert(ts);
if (PA_UNLIKELY(!ts))
return PA_USEC_INVALID;
return
(pa_usec_t) ts->tv_sec * PA_USEC_PER_SEC +
(pa_usec_t) ts->tv_nsec / PA_NSEC_PER_USEC;
}
struct timespec* pa_timespec_store(struct timespec *ts, pa_usec_t v) {
pa_assert(ts);
if (PA_UNLIKELY(v == PA_USEC_INVALID)) {
ts->tv_sec = PA_INT_TYPE_MAX(time_t);
ts->tv_nsec = (long) (PA_NSEC_PER_SEC-1);
return NULL;
}
ts->tv_sec = (time_t) (v / PA_USEC_PER_SEC);
ts->tv_nsec = (long) ((v % PA_USEC_PER_SEC) * PA_NSEC_PER_USEC);
return ts;
}
static struct timeval* wallclock_from_rtclock(struct timeval *tv) {
@ -162,6 +180,8 @@ static struct timeval* wallclock_from_rtclock(struct timeval *tv) {
pa_assert(tv);
/* pa_timeval_sub() saturates on underflow! */
if (pa_timeval_cmp(&rt_now, tv) < 0)
pa_timeval_add(&wc_now, pa_timeval_diff(tv, &rt_now));
else

View file

@ -44,6 +44,7 @@ void pa_rtclock_hrtimer_enable(void);
struct timeval* pa_rtclock_from_wallclock(struct timeval *tv);
pa_usec_t pa_timespec_load(const struct timespec *ts);
struct timespec* pa_timespec_store(struct timespec *ts, pa_usec_t v);
struct timeval* pa_timeval_rtstore(struct timeval *tv, pa_usec_t v, pa_bool_t rtclock);

View file

@ -335,12 +335,12 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t
pass_volume = TRUE;
if (e->volume_is_set && volume != (pa_volume_t) -1) {
if (e->volume_is_set && volume != PA_VOLUME_INVALID) {
pa_cvolume_set(&r, e->sample_spec.channels, volume);
pa_sw_cvolume_multiply(&r, &r, &e->volume);
} else if (e->volume_is_set)
r = e->volume;
else if (volume != (pa_volume_t) -1)
else if (volume != PA_VOLUME_INVALID)
pa_cvolume_set(&r, e->sample_spec.channels, volume);
else
pass_volume = FALSE;

View file

@ -116,6 +116,7 @@
#include <pulsecore/thread.h>
#include <pulsecore/strbuf.h>
#include <pulsecore/usergroup.h>
#include <pulsecore/strlist.h>
#include "core-util.h"
@ -124,6 +125,8 @@
#define MSG_NOSIGNAL 0
#endif
static pa_strlist *recorded_env = NULL;
#ifdef OS_IS_WIN32
#define PULSE_ROOTENV "PULSE_ROOT"
@ -588,13 +591,13 @@ static int set_scheduler(int rtprio) {
sp.sched_priority = rtprio;
#ifdef SCHED_RESET_ON_FORK
if ((r = pthread_setschedparam(pthread_self(), SCHED_RR|SCHED_RESET_ON_FORK, &sp)) == 0) {
if (pthread_setschedparam(pthread_self(), SCHED_RR|SCHED_RESET_ON_FORK, &sp) == 0) {
pa_log_debug("SCHED_RR|SCHED_RESET_ON_FORK worked.");
return 0;
}
#endif
if ((r = pthread_setschedparam(pthread_self(), SCHED_RR, &sp)) == 0) {
if (pthread_setschedparam(pthread_self(), SCHED_RR, &sp) == 0) {
pa_log_debug("SCHED_RR worked.");
return 0;
}
@ -609,6 +612,11 @@ static int set_scheduler(int rtprio) {
return -1;
}
/* We need to disable exit on disconnect because otherwise
* dbus_shutdown will kill us. See
* https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
dbus_connection_set_exit_on_disconnect(bus, FALSE);
r = rtkit_make_realtime(bus, 0, rtprio);
dbus_connection_unref(bus);
@ -677,6 +685,11 @@ static int set_nice(int nice_level) {
return -1;
}
/* We need to disable exit on disconnect because otherwise
* dbus_shutdown will kill us. See
* https://bugs.freedesktop.org/show_bug.cgi?id=16924 */
dbus_connection_set_exit_on_disconnect(bus, FALSE);
r = rtkit_make_high_priority(bus, 0, nice_level);
dbus_connection_unref(bus);
@ -773,7 +786,6 @@ int pa_match(const char *expr, const char *v) {
/* Try to parse a boolean string value.*/
int pa_parse_boolean(const char *v) {
const char *expr;
int r;
pa_assert(v);
/* First we check language independant */
@ -785,12 +797,12 @@ int pa_parse_boolean(const char *v) {
/* And then we check language dependant */
if ((expr = nl_langinfo(YESEXPR)))
if (expr[0])
if ((r = pa_match(expr, v)) > 0)
if (pa_match(expr, v) > 0)
return 1;
if ((expr = nl_langinfo(NOEXPR)))
if (expr[0])
if ((r = pa_match(expr, v)) > 0)
if (pa_match(expr, v) > 0)
return 0;
errno = EINVAL;
@ -1182,7 +1194,7 @@ char* pa_strip_nl(char *s) {
/* Create a temporary lock file and lock it. */
int pa_lock_lockfile(const char *fn) {
int fd = -1;
int fd;
pa_assert(fn);
for (;;) {
@ -1225,8 +1237,6 @@ int pa_lock_lockfile(const char *fn) {
fd = -1;
goto fail;
}
fd = -1;
}
return fd;
@ -1368,19 +1378,10 @@ static char* make_random_dir(mode_t m) {
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
const char *tmpdir;
char *fn;
size_t pathlen;
if (!(tmpdir = getenv("TMPDIR")))
if (!(tmpdir = getenv("TMP")))
if (!(tmpdir = getenv("TEMP")))
tmpdir = getenv("TEMPDIR");
if (!tmpdir || !pa_is_path_absolute(tmpdir))
tmpdir = "/tmp";
fn = pa_sprintf_malloc("%s/pulse-XXXXXXXXXXXX", tmpdir);
fn = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse-XXXXXXXXXXXX", pa_get_temp_dir());
pathlen = strlen(fn);
for (;;) {
@ -2394,7 +2395,7 @@ int pa_reset_sigs(int except, ...) {
p[i++] = except;
while ((sig = va_arg(ap, int)) >= 0)
sig = p[i++];
p[i++] = sig;
}
p[i] = -1;
@ -2451,9 +2452,38 @@ void pa_set_env(const char *key, const char *value) {
pa_assert(key);
pa_assert(value);
/* This is not thread-safe */
putenv(pa_sprintf_malloc("%s=%s", key, value));
}
void pa_set_env_and_record(const char *key, const char *value) {
pa_assert(key);
pa_assert(value);
/* This is not thread-safe */
pa_set_env(key, value);
recorded_env = pa_strlist_prepend(recorded_env, key);
}
void pa_unset_env_recorded(void) {
/* This is not thread-safe */
for (;;) {
char *s;
recorded_env = pa_strlist_pop(recorded_env, &s);
if (!s)
break;
unsetenv(s);
pa_xfree(s);
}
}
pa_bool_t pa_in_system_mode(void) {
const char *e;
@ -2837,3 +2867,25 @@ pa_bool_t pa_run_from_build_tree(void) {
}
#endif
const char *pa_get_temp_dir(void) {
const char *t;
if ((t = getenv("TMPDIR")) &&
pa_is_path_absolute(t))
return t;
if ((t = getenv("TMP")) &&
pa_is_path_absolute(t))
return t;
if ((t = getenv("TEMP")) &&
pa_is_path_absolute(t))
return t;
if ((t = getenv("TEMPDIR")) &&
pa_is_path_absolute(t))
return t;
return "/tmp";
}

View file

@ -195,6 +195,8 @@ int pa_reset_sigs(int except, ...);
int pa_reset_sigsv(const int except[]);
void pa_set_env(const char *key, const char *value);
void pa_set_env_and_record(const char *key, const char *value);
void pa_unset_env_recorded(void);
pa_bool_t pa_in_system_mode(void);
@ -254,4 +256,6 @@ void pa_reset_personality(void);
pa_bool_t pa_run_from_build_tree(void);
#endif
const char *pa_get_temp_dir(void);
#endif

View file

@ -115,7 +115,7 @@ void pa_cpu_init_x86 (void) {
pa_remap_func_init_mmx (flags);
}
if (flags & PA_CPU_X86_SSE) {
if (flags & (PA_CPU_X86_SSE | PA_CPU_X86_SSE2)) {
pa_volume_func_init_sse (flags);
pa_remap_func_init_sse (flags);
pa_convert_func_init_sse (flags);

View file

@ -130,15 +130,22 @@ void pa_flist_free(pa_flist *l, pa_free_cb_t free_cb) {
}
int pa_flist_push(pa_flist*l, void *p) {
unsigned idx, n, len;
unsigned idx, n;
pa_atomic_ptr_t*cells;
#ifdef PROFILE
unsigned len;
#endif
pa_assert(l);
pa_assert(p);
cells = PA_FLIST_CELLS(l);
n = len = l->size + N_EXTRA_SCAN - (unsigned) pa_atomic_load(&l->length);
n = l->size + N_EXTRA_SCAN - (unsigned) pa_atomic_load(&l->length);
#ifdef PROFILE
len = n;
#endif
_Y;
idx = reduce(l, (unsigned) pa_atomic_load(&l->write_idx));
@ -171,14 +178,21 @@ int pa_flist_push(pa_flist*l, void *p) {
}
void* pa_flist_pop(pa_flist*l) {
unsigned idx, len, n;
unsigned idx, n;
pa_atomic_ptr_t *cells;
#ifdef PROFILE
unsigned len;
#endif
pa_assert(l);
cells = PA_FLIST_CELLS(l);
n = len = (unsigned) pa_atomic_load(&l->length) + N_EXTRA_SCAN;
n = (unsigned) pa_atomic_load(&l->length) + N_EXTRA_SCAN;
#ifdef PROFILE
len = n;
#endif
_Y;
idx = reduce(l, (unsigned) pa_atomic_load(&l->read_idx));

View file

@ -304,6 +304,18 @@ typedef int pa_bool_t;
#define pa_memzero(x,l) (memset((x), 0, (l)))
#define pa_zero(x) (pa_memzero(&(x), sizeof(x)))
#define PA_INT_TYPE_SIGNED(type) (!!((type) 0 > (type) -1))
#define PA_INT_TYPE_MAX(type) \
((type) (PA_INT_TYPE_SIGNED(type) \
? ~(~(type) 0 << (8*sizeof(type)-1)) \
: (type) -1))
#define PA_INT_TYPE_MIN(type) \
((type) (PA_INT_TYPE_SIGNED(type) \
? (~(type) 0 << (8*sizeof(type)-1)) \
: (type) 0))
/* We include this at the very last place */
#include <pulsecore/log.h>

View file

@ -303,10 +303,17 @@ static struct mempool_slot* mempool_slot_by_ptr(pa_mempool *p, void *ptr) {
pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) {
pa_memblock *b = NULL;
struct mempool_slot *slot;
static int mempool_disable = 0;
pa_assert(p);
pa_assert(length);
if (mempool_disable == 0)
mempool_disable = getenv("PULSE_MEMPOOL_DISABLE") ? 1 : -1;
if (mempool_disable > 0)
return NULL;
/* If -1 is passed as length we choose the size for the caller: we
* take the largest size that fits in one of our slots. */
@ -361,6 +368,7 @@ pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, pa_boo
if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks))))
b = pa_xnew(pa_memblock, 1);
PA_REFCNT_INIT(b);
b->pool = p;
b->type = PA_MEMBLOCK_FIXED;
@ -387,6 +395,7 @@ pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, pa_free
if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks))))
b = pa_xnew(pa_memblock, 1);
PA_REFCNT_INIT(b);
b->pool = p;
b->type = PA_MEMBLOCK_USER;
@ -499,13 +508,19 @@ static void memblock_free(pa_memblock *b) {
/* Fall through */
case PA_MEMBLOCK_FIXED:
case PA_MEMBLOCK_APPENDED :
if (pa_flist_push(PA_STATIC_FLIST_GET(unused_memblocks), b) < 0)
pa_xfree(b);
break;
case PA_MEMBLOCK_IMPORTED : {
case PA_MEMBLOCK_APPENDED:
/* We could attached it unused_memblocks, but that would
* probably waste some considerable memory */
pa_xfree(b);
break;
case PA_MEMBLOCK_IMPORTED: {
pa_memimport_segment *segment;
pa_memimport *import;
@ -539,8 +554,7 @@ static void memblock_free(pa_memblock *b) {
struct mempool_slot *slot;
pa_bool_t call_free;
slot = mempool_slot_by_ptr(b->pool, pa_atomic_ptr_load(&b->data));
pa_assert(slot);
pa_assert_se(slot = mempool_slot_by_ptr(b->pool, pa_atomic_ptr_load(&b->data)));
call_free = b->type == PA_MEMBLOCK_POOL_EXTERNAL;
@ -694,7 +708,7 @@ static void memblock_replace_import(pa_memblock *b) {
pa_mempool* pa_mempool_new(pa_bool_t shared, size_t size) {
pa_mempool *p;
char t1[64], t2[64];
char t1[PA_BYTES_SNPRINT_MAX], t2[PA_BYTES_SNPRINT_MAX];
p = pa_xnew(pa_mempool, 1);
@ -891,7 +905,7 @@ static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) {
if (pa_hashmap_size(i->segments) >= PA_MEMIMPORT_SEGMENTS_MAX)
return NULL;
seg = pa_xnew(pa_memimport_segment, 1);
seg = pa_xnew0(pa_memimport_segment, 1);
if (pa_shm_attach_ro(&seg->memory, shm_id) < 0) {
pa_xfree(seg);
@ -899,10 +913,9 @@ static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) {
}
seg->import = i;
seg->n_blocks = 0;
seg->trap = pa_memtrap_add(seg->memory.ptr, seg->memory.size);
pa_hashmap_put(i->segments, PA_UINT32_TO_PTR(shm_id), seg);
pa_hashmap_put(i->segments, PA_UINT32_TO_PTR(seg->memory.id), seg);
return seg;
}

View file

@ -107,7 +107,10 @@ static void memtrap_link(pa_memtrap *m, unsigned j) {
pa_assert(m);
m->prev[j] = NULL;
m->next[j] = memtraps[j];
if ((m->next[j] = memtraps[j]))
m->next[j]->prev[j] = m;
memtraps[j] = m;
}
@ -200,13 +203,13 @@ pa_memtrap *pa_memtrap_update(pa_memtrap *m, const void *start, size_t size) {
goto unlock;
memtrap_unlink(m, j);
j = pa_aupdate_write_swap(aupdate);
pa_aupdate_write_swap(aupdate);
m->start = (void*) start;
m->size = size;
pa_atomic_store(&m->bad, 0);
j = pa_aupdate_write_swap(aupdate);
pa_assert_se(pa_aupdate_write_swap(aupdate) == j);
memtrap_link(m, j);
unlock:

View file

@ -98,7 +98,7 @@ char* pa_namereg_make_valid_name(const char *name) {
if (*name == 0)
return NULL;
n = pa_xmalloc(strlen(name)+1);
n = pa_xnew(char, strlen(name)+1);
for (a = name, b = n; *a && (a-name < PA_NAME_MAX); a++, b++)
*b = (char) (is_valid_char(*a) ? *a : '_');
@ -170,6 +170,17 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t
pa_assert_se(pa_hashmap_put(c->namereg, e->name, e) >= 0);
/* If a sink or source is registered and there was none registered
* before we inform the clients which then can ask for the default
* sink/source which is then assigned. We don't adjust the default
* sink/source here right away to give the module the chance to
* register more sinks/sources before we choose a new default
* sink/source. */
if ((!c->default_sink && type == PA_NAMEREG_SINK) ||
(!c->default_source && type == PA_NAMEREG_SOURCE))
pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
return e->name;
}

View file

@ -81,7 +81,7 @@ static pid_t read_pid(const char *fn, int fd) {
}
static int open_pid_file(const char *fn, int mode) {
int fd = -1;
int fd;
pa_assert(fn);
@ -123,8 +123,6 @@ static int open_pid_file(const char *fn, int mode) {
fd = -1;
goto fail;
}
fd = -1;
}
return fd;

View file

@ -771,7 +771,6 @@ static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *
memcpy(&rvolume, data, sizeof(uint32_t));
rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, rvolume);
data = (const char*)data + sizeof(uint32_t);
if ((conn = pa_idxset_get_by_index(c->protocol->connections, idx)) && conn->sink_input) {
pa_cvolume volume;
@ -809,7 +808,6 @@ static int esd_proto_sample_pan(connection *c, esd_proto_t request, const void *
memcpy(&rvolume, data, sizeof(uint32_t));
rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, rvolume);
data = (const char*)data + sizeof(uint32_t);
volume.values[0] = (lvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
@ -1123,7 +1121,7 @@ static int do_read(connection *c) {
ssize_t r;
size_t l;
void *p;
size_t space;
size_t space = 0;
pa_assert(c->input_memblockq);

View file

@ -628,7 +628,6 @@ static record_stream* record_stream_new(
record_stream *s;
pa_source_output *source_output = NULL;
size_t base;
pa_source_output_new_data data;
pa_assert(c);
@ -682,7 +681,7 @@ static record_stream* record_stream_new(
0,
s->buffer_attr.maxlength,
0,
base = pa_frame_size(&source_output->sample_spec),
pa_frame_size(&source_output->sample_spec),
1,
0,
0,
@ -827,24 +826,26 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
pa_pstream_send_simple_ack(s->connection->pstream, PA_PTR_TO_UINT(userdata));
break;
case PLAYBACK_STREAM_MESSAGE_UPDATE_TLENGTH: {
pa_tagstruct *t;
case PLAYBACK_STREAM_MESSAGE_UPDATE_TLENGTH:
s->buffer_attr.tlength = (uint32_t) offset;
t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED);
pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
pa_tagstruct_putu32(t, s->index);
pa_tagstruct_putu32(t, s->buffer_attr.maxlength);
pa_tagstruct_putu32(t, s->buffer_attr.tlength);
pa_tagstruct_putu32(t, s->buffer_attr.prebuf);
pa_tagstruct_putu32(t, s->buffer_attr.minreq);
pa_tagstruct_put_usec(t, s->configured_sink_latency);
pa_pstream_send_tagstruct(s->connection->pstream, t);
if (s->connection->version >= 15) {
pa_tagstruct *t;
t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED);
pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
pa_tagstruct_putu32(t, s->index);
pa_tagstruct_putu32(t, s->buffer_attr.maxlength);
pa_tagstruct_putu32(t, s->buffer_attr.tlength);
pa_tagstruct_putu32(t, s->buffer_attr.prebuf);
pa_tagstruct_putu32(t, s->buffer_attr.minreq);
pa_tagstruct_put_usec(t, s->configured_sink_latency);
pa_pstream_send_tagstruct(s->connection->pstream, t);
}
break;
}
}
return 0;
@ -2274,6 +2275,8 @@ static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
ret = pa_core_exit(c->protocol->core, FALSE, 0);
CHECK_VALIDITY(c->pstream, ret >= 0, tag, PA_ERR_ACCESS);
pa_log_debug("Client %s asks us to terminate.", pa_strnull(pa_proplist_gets(c->client->proplist, PA_PROP_APPLICATION_PROCESS_BINARY)));
pa_pstream_send_simple_ack(c->pstream, tag); /* nonsense */
}
@ -3390,12 +3393,18 @@ static void command_set_volume(
client_name = pa_strnull(pa_proplist_gets(c->client->proplist, PA_PROP_APPLICATION_PROCESS_BINARY));
if (sink) {
CHECK_VALIDITY(c->pstream, volume.channels == 1 || pa_cvolume_compatible(&volume, &sink->sample_spec), tag, PA_ERR_INVALID);
pa_log_debug("Client %s changes volume of sink %s.", client_name, sink->name);
pa_sink_set_volume(sink, &volume, TRUE, TRUE);
} else if (source) {
CHECK_VALIDITY(c->pstream, volume.channels == 1 || pa_cvolume_compatible(&volume, &source->sample_spec), tag, PA_ERR_INVALID);
pa_log_debug("Client %s changes volume of source %s.", client_name, source->name);
pa_source_set_volume(source, &volume, TRUE);
} else if (si) {
CHECK_VALIDITY(c->pstream, volume.channels == 1 || pa_cvolume_compatible(&volume, &si->sample_spec), tag, PA_ERR_INVALID);
pa_log_debug("Client %s changes volume of sink input %s.",
client_name,
pa_strnull(pa_proplist_gets(si->proplist, PA_PROP_MEDIA_NAME)));
@ -3441,7 +3450,6 @@ static void command_set_mute(
switch (command) {
case PA_COMMAND_SET_SINK_MUTE:
if (idx != PA_INVALID_INDEX)
sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx);
else

View file

@ -154,7 +154,7 @@ static int do_read(connection *c) {
ssize_t r;
size_t l;
void *p;
size_t space;
size_t space = 0;
connection_assert_ref(c);

View file

@ -26,21 +26,31 @@
#include <pulsecore/macro.h>
typedef struct pa_ratelimit {
const pa_usec_t interval;
const unsigned burst;
pa_usec_t interval;
unsigned burst;
unsigned n_printed, n_missed;
pa_usec_t begin;
} pa_ratelimit;
#define PA_DEFINE_RATELIMIT(_name, _interval, _burst) \
pa_ratelimit _name = { \
.interval = _interval, \
.burst = _burst, \
.interval = (_interval), \
.burst = (_burst), \
.n_printed = 0, \
.n_missed = 0, \
.begin = 0 \
}
#define PA_INIT_RATELIMIT(v, _interval, _burst) \
do { \
pa_ratelimit *r = &(v); \
r->interval = (_interval); \
r->burst = (_burst); \
r->n_printed = 0; \
r->n_missed = 0; \
r->begin = 0; \
} while (FALSE);
pa_bool_t pa_ratelimit_test(pa_ratelimit *r);
#endif

View file

@ -65,16 +65,24 @@
" add $32, %1 \n\t" \
" add $64, %0 \n\t"
#define HANDLE_SINGLE(s) \
#define HANDLE_SINGLE_dq() \
" movd (%1), %%mm0 \n\t" \
" punpckl"#s" %%mm0, %%mm0 \n\t" \
" punpckldq %%mm0, %%mm0 \n\t" \
" movq %%mm0, (%0) \n\t" \
" add $4, %1 \n\t" \
" add $8, %0 \n\t"
#define MONO_TO_STEREO(s) \
" mov %3, %2 \n\t" \
" sar $3, %2 \n\t" \
#define HANDLE_SINGLE_wd() \
" movw (%1), %w3 \n\t" \
" movd %3, %%mm0 \n\t" \
" punpcklwd %%mm0, %%mm0 \n\t" \
" movd %%mm0, (%0) \n\t" \
" add $2, %1 \n\t" \
" add $4, %0 \n\t"
#define MONO_TO_STEREO(s,shift,mask) \
" mov %4, %2 \n\t" \
" sar $"#shift", %2 \n\t" \
" cmp $0, %2 \n\t" \
" je 2f \n\t" \
"1: \n\t" \
@ -84,11 +92,11 @@
" dec %2 \n\t" \
" jne 1b \n\t" \
"2: \n\t" \
" mov %3, %2 \n\t" \
" and $7, %2 \n\t" \
" mov %4, %2 \n\t" \
" and $"#mask", %2 \n\t" \
" je 4f \n\t" \
"3: \n\t" \
HANDLE_SINGLE(s) \
HANDLE_SINGLE_##s() \
" dec %2 \n\t" \
" jne 3b \n\t" \
"4: \n\t" \
@ -96,14 +104,14 @@
#if defined (__i386__) || defined (__amd64__)
static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, unsigned n) {
pa_reg_x86 temp;
pa_reg_x86 temp, temp2;
switch (*m->format) {
case PA_SAMPLE_FLOAT32NE:
{
__asm__ __volatile__ (
MONO_TO_STEREO(dq) /* do doubles to quads */
: "+r" (dst), "+r" (src), "=&r" (temp)
MONO_TO_STEREO(dq,3,7) /* do doubles to quads */
: "+r" (dst), "+r" (src), "=&r" (temp), "=&r" (temp2)
: "r" ((pa_reg_x86)n)
: "cc"
);
@ -112,8 +120,8 @@ static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src,
case PA_SAMPLE_S16NE:
{
__asm__ __volatile__ (
MONO_TO_STEREO(wd) /* do words to doubles */
: "+r" (dst), "+r" (src), "=&r" (temp)
MONO_TO_STEREO(wd,4,15) /* do words to doubles */
: "+r" (dst), "+r" (src), "=&r" (temp), "=&r" (temp2)
: "r" ((pa_reg_x86)n)
: "cc"
);
@ -142,8 +150,12 @@ static void init_remap_mmx (pa_remap_t *m) {
void pa_remap_func_init_mmx (pa_cpu_x86_flag_t flags) {
#if defined (__i386__) || defined (__amd64__)
pa_log_info("Initialising MMX optimized remappers.");
pa_set_init_remap_func ((pa_init_remap_func_t) init_remap_mmx);
if (flags & PA_CPU_X86_MMX) {
pa_log_info("Initialising MMX optimized remappers.");
pa_set_init_remap_func ((pa_init_remap_func_t) init_remap_mmx);
}
#endif /* defined (__i386__) || defined (__amd64__) */
}

View file

@ -65,43 +65,52 @@
" add $64, %1 \n\t" \
" add $128, %0 \n\t"
#define HANDLE_SINGLE(s) \
#define HANDLE_SINGLE_dq() \
" movd (%1), %%xmm0 \n\t" \
" punpckl"#s" %%xmm0, %%xmm0 \n\t" \
" punpckldq %%xmm0, %%xmm0 \n\t" \
" movq %%xmm0, (%0) \n\t" \
" add $4, %1 \n\t" \
" add $8, %0 \n\t"
#define MONO_TO_STEREO(s) \
" mov %3, %2 \n\t" \
" sar $4, %2 \n\t" \
" cmp $0, %2 \n\t" \
" je 2f \n\t" \
"1: \n\t" \
LOAD_SAMPLES \
UNPACK_SAMPLES(s) \
STORE_SAMPLES \
" dec %2 \n\t" \
" jne 1b \n\t" \
"2: \n\t" \
" mov %3, %2 \n\t" \
" and $15, %2 \n\t" \
" je 4f \n\t" \
"3: \n\t" \
HANDLE_SINGLE(s) \
" dec %2 \n\t" \
" jne 3b \n\t" \
#define HANDLE_SINGLE_wd() \
" movw (%1), %w3 \n\t" \
" movd %3, %%xmm0 \n\t" \
" punpcklwd %%xmm0, %%xmm0 \n\t" \
" movd %%xmm0, (%0) \n\t" \
" add $2, %1 \n\t" \
" add $4, %0 \n\t"
#define MONO_TO_STEREO(s,shift,mask) \
" mov %4, %2 \n\t" \
" sar $"#shift", %2 \n\t" \
" cmp $0, %2 \n\t" \
" je 2f \n\t" \
"1: \n\t" \
LOAD_SAMPLES \
UNPACK_SAMPLES(s) \
STORE_SAMPLES \
" dec %2 \n\t" \
" jne 1b \n\t" \
"2: \n\t" \
" mov %4, %2 \n\t" \
" and $"#mask", %2 \n\t" \
" je 4f \n\t" \
"3: \n\t" \
HANDLE_SINGLE_##s() \
" dec %2 \n\t" \
" jne 3b \n\t" \
"4: \n\t"
static void remap_mono_to_stereo_sse (pa_remap_t *m, void *dst, const void *src, unsigned n) {
pa_reg_x86 temp;
#if defined (__i386__) || defined (__amd64__)
static void remap_mono_to_stereo_sse2 (pa_remap_t *m, void *dst, const void *src, unsigned n) {
pa_reg_x86 temp, temp2;
switch (*m->format) {
case PA_SAMPLE_FLOAT32NE:
{
__asm__ __volatile__ (
MONO_TO_STEREO(dq) /* do doubles to quads */
: "+r" (dst), "+r" (src), "=&r" (temp)
MONO_TO_STEREO(dq, 4, 15) /* do doubles to quads */
: "+r" (dst), "+r" (src), "=&r" (temp), "=&r" (temp2)
: "r" ((pa_reg_x86)n)
: "cc"
);
@ -110,8 +119,8 @@ static void remap_mono_to_stereo_sse (pa_remap_t *m, void *dst, const void *src,
case PA_SAMPLE_S16NE:
{
__asm__ __volatile__ (
MONO_TO_STEREO(wd) /* do words to doubles */
: "+r" (dst), "+r" (src), "=&r" (temp)
MONO_TO_STEREO(wd, 5, 31) /* do words to doubles */
: "+r" (dst), "+r" (src), "=&r" (temp), "=&r" (temp2)
: "r" ((pa_reg_x86)n)
: "cc"
);
@ -123,7 +132,7 @@ static void remap_mono_to_stereo_sse (pa_remap_t *m, void *dst, const void *src,
}
/* set the function that will execute the remapping based on the matrices */
static void init_remap_sse (pa_remap_t *m) {
static void init_remap_sse2 (pa_remap_t *m) {
unsigned n_oc, n_ic;
n_oc = m->o_ss->channels;
@ -132,15 +141,19 @@ static void init_remap_sse (pa_remap_t *m) {
/* find some common channel remappings, fall back to full matrix operation. */
if (n_ic == 1 && n_oc == 2 &&
m->map_table_f[0][0] >= 1.0 && m->map_table_f[1][0] >= 1.0) {
m->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo_sse;
m->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo_sse2;
pa_log_info("Using SSE mono to stereo remapping");
}
}
#endif /* defined (__i386__) || defined (__amd64__) */
void pa_remap_func_init_sse (pa_cpu_x86_flag_t flags) {
#if defined (__i386__) || defined (__amd64__)
pa_log_info("Initialising SSE optimized remappers.");
pa_set_init_remap_func ((pa_init_remap_func_t) init_remap_sse);
if (flags & PA_CPU_X86_SSE2) {
pa_log_info("Initialising SSE2 optimized remappers.");
pa_set_init_remap_func ((pa_init_remap_func_t) init_remap_sse2);
}
#endif /* defined (__i386__) || defined (__amd64__) */
}

View file

@ -1056,3 +1056,13 @@ void pa_memchunk_sine(pa_memchunk *c, pa_mempool *pool, unsigned rate, unsigned
calc_sine(p, c->length, freq * l / rate);
pa_memblock_release(c->memblock);
}
size_t pa_convert_size(size_t size, const pa_sample_spec *from, const pa_sample_spec *to) {
pa_usec_t usec;
pa_assert(from);
pa_assert(to);
usec = pa_bytes_to_usec_round_up(size, from);
return pa_usec_to_bytes_round_up(usec, to);
}

View file

@ -91,6 +91,8 @@ typedef void (*pa_do_volume_func_t) (void *samples, void *volumes, unsigned chan
pa_do_volume_func_t pa_get_volume_func(pa_sample_format_t f);
void pa_set_volume_func(pa_sample_format_t f, pa_do_volume_func_t func);
size_t pa_convert_size(size_t size, const pa_sample_spec *from, const pa_sample_spec *to);
#define PA_CHANNEL_POSITION_MASK_LEFT \
(PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_LEFT) \

View file

@ -83,7 +83,7 @@ static void pa_sconv_s16le_from_f32ne_sse(unsigned n, const float *a, int16_t *b
"2: \n\t"
" mov %4, %1 \n\t" /* prepare for leftovers */
" and $15, %1 \n\t"
" and $7, %1 \n\t"
" je 4f \n\t"
"3: \n\t"
@ -142,7 +142,7 @@ static void pa_sconv_s16le_from_f32ne_sse2(unsigned n, const float *a, int16_t *
"2: \n\t"
" mov %4, %1 \n\t" /* prepare for leftovers */
" and $15, %1 \n\t"
" and $7, %1 \n\t"
" je 4f \n\t"
"3: \n\t"
@ -218,16 +218,18 @@ static void run_test (void) {
void pa_convert_func_init_sse (pa_cpu_x86_flag_t flags) {
#if defined (__i386__) || defined (__amd64__)
pa_log_info("Initialising SSE optimized conversions.");
#ifdef RUN_TEST
run_test ();
#endif
if (flags & PA_CPU_X86_SSE2)
pa_set_convert_from_float32ne_function (PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse2);
else
pa_set_convert_from_float32ne_function (PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse);
if (flags & PA_CPU_X86_SSE2) {
pa_log_info("Initialising SSE2 optimized conversions.");
pa_set_convert_from_float32ne_function (PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse2);
} else {
pa_log_info("Initialising SSE optimized conversions.");
pa_set_convert_from_float32ne_function (PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse);
}
#endif /* defined (__i386__) || defined (__amd64__) */
}

View file

@ -92,6 +92,18 @@ void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, co
}
}
void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
pa_assert(data);
pa_assert(volume_factor);
if (data->volume_factor_sink_is_set)
pa_sw_cvolume_multiply(&data->volume_factor_sink, &data->volume_factor_sink, volume_factor);
else {
data->volume_factor_sink_is_set = TRUE;
data->volume_factor_sink = *volume_factor;
}
}
void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
pa_assert(data);
@ -141,6 +153,7 @@ int pa_sink_input_new(
char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
pa_channel_map original_cm;
int r;
char *pt;
pa_assert(_i);
pa_assert(core);
@ -176,7 +189,6 @@ int pa_sink_input_new(
pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
}
pa_return_val_if_fail(pa_channel_map_valid(&data->channel_map), -PA_ERR_INVALID);
pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
if (!data->volume_is_set) {
@ -185,15 +197,18 @@ int pa_sink_input_new(
data->save_volume = FALSE;
}
pa_return_val_if_fail(pa_cvolume_valid(&data->volume), -PA_ERR_INVALID);
pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
if (!data->volume_factor_is_set)
pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
pa_return_val_if_fail(pa_cvolume_valid(&data->volume_factor), -PA_ERR_INVALID);
pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
if (!data->volume_factor_sink_is_set)
pa_cvolume_reset(&data->volume_factor_sink, data->sink->sample_spec.channels);
pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor_sink, &data->sink->sample_spec), -PA_ERR_INVALID);
if (!data->muted_is_set)
data->muted = FALSE;
@ -283,6 +298,7 @@ int pa_sink_input_new(
i->volume = data->volume;
i->volume_factor = data->volume_factor;
i->volume_factor_sink = data->volume_factor_sink;
i->real_ratio = i->reference_ratio = data->volume;
pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
@ -338,12 +354,15 @@ int pa_sink_input_new(
if (i->client)
pa_assert_se(pa_idxset_put(i->client->sink_inputs, i, NULL) >= 0);
pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s",
pt = pa_proplist_to_string_sep(i->proplist, "\n ");
pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
i->index,
pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)),
i->sink->name,
pa_sample_spec_snprint(st, sizeof(st), &i->sample_spec),
pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map));
pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
pt);
pa_xfree(pt);
/* Don't forget to call pa_sink_input_put! */
@ -576,7 +595,7 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {
/* Called from thread context */
void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa_memchunk *chunk, pa_cvolume *volume) {
pa_bool_t do_volume_adj_here;
pa_bool_t do_volume_adj_here, need_volume_factor_sink;
pa_bool_t volume_is_norm;
size_t block_size_max_sink, block_size_max_sink_input;
size_t ilength;
@ -624,6 +643,7 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map);
volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.muted;
need_volume_factor_sink = !pa_cvolume_is_norm(&i->volume_factor_sink);
while (!pa_memblockq_is_readable(i->thread_info.render_memblockq)) {
pa_memchunk tchunk;
@ -655,6 +675,7 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
while (tchunk.length > 0) {
pa_memchunk wchunk;
pa_bool_t nvfs = need_volume_factor_sink;
wchunk = tchunk;
pa_memblock_ref(wchunk.memblock);
@ -666,18 +687,41 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
if (do_volume_adj_here && !volume_is_norm) {
pa_memchunk_make_writable(&wchunk, 0);
if (i->thread_info.muted)
if (i->thread_info.muted) {
pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
else
nvfs = FALSE;
} else if (!i->thread_info.resampler && nvfs) {
pa_cvolume v;
/* If we don't need a resampler we can merge the
* post and the pre volume adjustment into one */
pa_sw_cvolume_multiply(&v, &i->thread_info.soft_volume, &i->volume_factor_sink);
pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &v);
nvfs = FALSE;
} else
pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &i->thread_info.soft_volume);
}
if (!i->thread_info.resampler)
if (!i->thread_info.resampler) {
if (nvfs) {
pa_memchunk_make_writable(&wchunk, 0);
pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
}
pa_memblockq_push_align(i->thread_info.render_memblockq, &wchunk);
else {
} else {
pa_memchunk rchunk;
pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
if (nvfs) {
pa_memchunk_make_writable(&rchunk, 0);
pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
}
/* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
if (rchunk.memblock) {
@ -941,12 +985,22 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_boo
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
pa_assert(volume);
pa_assert(pa_cvolume_valid(volume));
pa_assert(pa_cvolume_compatible(volume, &i->sample_spec));
pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &i->sample_spec));
if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
v = i->sink->reference_volume;
pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
volume = pa_sw_cvolume_multiply(&v, &v, volume);
if (pa_cvolume_compatible(volume, &i->sample_spec))
volume = pa_sw_cvolume_multiply(&v, &v, volume);
else
volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume));
} else {
if (!pa_cvolume_compatible(volume, &i->sample_spec)) {
v = i->volume;
volume = pa_cvolume_scale(&v, pa_cvolume_max(volume));
}
}
if (pa_cvolume_equal(volume, &i->volume)) {
@ -1142,7 +1196,6 @@ pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
/* Called from main context */
int pa_sink_input_start_move(pa_sink_input *i) {
pa_source_output *o, *p = NULL;
pa_sink *origin;
int r;
pa_sink_input_assert_ref(i);
@ -1156,8 +1209,6 @@ int pa_sink_input_start_move(pa_sink_input *i) {
if ((r = pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], i)) < 0)
return r;
origin = i->sink;
/* Kill directly connected outputs */
while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
pa_assert(o != p);
@ -1179,6 +1230,7 @@ int pa_sink_input_start_move(pa_sink_input *i) {
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
pa_sink_update_status(i->sink);
pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
i->sink = NULL;
pa_sink_input_unref(i);
@ -1233,6 +1285,8 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
i->save_sink = save;
pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
pa_cvolume_remap(&i->volume_factor_sink, &i->channel_map, &i->sink->channel_map);
if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
i->sink->n_corked++;

View file

@ -100,6 +100,8 @@ struct pa_sink_input {
pa_cvolume volume_factor; /* An internally used volume factor that can be used by modules to apply effects and suchlike without having that visible to the outside */
pa_cvolume soft_volume; /* The internal software volume we apply to all PCM data while it passes through. Usually calculated as real_ratio * volume_factor */
pa_cvolume volume_factor_sink; /* A second volume factor in format of the sink this stream is connected to */
pa_bool_t muted:1;
/* if TRUE then the source we are connected to and/or the volume
@ -273,13 +275,13 @@ typedef struct pa_sink_input_new_data {
pa_sample_spec sample_spec;
pa_channel_map channel_map;
pa_cvolume volume, volume_factor;
pa_cvolume volume, volume_factor, volume_factor_sink;
pa_bool_t muted:1;
pa_bool_t sample_spec_is_set:1;
pa_bool_t channel_map_is_set:1;
pa_bool_t volume_is_set:1, volume_factor_is_set:1;
pa_bool_t volume_is_set:1, volume_factor_is_set:1, volume_factor_sink_is_set:1;
pa_bool_t muted_is_set:1;
pa_bool_t volume_is_absolute:1;
@ -292,6 +294,7 @@ void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const
void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map);
void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume);
void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor);
void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor);
void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute);
void pa_sink_input_new_data_done(pa_sink_input_new_data *data);

View file

@ -778,7 +778,7 @@ static unsigned fill_mix_info(pa_sink *s, size_t *length, pa_mix_info *info, uns
/* Called from IO thread context */
static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, pa_memchunk *result) {
pa_sink_input *i;
void *state = NULL;
void *state;
unsigned p = 0;
unsigned n_unreffed = 0;
@ -790,7 +790,7 @@ static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, pa_memchunk *
/* We optimize for the case where the order of the inputs has not changed */
while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) {
PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
unsigned j;
pa_mix_info* m = NULL;
@ -884,8 +884,6 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
pa_assert(pa_frame_aligned(length, &s->sample_spec));
pa_assert(result);
pa_sink_ref(s);
pa_assert(!s->thread_info.rewind_requested);
pa_assert(s->thread_info.rewind_nbytes == 0);
@ -896,6 +894,8 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
return;
}
pa_sink_ref(s);
if (length <= 0)
length = pa_frame_align(MIX_BUFFER_LENGTH, &s->sample_spec);
@ -973,8 +973,6 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
pa_assert(target->length > 0);
pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
pa_sink_ref(s);
pa_assert(!s->thread_info.rewind_requested);
pa_assert(s->thread_info.rewind_nbytes == 0);
@ -983,6 +981,8 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
return;
}
pa_sink_ref(s);
length = target->length;
block_size_max = pa_mempool_block_size_max(s->core->mempool);
if (length > block_size_max)
@ -1057,11 +1057,16 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {
pa_assert(target->length > 0);
pa_assert(pa_frame_aligned(target->length, &s->sample_spec));
pa_sink_ref(s);
pa_assert(!s->thread_info.rewind_requested);
pa_assert(s->thread_info.rewind_nbytes == 0);
if (s->thread_info.state == PA_SINK_SUSPENDED) {
pa_silence_memchunk(target, &s->sample_spec);
return;
}
pa_sink_ref(s);
l = target->length;
d = 0;
while (l > 0) {
@ -1080,10 +1085,6 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {
/* Called from IO thread context */
void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
pa_mix_info info[MAX_MIX_CHANNELS];
size_t length1st = length;
unsigned n;
pa_sink_assert_ref(s);
pa_sink_assert_io_context(s);
pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
@ -1091,81 +1092,24 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
pa_assert(pa_frame_aligned(length, &s->sample_spec));
pa_assert(result);
pa_sink_ref(s);
pa_assert(!s->thread_info.rewind_requested);
pa_assert(s->thread_info.rewind_nbytes == 0);
pa_assert(length > 0);
pa_sink_ref(s);
n = fill_mix_info(s, &length1st, info, MAX_MIX_CHANNELS);
if (n == 0) {
pa_silence_memchunk_get(&s->core->silence_cache,
s->core->mempool,
result,
&s->sample_spec,
length1st);
} else if (n == 1) {
pa_cvolume volume;
*result = info[0].chunk;
pa_memblock_ref(result->memblock);
if (result->length > length)
result->length = length;
pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&volume)) {
if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) {
pa_memblock_unref(result->memblock);
pa_silence_memchunk_get(&s->core->silence_cache,
s->core->mempool,
result,
&s->sample_spec,
result->length);
} else {
pa_memchunk_make_writable(result, length);
pa_volume_memchunk(result, &s->sample_spec, &volume);
}
}
} else {
void *ptr;
result->index = 0;
result->memblock = pa_memblock_new(s->core->mempool, length);
ptr = pa_memblock_acquire(result->memblock);
result->length = pa_mix(info, n,
(uint8_t*) ptr + result->index, length1st,
&s->sample_spec,
&s->thread_info.soft_volume,
s->thread_info.soft_muted);
pa_memblock_release(result->memblock);
}
inputs_drop(s, info, n, result);
pa_sink_render(s, length, result);
if (result->length < length) {
pa_memchunk chunk;
size_t l, d;
pa_memchunk_make_writable(result, length);
l = length - result->length;
d = result->index + result->length;
while (l > 0) {
chunk = *result;
chunk.index = d;
chunk.length = l;
chunk.memblock = result->memblock;
chunk.index = result->index + result->length;
chunk.length = length - result->length;
pa_sink_render_into(s, &chunk);
pa_sink_render_into_full(s, &chunk);
d += chunk.length;
l -= chunk.length;
}
result->length = length;
}
@ -1408,8 +1352,11 @@ void pa_sink_set_volume(
pa_assert_ctl_context();
pa_assert(PA_SINK_IS_LINKED(s->state));
pa_assert(!volume || pa_cvolume_valid(volume));
pa_assert(!volume || pa_cvolume_compatible(volume, &s->sample_spec));
pa_assert(volume || (s->flags & PA_SINK_FLAT_VOLUME));
pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
/* As a special exception we accept mono volumes on all sinks --
* even on those with more complex channel maps */
/* If volume is NULL we synchronize the sink's real and reference
* volumes with the stream volumes. If it is not NULL we update
@ -1419,7 +1366,10 @@ void pa_sink_set_volume(
if (volume) {
s->reference_volume = *volume;
if (pa_cvolume_compatible(volume, &s->sample_spec))
s->reference_volume = *volume;
else
pa_cvolume_scale(&s->reference_volume, pa_cvolume_max(volume));
if (s->flags & PA_SINK_FLAT_VOLUME) {
/* OK, propagate this volume change back to the inputs */

View file

@ -73,14 +73,18 @@
struct pa_socket_client {
PA_REFCNT_DECLARE;
pa_mainloop_api *mainloop;
int fd;
pa_mainloop_api *mainloop;
pa_io_event *io_event;
pa_time_event *timeout_event;
pa_defer_event *defer_event;
pa_socket_client_cb_t callback;
void *userdata;
pa_bool_t local;
#ifdef HAVE_LIBASYNCNS
asyncns_t *asyncns;
asyncns_query_t * asyncns_query;
@ -92,22 +96,10 @@ static pa_socket_client* socket_client_new(pa_mainloop_api *m) {
pa_socket_client *c;
pa_assert(m);
c = pa_xnew(pa_socket_client, 1);
c = pa_xnew0(pa_socket_client, 1);
PA_REFCNT_INIT(c);
c->mainloop = m;
c->fd = -1;
c->io_event = NULL;
c->timeout_event = NULL;
c->defer_event = NULL;
c->callback = NULL;
c->userdata = NULL;
c->local = FALSE;
#ifdef HAVE_LIBASYNCNS
c->asyncns = NULL;
c->asyncns_io_event = NULL;
c->asyncns_query = NULL;
#endif
return c;
}
@ -163,7 +155,6 @@ static void do_call(pa_socket_client *c) {
}
io = pa_iochannel_new(c->mainloop, c->fd, c->fd);
pa_assert(io);
finish:
if (!io && c->fd >= 0)
@ -172,7 +163,6 @@ finish:
free_events(c);
pa_assert(c->callback);
c->callback(c, io, c->userdata);
pa_socket_client_unref(c);
@ -202,8 +192,6 @@ static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event
}
static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t len) {
int r;
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
pa_assert(sa);
@ -211,7 +199,7 @@ static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t
pa_make_fd_nonblock(c->fd);
if ((r = connect(c->fd, sa, len)) < 0) {
if (connect(c->fd, sa, len) < 0) {
#ifdef OS_IS_WIN32
if (WSAGetLastError() != EWOULDBLOCK) {
pa_log_debug("connect(): %d", WSAGetLastError());
@ -222,9 +210,9 @@ static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t
return -1;
}
pa_assert_se(c->io_event = c->mainloop->io_new(c->mainloop, c->fd, PA_IO_EVENT_OUTPUT, connect_io_cb, c));
c->io_event = c->mainloop->io_new(c->mainloop, c->fd, PA_IO_EVENT_OUTPUT, connect_io_cb, c);
} else
pa_assert_se(c->defer_event = c->mainloop->defer_new(c->mainloop, connect_defer_cb, c));
c->defer_event = c->mainloop->defer_new(c->mainloop, connect_defer_cb, c);
return 0;
}
@ -235,7 +223,7 @@ pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address
pa_assert(m);
pa_assert(port > 0);
memset(&sa, 0, sizeof(sa));
pa_zero(sa);
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
sa.sin_addr.s_addr = htonl(address);
@ -243,28 +231,24 @@ pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address
return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa));
}
#ifdef HAVE_SYS_UN_H
pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename) {
#ifdef HAVE_SYS_UN_H
struct sockaddr_un sa;
pa_assert(m);
pa_assert(filename);
memset(&sa, 0, sizeof(sa));
pa_zero(sa);
sa.sun_family = AF_UNIX;
pa_strlcpy(sa.sun_path, filename, sizeof(sa.sun_path));
return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa));
}
#else /* HAVE_SYS_UN_H */
pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename) {
return NULL;
}
#endif /* HAVE_SYS_UN_H */
}
static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size_t salen) {
pa_assert(c);
@ -302,7 +286,7 @@ pa_socket_client* pa_socket_client_new_sockaddr(pa_mainloop_api *m, const struct
pa_assert(sa);
pa_assert(salen > 0);
pa_assert_se(c = socket_client_new(m));
c = socket_client_new(m);
if (sockaddr_prepare(c, sa, salen) < 0)
goto fail;
@ -359,22 +343,25 @@ void pa_socket_client_set_callback(pa_socket_client *c, pa_socket_client_cb_t on
c->userdata = userdata;
}
#ifdef HAVE_IPV6
pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[16], uint16_t port) {
#ifdef HAVE_IPV6
struct sockaddr_in6 sa;
pa_assert(m);
pa_assert(address);
pa_assert(port > 0);
memset(&sa, 0, sizeof(sa));
pa_zero(sa);
sa.sin6_family = AF_INET6;
sa.sin6_port = htons(port);
memcpy(&sa.sin6_addr, address, sizeof(sa.sin6_addr));
return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa));
}
#else
return NULL;
#endif
}
#ifdef HAVE_LIBASYNCNS
@ -468,14 +455,13 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, pa_bool_t use_
case PA_PARSED_ADDRESS_TCP4: /* Fallthrough */
case PA_PARSED_ADDRESS_TCP6: /* Fallthrough */
case PA_PARSED_ADDRESS_TCP_AUTO:{
case PA_PARSED_ADDRESS_TCP_AUTO: {
struct addrinfo hints;
char port[12];
pa_snprintf(port, sizeof(port), "%u", (unsigned) a.port);
memset(&hints, 0, sizeof(hints));
pa_zero(hints);
if (a.type == PA_PARSED_ADDRESS_TCP4)
hints.ai_family = PF_INET;
#ifdef HAVE_IPV6
@ -494,11 +480,10 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, pa_bool_t use_
if (!(asyncns = asyncns_new(1)))
goto finish;
pa_assert_se(c = socket_client_new(m));
c = socket_client_new(m);
c->asyncns = asyncns;
c->asyncns_io_event = m->io_new(m, asyncns_fd(c->asyncns), PA_IO_EVENT_INPUT, asyncns_cb, c);
c->asyncns_query = asyncns_getaddrinfo(c->asyncns, a.path_or_host, port, &hints);
pa_assert(c->asyncns_query);
pa_assert_se(c->asyncns_query = asyncns_getaddrinfo(c->asyncns, a.path_or_host, port, &hints));
start_timeout(c, use_rtclock);
}
#elif defined(HAVE_GETADDRINFO)
@ -541,6 +526,7 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, pa_bool_t use_
if (!host)
goto finish;
pa_zero(sa);
s.sin_family = AF_INET;
memcpy(&s.sin_addr, host->h_addr, sizeof(struct in_addr));
s.sin_port = htons(a.port);

View file

@ -35,9 +35,7 @@ typedef struct pa_socket_client pa_socket_client;
typedef void (*pa_socket_client_cb_t)(pa_socket_client *c, pa_iochannel*io, void *userdata);
pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port);
#ifdef HAVE_IPV6
pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[16], uint16_t port);
#endif
pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename);
pa_socket_client* pa_socket_client_new_sockaddr(pa_mainloop_api *m, const struct sockaddr *sa, size_t salen);
pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, pa_bool_t use_rtclock, const char *a, uint16_t default_port);

View file

@ -107,6 +107,7 @@ int pa_source_output_new(
pa_resampler *resampler = NULL;
char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
int r;
char *pt;
pa_assert(_o);
pa_assert(core);
@ -247,12 +248,15 @@ int pa_source_output_new(
if (o->direct_on_input)
pa_assert_se(pa_idxset_put(o->direct_on_input->direct_outputs, o, NULL) == 0);
pa_log_info("Created output %u \"%s\" on %s with sample spec %s and channel map %s",
pt = pa_proplist_to_string_sep(o->proplist, "\n ");
pa_log_info("Created output %u \"%s\" on %s with sample spec %s and channel map %s\n %s",
o->index,
pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_MEDIA_NAME)),
o->source->name,
pa_sample_spec_snprint(st, sizeof(st), &o->sample_spec),
pa_channel_map_snprint(cm, sizeof(cm), &o->channel_map));
pa_channel_map_snprint(cm, sizeof(cm), &o->channel_map),
pt);
pa_xfree(pt);
/* Don't forget to call pa_source_output_put! */

View file

@ -760,15 +760,22 @@ void pa_source_set_volume(
pa_bool_t save) {
pa_bool_t real_changed;
pa_cvolume old_volume;
pa_source_assert_ref(s);
pa_assert_ctl_context();
pa_assert(PA_SOURCE_IS_LINKED(s->state));
pa_assert(pa_cvolume_valid(volume));
pa_assert(pa_cvolume_compatible(volume, &s->sample_spec));
pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
real_changed = !pa_cvolume_equal(volume, &s->volume);
s->volume = *volume;
old_volume = s->volume;
if (pa_cvolume_compatible(volume, &s->sample_spec))
s->volume = *volume;
else
pa_cvolume_scale(&s->volume, pa_cvolume_max(volume));
real_changed = !pa_cvolume_equal(&old_volume, &s->volume);
s->save_volume = (!real_changed && s->save_volume) || save;
if (s->set_volume) {

View file

@ -86,6 +86,11 @@ int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) {
pa_reset_sigs(-1);
pa_unblock_sigs(-1);
pa_reset_priority();
pa_unset_env_recorded();
/* Make sure our children are not influenced by the
* LD_BIND_NOW we set for ourselves. */
unsetenv("LD_BIND_NOW");
#ifdef PR_SET_PDEATHSIG
/* On Linux we can use PR_SET_PDEATHSIG to have the helper

View file

@ -57,14 +57,12 @@
" punpcklwd %%mm4, "#s" \n\t" /* .. | 0 | p0 | */ \
" pcmpgtw "#v", %%mm4 \n\t" /* .. | 0 | s(vl) | */ \
" pand "#s", %%mm4 \n\t" /* .. | 0 | (p0) | (vl >> 15) & p */ \
" movq %%mm6, %%mm5 \n\t" /* .. | ffff | 0 | */ \
" pand "#v", %%mm5 \n\t" /* .. | vh | 0 | */ \
" por %%mm5, %%mm4 \n\t" /* .. | vh | (p0) | */ \
" pmulhw "#s", "#v" \n\t" /* .. | 0 | vl*p0 | */ \
" paddw %%mm4, "#v" \n\t" /* .. | vh | vl*p0 | vh + sign correct */ \
" pslld $16, "#s" \n\t" /* .. | p0 | 0 | */ \
" por %%mm7, "#s" \n\t" /* .. | p0 | 1 | */ \
" pmaddwd "#s", "#v" \n\t" /* .. | p0 * v0 | */ \
" movq "#s", %%mm5 \n\t" \
" pmulhw "#v", "#s" \n\t" /* .. | 0 | vl*p0 | */ \
" paddw %%mm4, "#s" \n\t" /* .. | 0 | vl*p0 | + sign correct */ \
" psrld $16, "#v" \n\t" /* .. | 0 | vh | */ \
" pmaddwd %%mm5, "#v" \n\t" /* .. | p0 * vh | */ \
" paddd "#s", "#v" \n\t" /* .. | p0 * v0 | */ \
" packssdw "#v", "#v" \n\t" /* .. | p1*v1 | p0*v0 | */
/* approximately advances %3 = (%3 + a) % b. This function requires that
@ -105,10 +103,6 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
__asm__ __volatile__ (
" xor %3, %3 \n\t"
" sar $1, %2 \n\t" /* length /= sizeof (int16_t) */
" pcmpeqw %%mm6, %%mm6 \n\t" /* .. | ffff | ffff | */
" pcmpeqw %%mm7, %%mm7 \n\t" /* .. | ffff | ffff | */
" pslld $16, %%mm6 \n\t" /* .. | ffff | 0 | */
" psrld $31, %%mm7 \n\t" /* .. | 0 | 1 | */
" test $1, %2 \n\t" /* check for odd samples */
" je 2f \n\t"
@ -158,7 +152,7 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
" emms \n\t"
: "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp)
: "r" ((pa_reg_x86)channels)
: "X" ((pa_reg_x86)channels)
: "cc"
);
}
@ -234,7 +228,7 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
" emms \n\t"
: "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp)
: "r" ((pa_reg_x86)channels)
: "X" ((pa_reg_x86)channels)
: "cc"
);
}
@ -301,13 +295,16 @@ static void run_test (void) {
void pa_volume_func_init_mmx (pa_cpu_x86_flag_t flags) {
#if defined (__i386__) || defined (__amd64__)
pa_log_info("Initialising MMX optimized functions.");
#ifdef RUN_TEST
run_test ();
#endif
pa_set_volume_func (PA_SAMPLE_S16NE, (pa_do_volume_func_t) pa_volume_s16ne_mmx);
pa_set_volume_func (PA_SAMPLE_S16RE, (pa_do_volume_func_t) pa_volume_s16re_mmx);
if (flags & PA_CPU_X86_MMX) {
pa_log_info("Initialising MMX optimized functions.");
pa_set_volume_func (PA_SAMPLE_S16NE, (pa_do_volume_func_t) pa_volume_s16ne_mmx);
pa_set_volume_func (PA_SAMPLE_S16RE, (pa_do_volume_func_t) pa_volume_s16re_mmx);
}
#endif /* defined (__i386__) || defined (__amd64__) */
}

View file

@ -45,7 +45,7 @@
" movdqa "#s", %%xmm5 \n\t" \
" pmulhuw "#v", "#s" \n\t" /* .. | 0 | vl*p0 | */ \
" psubd %%xmm4, "#s" \n\t" /* .. | 0 | vl*p0 | + sign correct */ \
" psrld $16, "#v" \n\t" /* .. | p0 | 0 | */ \
" psrld $16, "#v" \n\t" /* .. | 0 | vh | */ \
" pmaddwd %%xmm5, "#v" \n\t" /* .. | p0 * vh | */ \
" paddd "#s", "#v" \n\t" /* .. | p0 * v0 | */ \
" packssdw "#v", "#v" \n\t" /* .. | p1*v1 | p0*v0 | */
@ -75,7 +75,7 @@
" por %%xmm5, "#s2" \n\t"
static void
pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
pa_volume_s16ne_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
{
pa_reg_x86 channel, temp;
@ -149,13 +149,13 @@ pa_volume_s16ne_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
"8: \n\t"
: "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
: "r" ((pa_reg_x86)channels)
: "X" ((pa_reg_x86)channels)
: "cc"
);
}
static void
pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
pa_volume_s16re_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
{
pa_reg_x86 channel, temp;
@ -237,7 +237,7 @@ pa_volume_s16re_sse (int16_t *samples, int32_t *volumes, unsigned channels, unsi
"8: \n\t"
: "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
: "r" ((pa_reg_x86)channels)
: "X" ((pa_reg_x86)channels)
: "cc"
);
}
@ -302,13 +302,16 @@ static void run_test (void) {
void pa_volume_func_init_sse (pa_cpu_x86_flag_t flags) {
#if defined (__i386__) || defined (__amd64__)
pa_log_info("Initialising SSE optimized functions.");
#ifdef RUN_TEST
run_test ();
#endif
pa_set_volume_func (PA_SAMPLE_S16NE, (pa_do_volume_func_t) pa_volume_s16ne_sse);
pa_set_volume_func (PA_SAMPLE_S16RE, (pa_do_volume_func_t) pa_volume_s16re_sse);
if (flags & PA_CPU_X86_SSE2) {
pa_log_info("Initialising SSE2 optimized functions.");
pa_set_volume_func (PA_SAMPLE_S16NE, (pa_do_volume_func_t) pa_volume_s16ne_sse2);
pa_set_volume_func (PA_SAMPLE_S16RE, (pa_do_volume_func_t) pa_volume_s16re_sse2);
}
#endif /* defined (__i386__) || defined (__amd64__) */
}

View file

@ -23,7 +23,8 @@
#include <inttypes.h>
/* First, define HAVE_VECTOR if we have the gcc vector extensions at all */
#if defined(__SSE2__) || defined(__ALTIVEC__)
#if defined(__SSE2__)
/* || defined(__ALTIVEC__)*/
#define HAVE_VECTOR