Merge branch 'master' into master-tx

This commit is contained in:
Lennart Poettering 2008-09-08 17:25:16 +03:00
commit c7a77657ff
27 changed files with 224 additions and 263 deletions

View file

@ -108,9 +108,11 @@ USA.
<optdesc><p>Capture or play back audio with the specified sample
format. Specify one of <opt>u8</opt>, <opt>s16le</opt>,
<opt>s16be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
<opt>s16be</opt>, <opt>s32le</opt>,
<opt>s32be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
<opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianess of
the CPU the formats <opt>s16ne</opt>, <opt>s16re</opt>,
the CPU the
formats <opt>s16ne</opt>, <opt>s16re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
<opt>float32ne</opt>, <opt>float32re</opt> (for native,
resp. reverse endian) are available as aliases. Defaults to
s16ne.</p></optdesc>

View file

@ -105,6 +105,16 @@ USA.
matching only.</p>
</option>
<option>
<p><opt>disable-lfe-remixing=</opt> When upmixing or downmixing
ignore LFE channels. When this option is on the output LFE
channel will only get a signal when an input LFE channel is
available as well. If no input LFE channel is available the
output LFE channel will always be 0. If no output LFE channel is
available the signal on the input LFE channel will be
ignored.</p>
</option>
<option>
<p><opt>use-pid-file=</opt> Create a PID file in
<file>/tmp/pulse-$USER/pid</file>. Of this is enabled you may
@ -319,9 +329,11 @@ USA.
<option>
<p><opt>default-sample-format=</opt> The default sampling
format. Specify one of <opt>u8</opt>, <opt>s16le</opt>,
<opt>s16be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
<opt>s16be</opt>, <opt>s32le</opt>,
<opt>s32be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
<opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianess of
the CPU the formats <opt>s16ne</opt>, <opt>s16re</opt>,
the CPU the
formats <opt>s16ne</opt>, <opt>s16re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
<opt>float32ne</opt>, <opt>float32re</opt> (for native,
resp. reverse endian) are available as aliases.</p>
</option>

View file

@ -541,8 +541,7 @@ libpulse_la_SOURCES = \
pulse/xmalloc.c pulse/xmalloc.h \
pulse/proplist.c pulse/proplist.h \
pulse/ext-stream-restore.c pulse/ext-stream-restore.h \
pulse/i18n.c pulse/i18n.h \
pulse/lock-autospawn.c pulse/lock-autospawn.h
pulse/i18n.c pulse/i18n.h
# Internal stuff that is shared with libpulsecore
libpulse_la_SOURCES += \
@ -740,8 +739,7 @@ libpulsecore_la_SOURCES = \
pulse/volume.c pulse/volume.h \
pulse/xmalloc.c pulse/xmalloc.h \
pulse/proplist.c pulse/proplist.h \
pulse/i18n.c pulse/i18n.h \
pulse/lock-autospawn.c pulse/lock-autospawn.h
pulse/i18n.c pulse/i18n.h
# Pure core stuff (some are shared in libpulse though).
libpulsecore_la_SOURCES += \
@ -811,6 +809,7 @@ libpulsecore_la_SOURCES += \
pulsecore/start-child.c pulsecore/start-child.h \
pulsecore/envelope.c pulsecore/envelope.h \
pulsecore/proplist-util.c pulsecore/proplist-util.h \
pulsecore/lock-autospawn.c pulsecore/lock-autospawn.h \
$(PA_THREAD_OBJS)
if OS_IS_WIN32
@ -1625,7 +1624,7 @@ update-ffmpeg:
update-map-file:
( echo "PULSE_0 {" ; \
echo "global:" ; \
ctags -I PA_GCC_PURE,PA_GCC_CONST,PA_GCC_DEPRECATED,PA_GCC_PRINTF_ATTR -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \
ctags -I PA_GCC_MALLOC,PA_GCC_ALLOC_SIZE2,PA_GCC_ALLOC_SIZE,PA_GCC_PURE,PA_GCC_CONST,PA_GCC_DEPRECATED,PA_GCC_PRINTF_ATTR -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \
echo "local:" ; \
echo "*;" ; \
echo "};" ) > $(srcdir)/map-file

View file

@ -167,6 +167,8 @@ static void callback(pa_mainloop_api*m, pa_io_event*e, int fd, pa_io_event_flags
pa_assert(e == io_event);
pa_assert(fd == the_pipe[0]);
pa_log("Recevied request to terminate due to CPU overload.");
pa_read(the_pipe[0], &c, sizeof(c), NULL);
m->quit(m, 1); /* Quit the main loop */
}

View file

@ -76,6 +76,7 @@ static const pa_daemon_conf default_conf = {
.log_level = PA_LOG_NOTICE,
.resample_method = PA_RESAMPLER_AUTO,
.disable_remixing = FALSE,
.disable_lfe_remixing = TRUE,
.config_file = NULL,
.use_pid_file = TRUE,
.system_instance = FALSE,
@ -426,6 +427,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
{ "default-fragment-size-msec", parse_fragment_size_msec, NULL },
{ "nice-level", parse_nice_level, NULL },
{ "disable-remixing", pa_config_parse_bool, NULL },
{ "disable-lfe-remixing", pa_config_parse_bool, NULL },
{ "load-default-script-file", pa_config_parse_bool, NULL },
#ifdef HAVE_SYS_RESOURCE_H
{ "rlimit-fsize", parse_rlimit, NULL },
@ -490,66 +492,67 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
table[24].data = c;
table[25].data = c;
table[26].data = &c->disable_remixing;
table[27].data = &c->load_default_script_file;
table[27].data = &c->disable_lfe_remixing;
table[28].data = &c->load_default_script_file;
#ifdef HAVE_SYS_RESOURCE_H
table[28].data = &c->rlimit_fsize;
table[29].data = &c->rlimit_data;
table[30].data = &c->rlimit_stack;
table[31].data = &c->rlimit_as;
table[32].data = &c->rlimit_core;
table[33].data = &c->rlimit_nofile;
table[34].data = &c->rlimit_as;
table[29].data = &c->rlimit_fsize;
table[30].data = &c->rlimit_data;
table[31].data = &c->rlimit_stack;
table[32].data = &c->rlimit_as;
table[33].data = &c->rlimit_core;
table[34].data = &c->rlimit_nofile;
table[35].data = &c->rlimit_as;
#ifdef RLIMIT_NPROC
table[35].data = &c->rlimit_nproc;
table[36].data = &c->rlimit_nproc;
#endif
#ifdef RLIMIT_MEMLOCK
#ifndef RLIMIT_NPROC
#error "Houston, we have a numbering problem!"
#endif
table[36].data = &c->rlimit_memlock;
table[37].data = &c->rlimit_memlock;
#endif
#ifdef RLIMIT_LOCKS
#ifndef RLIMIT_MEMLOCK
#error "Houston, we have a numbering problem!"
#endif
table[37].data = &c->rlimit_locks;
table[38].data = &c->rlimit_locks;
#endif
#ifdef RLIMIT_SIGPENDING
#ifndef RLIMIT_LOCKS
#error "Houston, we have a numbering problem!"
#endif
table[38].data = &c->rlimit_sigpending;
table[39].data = &c->rlimit_sigpending;
#endif
#ifdef RLIMIT_MSGQUEUE
#ifndef RLIMIT_SIGPENDING
#error "Houston, we have a numbering problem!"
#endif
table[39].data = &c->rlimit_msgqueue;
table[40].data = &c->rlimit_msgqueue;
#endif
#ifdef RLIMIT_NICE
#ifndef RLIMIT_MSGQUEUE
#error "Houston, we have a numbering problem!"
#endif
table[40].data = &c->rlimit_nice;
table[41].data = &c->rlimit_nice;
#endif
#ifdef RLIMIT_RTPRIO
#ifndef RLIMIT_NICE
#error "Houston, we have a numbering problem!"
#endif
table[41].data = &c->rlimit_rtprio;
table[42].data = &c->rlimit_rtprio;
#endif
#ifdef RLIMIT_RTTIME
#ifndef RLIMIT_RTTIME
#error "Houston, we have a numbering problem!"
#endif
table[42].data = &c->rlimit_rttime;
table[43].data = &c->rlimit_rttime;
#endif
#endif
@ -661,6 +664,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
pa_strbuf_printf(s, "log-level = %s\n", log_level_to_string[c->log_level]);
pa_strbuf_printf(s, "resample-method = %s\n", pa_resample_method_to_string(c->resample_method));
pa_strbuf_printf(s, "disable-remixing = %s\n", pa_yes_no(c->disable_remixing));
pa_strbuf_printf(s, "disable-lfe-remixing = %s\n", pa_yes_no(c->disable_lfe_remixing));
pa_strbuf_printf(s, "default-sample-format = %s\n", pa_sample_format_to_string(c->default_sample_spec.format));
pa_strbuf_printf(s, "default-sample-rate = %u\n", c->default_sample_spec.rate);
pa_strbuf_printf(s, "default-sample-channels = %u\n", c->default_sample_spec.channels);

View file

@ -66,6 +66,7 @@ typedef struct pa_daemon_conf {
no_cpu_limit,
disable_shm,
disable_remixing,
disable_lfe_remixing,
load_default_script_file,
disallow_exit;
int exit_idle_time,

View file

@ -47,6 +47,7 @@
; resample-method = speex-float-3
; disable-remixing = no
; disable-lfe-remixing = yes
; no-cpu-limit = no

View file

@ -65,8 +65,8 @@
#include <pulse/timeval.h>
#include <pulse/xmalloc.h>
#include <pulse/i18n.h>
#include <pulse/lock-autospawn.h>
#include <pulsecore/lock-autospawn.h>
#include <pulsecore/winsock.h>
#include <pulsecore/core-error.h>
#include <pulsecore/core.h>
@ -778,8 +778,15 @@ int main(int argc, char *argv[]) {
pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
s = pa_uname_string();
pa_log_debug(_("Running on host: %s"), s);
pa_xfree(s);
pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
#ifdef HAVE_VALGRIND_MEMCHECK_H
pa_log_debug(_("Compiled with Valgrind support: yes"));
#else
@ -792,8 +799,6 @@ int main(int argc, char *argv[]) {
pa_log_debug(_("Optimized build: no"));
#endif
pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
if (!(s = pa_machine_id())) {
pa_log(_("Failed to get machine ID"));
goto finish;
@ -864,6 +869,7 @@ int main(int argc, char *argv[]) {
c->realtime_priority = conf->realtime_priority;
c->realtime_scheduling = !!conf->realtime_scheduling;
c->disable_remixing = !!conf->disable_remixing;
c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
c->running_as_daemon = !!conf->daemonize;
c->disallow_exit = conf->disallow_exit;

View file

@ -9,6 +9,7 @@ pa_browser_unref;
pa_bytes_per_second;
pa_bytes_snprint;
pa_bytes_to_usec;
pa_channel_map_compatible;
pa_channel_map_equal;
pa_channel_map_init;
pa_channel_map_init_auto;
@ -98,6 +99,7 @@ pa_context_unref;
pa_cvolume_avg;
pa_cvolume_channels_equal_to;
pa_cvolume_equal;
pa_cvolume_max;
pa_cvolume_remap;
pa_cvolume_set;
pa_cvolume_snprint;

View file

@ -1241,7 +1241,7 @@ int pa__init(pa_module*m) {
}
if (use_tsched && !pa_rtclock_hrtimer()) {
pa_log("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
use_tsched = FALSE;
}

View file

@ -1073,7 +1073,7 @@ int pa__init(pa_module*m) {
}
if (use_tsched && !pa_rtclock_hrtimer()) {
pa_log("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
use_tsched = FALSE;
}

View file

@ -198,6 +198,7 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
pa_assert(m);
pa_assert(channels > 0);
pa_assert(channels <= PA_CHANNELS_MAX);
pa_assert(def < PA_CHANNEL_MAP_DEF_MAX);
pa_channel_map_init(m);
@ -287,9 +288,6 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
case PA_CHANNEL_MAP_AUX: {
unsigned i;
if (channels >= PA_CHANNELS_MAX)
return NULL;
for (i = 0; i < channels; i++)
m->map[i] = PA_CHANNEL_POSITION_AUX0 + i;
@ -391,7 +389,7 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
default:
return NULL;
pa_assert_not_reached();
}
}
@ -401,6 +399,7 @@ pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m, unsigned channels,
pa_assert(m);
pa_assert(channels > 0);
pa_assert(channels <= PA_CHANNELS_MAX);
pa_assert(def < PA_CHANNEL_MAP_DEF_MAX);
pa_channel_map_init(m);
@ -489,7 +488,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
pa_assert(rmap);
pa_assert(s);
memset(&map, 0, sizeof(map));
pa_channel_map_init(&map);
if (strcmp(s, "stereo") == 0) {
map.channels = 2;
@ -552,11 +551,16 @@ int pa_channel_map_valid(const pa_channel_map *map) {
if (map->channels <= 0 || map->channels > PA_CHANNELS_MAX)
return 0;
for (c = 0; c < map->channels; c++) {
if (map->map[c] < 0 ||map->map[c] >= PA_CHANNEL_POSITION_MAX)
for (c = 0; c < map->channels; c++)
if (map->map[c] < 0 || map->map[c] >= PA_CHANNEL_POSITION_MAX)
return 0;
}
return 1;
}
int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) {
pa_assert(map);
pa_assert(ss);
return map->channels == ss->channels;
}

View file

@ -157,6 +157,9 @@ typedef enum pa_channel_map_def {
PA_CHANNEL_MAP_OSS,
/**< The default channel mapping used by OSS as defined in the OSS 4.0 API specs */
/**< Upper limit of valid channel mapping definitions */
PA_CHANNEL_MAP_DEF_MAX,
PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF
/**< The default channel map */
} pa_channel_map_def_t;
@ -211,9 +214,13 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *map, const char *s);
/** Compare two channel maps. Return 1 if both match. */
int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) PA_GCC_PURE;
/** Return non-zero of the specified channel map is considered valid */
/** Return non-zero if the specified channel map is considered valid */
int pa_channel_map_valid(const pa_channel_map *map) PA_GCC_PURE;
/** Return non-zero if the specified channel map is compatible with
* the specified sample spec. \since 0.9.12 */
int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) PA_GCC_PURE;
PA_C_DECL_END
#endif

View file

@ -54,7 +54,6 @@
#include <pulse/utf8.h>
#include <pulse/util.h>
#include <pulse/i18n.h>
#include <pulse/lock-autospawn.h>
#include <pulsecore/winsock.h>
#include <pulsecore/core-error.h>
@ -98,26 +97,6 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
[PA_COMMAND_EXTENSION] = pa_command_extension
};
static void unlock_autospawn(pa_context *c) {
pa_assert(c);
if (c->autospawn_fd >= 0) {
if (c->autospawn_locked)
pa_autospawn_lock_release();
if (c->autospawn_event)
c->mainloop->io_free(c->autospawn_event);
pa_autospawn_lock_done(FALSE);
}
c->autospawn_locked = FALSE;
c->autospawn_fd = -1;
c->autospawn_event = NULL;
}
static void context_free(pa_context *c);
pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
@ -180,9 +159,6 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
c->do_shm = FALSE;
c->do_autospawn = FALSE;
c->autospawn_fd = -1;
c->autospawn_locked = FALSE;
c->autospawn_event = NULL;
memset(&c->spawn_api, 0, sizeof(c->spawn_api));
#ifndef MSG_NOSIGNAL
@ -252,8 +228,6 @@ static void context_free(pa_context *c) {
context_unlink(c);
unlock_autospawn(c);
if (c->record_streams)
pa_dynarray_free(c->record_streams, NULL, NULL);
if (c->playback_streams)
@ -577,32 +551,90 @@ static void setup_context(pa_context *c, pa_iochannel *io) {
pa_context_unref(c);
}
static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
static char *get_old_legacy_runtime_dir(void) {
char *p, u[128];
struct stat st;
if (!pa_get_user_name(u, sizeof(u)))
return NULL;
p = pa_sprintf_malloc("/tmp/pulse-%s", u);
if (stat(p, &st) < 0) {
pa_xfree(p);
return NULL;
}
if (st.st_uid != getuid()) {
pa_xfree(p);
return NULL;
}
return p;
}
static char *get_very_old_legacy_runtime_dir(void) {
char *p, h[128];
struct stat st;
if (!pa_get_home_dir(h, sizeof(h)))
return NULL;
p = pa_sprintf_malloc("%s/.pulse", h);
if (stat(p, &st) < 0) {
pa_xfree(p);
return NULL;
}
if (st.st_uid != getuid()) {
pa_xfree(p);
return NULL;
}
return p;
}
static pa_strlist *prepend_per_user(pa_strlist *l) {
char *ufn;
static char *legacy_dir;
/* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
l = pa_strlist_prepend(l, p);
pa_xfree(p);
pa_xfree(legacy_dir);
}
/* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
if ((legacy_dir = get_old_legacy_runtime_dir())) {
char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
l = pa_strlist_prepend(l, p);
pa_xfree(p);
pa_xfree(legacy_dir);
}
/* The per-user instance */
if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
l = pa_strlist_prepend(l, ufn);
pa_xfree(ufn);
}
return l;
}
#ifndef OS_IS_WIN32
static int context_connect_spawn(pa_context *c) {
static int context_autospawn(pa_context *c) {
pid_t pid;
int status, r;
int fds[2] = { -1, -1} ;
pa_iochannel *io;
if (getuid() == 0)
return -1;
pa_log_debug("Trying to autospawn...");
pa_context_ref(c);
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
pa_log_error(_("socketpair(): %s"), pa_cstrerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
goto fail;
}
pa_make_fd_cloexec(fds[0]);
pa_make_socket_low_delay(fds[0]);
pa_make_socket_low_delay(fds[1]);
if (c->spawn_api.prefork)
c->spawn_api.prefork();
@ -617,31 +649,22 @@ static int context_connect_spawn(pa_context *c) {
} else if (!pid) {
/* Child */
char t[128];
const char *state = NULL;
#define MAX_ARGS 64
const char * argv[MAX_ARGS+1];
int n;
char *f;
pa_close_all(fds[1], -1);
f = pa_sprintf_malloc("%i", fds[1]);
pa_set_env("PULSE_PASSED_FD", f);
pa_xfree(f);
if (c->spawn_api.atfork)
c->spawn_api.atfork();
pa_close_all(-1);
/* Setup argv */
n = 0;
argv[n++] = c->conf->daemon_binary;
argv[n++] = "--daemonize=yes";
pa_snprintf(t, sizeof(t), "-Lmodule-native-protocol-fd fd=%i", fds[1]);
argv[n++] = strdup(t);
argv[n++] = "--start";
while (n < MAX_ARGS) {
char *a;
@ -661,14 +684,13 @@ static int context_connect_spawn(pa_context *c) {
/* Parent */
pa_assert_se(pa_close(fds[1]) == 0);
fds[1] = -1;
r = waitpid(pid, &status, 0);
if (c->spawn_api.postfork)
c->spawn_api.postfork();
do {
r = waitpid(pid, &status, 0);
} while (r < 0 && errno == EINTR);
if (r < 0) {
pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
@ -678,21 +700,11 @@ static int context_connect_spawn(pa_context *c) {
goto fail;
}
c->is_local = TRUE;
unlock_autospawn(c);
io = pa_iochannel_new(c->mainloop, fds[0], fds[0]);
setup_context(c, io);
pa_context_unref(c);
return 0;
fail:
pa_close_pipe(fds);
unlock_autospawn(c);
pa_context_unref(c);
@ -701,6 +713,8 @@ fail:
#endif /* OS_IS_WIN32 */
static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
static int try_next_connection(pa_context *c) {
char *u = NULL;
int r = -1;
@ -718,8 +732,18 @@ static int try_next_connection(pa_context *c) {
#ifndef OS_IS_WIN32
if (c->do_autospawn) {
r = context_connect_spawn(c);
goto finish;
if ((r = context_autospawn(c)) < 0)
goto finish;
/* Autospawn only once */
c->do_autospawn = FALSE;
/* Connect only to per-user sockets this time */
c->server_list = prepend_per_user(c->server_list);
/* Retry connection */
continue;
}
#endif
@ -774,91 +798,12 @@ static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userd
goto finish;
}
unlock_autospawn(c);
setup_context(c, io);
finish:
pa_context_unref(c);
}
static void autospawn_cb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
pa_context *c = userdata;
int k;
pa_assert(a);
pa_assert(e);
pa_assert(fd >= 0);
pa_assert(events == PA_IO_EVENT_INPUT);
pa_assert(c);
pa_assert(e == c->autospawn_event);
pa_assert(fd == c->autospawn_fd);
pa_context_ref(c);
/* Check whether we can get the lock right now*/
if ((k = pa_autospawn_lock_acquire(FALSE)) < 0) {
pa_context_fail(c, PA_ERR_ACCESS);
goto finish;
}
if (k > 0) {
/* So we got it, rock on! */
c->autospawn_locked = TRUE;
try_next_connection(c);
c->mainloop->io_free(c->autospawn_event);
c->autospawn_event = NULL;
}
finish:
pa_context_unref(c);
}
static char *get_old_legacy_runtime_dir(void) {
char *p, u[128];
struct stat st;
if (!pa_get_user_name(u, sizeof(u)))
return NULL;
p = pa_sprintf_malloc("/tmp/pulse-%s", u);
if (stat(p, &st) < 0) {
pa_xfree(p);
return NULL;
}
if (st.st_uid != getuid()) {
pa_xfree(p);
return NULL;
}
return p;
}
static char *get_very_old_legacy_runtime_dir(void) {
char *p, h[128];
struct stat st;
if (!pa_get_home_dir(h, sizeof(h)))
return NULL;
p = pa_sprintf_malloc("%s/.pulse", h);
if (stat(p, &st) < 0) {
pa_xfree(p);
return NULL;
}
if (st.st_uid != getuid()) {
pa_xfree(p);
return NULL;
}
return p;
}
int pa_context_connect(
pa_context *c,
const char *server,
@ -888,11 +833,11 @@ int pa_context_connect(
}
} else {
char *d, *ufn;
static char *legacy_dir;
char *d;
/* Prepend in reverse order */
/* Follow the X display */
if ((d = getenv("DISPLAY"))) {
char *e;
d = pa_xstrdup(d);
@ -905,70 +850,27 @@ int pa_context_connect(
pa_xfree(d);
}
c->server_list = pa_strlist_prepend(c->server_list, "tcp6:localhost");
c->server_list = pa_strlist_prepend(c->server_list, "tcp4:localhost");
/* Add TCP/IP on the localhost */
c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
/* The system wide instance */
/* The system wide instance via PF_LOCAL */
c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
/* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
c->server_list = pa_strlist_prepend(c->server_list, p);
pa_xfree(p);
pa_xfree(legacy_dir);
}
/* The user instance via PF_LOCAL */
c->server_list = prepend_per_user(c->server_list);
/* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
if ((legacy_dir = get_old_legacy_runtime_dir())) {
char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
c->server_list = pa_strlist_prepend(c->server_list, p);
pa_xfree(p);
pa_xfree(legacy_dir);
}
/* The per-user instance */
if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
c->server_list = pa_strlist_prepend(c->server_list, ufn);
pa_xfree(ufn);
}
/* Wrap the connection attempts in a single transaction for sane autospawn locking */
/* Set up autospawning */
if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
int k;
pa_assert(c->autospawn_fd < 0);
pa_assert(!c->autospawn_locked);
/* Start the locking procedure */
if ((c->autospawn_fd = pa_autospawn_lock_init()) < 0) {
pa_context_fail(c, PA_ERR_ACCESS);
goto finish;
}
if (api)
c->spawn_api = *api;
c->do_autospawn = TRUE;
/* Check whether we can get the lock right now*/
if ((k = pa_autospawn_lock_acquire(FALSE)) < 0) {
pa_context_fail(c, PA_ERR_ACCESS);
goto finish;
}
if (k > 0)
/* So we got it, rock on! */
c->autospawn_locked = TRUE;
if (getuid() == 0)
pa_log_debug("Not doing autospawn since we are root.");
else {
/* Hmm, we didn't get it, so let's wait for it */
c->autospawn_event = c->mainloop->io_new(c->mainloop, c->autospawn_fd, PA_IO_EVENT_INPUT, autospawn_cb, c);
c->do_autospawn = TRUE;
pa_context_set_state(c, PA_CONTEXT_CONNECTING);
r = 0;
goto finish;
if (api)
c->spawn_api = *api;
}
}
}

View file

@ -78,9 +78,6 @@ struct pa_context {
pa_bool_t do_shm:1;
pa_bool_t do_autospawn:1;
pa_bool_t autospawn_locked:1;
int autospawn_fd;
pa_io_event *autospawn_event;
pa_spawn_api spawn_api;
pa_strlist *server_list;

View file

@ -42,6 +42,7 @@
#include <dirent.h>
#include <regex.h>
#include <langinfo.h>
#include <sys/utsname.h>
#ifdef HAVE_STRTOF_L
#include <locale.h>
@ -2445,5 +2446,12 @@ char *pa_machine_id(void) {
/* If no hostname was set we use the POSIX hostid. It's usually
* the IPv4 address. Mit not be that stable. */
return pa_sprintf_malloc("%08lx", (unsigned long) gethostid);
}
char *pa_uname_string(void) {
struct utsname u;
pa_assert_se(uname(&u) == 0);
return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
}

View file

@ -191,5 +191,6 @@ pa_bool_t pa_in_system_mode(void);
#define pa_streq(a,b) (!strcmp((a),(b)))
char *pa_machine_id(void);
char *pa_uname_string(void);
#endif

View file

@ -138,6 +138,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) {
c->realtime_scheduling = FALSE;
c->realtime_priority = 5;
c->disable_remixing = FALSE;
c->disable_lfe_remixing = FALSE;
for (j = 0; j < PA_CORE_HOOK_MAX; j++)
pa_hook_init(&c->hooks[j], c);
@ -204,6 +205,7 @@ static void exit_callback(pa_mainloop_api*m, pa_time_event *e, const struct time
pa_core *c = userdata;
pa_assert(c->exit_event == e);
pa_log_info("We are idle, quitting...");
pa_core_exit(c, TRUE, 0);
}

View file

@ -124,6 +124,7 @@ struct pa_core {
pa_bool_t running_as_daemon:1;
pa_bool_t realtime_scheduling:1;
pa_bool_t disable_remixing:1;
pa_bool_t disable_lfe_remixing:1;
pa_resample_method_t resample_method;
int realtime_priority;

View file

@ -716,7 +716,11 @@ static void calc_map_table(pa_resampler *r) {
* channels for LFE. */
for (ic = 0; ic < r->i_ss.channels; ic++) {
r->map_table[oc][ic] = 1.0f / (float) r->i_ss.channels;
if (!(r->flags & PA_RESAMPLER_NO_LFE))
r->map_table[oc][ic] = 1.0f / (float) r->i_ss.channels;
else
r->map_table[oc][ic] = 0;
/* Please note that a channel connected to LFE
* doesn't really count as connected. */
@ -851,7 +855,7 @@ static void calc_map_table(pa_resampler *r) {
}
}
if (ic_unconnected_lfe > 0) {
if (ic_unconnected_lfe > 0 && !(r->flags & PA_RESAMPLER_NO_LFE)) {
/* OK, so there is an unconnected LFE channel. Let's mix
* it into all channels, with factor 0.375 */

View file

@ -49,9 +49,10 @@ typedef enum pa_resample_method {
} pa_resample_method_t;
typedef enum pa_resample_flags {
PA_RESAMPLER_VARIABLE_RATE = 1,
PA_RESAMPLER_NO_REMAP = 2, /* implies NO_REMIX */
PA_RESAMPLER_NO_REMIX = 4
PA_RESAMPLER_VARIABLE_RATE = 0x0001U,
PA_RESAMPLER_NO_REMAP = 0x0002U, /* implies NO_REMIX */
PA_RESAMPLER_NO_REMIX = 0x0004U,
PA_RESAMPLER_NO_LFE = 0x0008U
} pa_resample_flags_t;
pa_resampler* pa_resampler_new(

View file

@ -201,7 +201,8 @@ pa_sink_input* pa_sink_input_new(
data->resample_method,
((flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
((flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
(core->disable_remixing || (flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
(core->disable_remixing || (flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
(core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
pa_log_warn("Unsupported resampling operation.");
return NULL;
}

View file

@ -171,7 +171,8 @@ pa_source_output* pa_source_output_new(
data->resample_method,
((flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
((flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
(core->disable_remixing || (flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
(core->disable_remixing || (flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
(core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
pa_log_warn("Unsupported resampling operation.");
return NULL;
}

View file

@ -28,7 +28,7 @@
#include <pulsecore/macro.h>
#include <pulsecore/thread.h>
#include <pulse/lock-autospawn.h>
#include <pulsecore/lock-autospawn.h>
#include <pulse/util.h>
static void thread_func(void*k) {

View file

@ -500,7 +500,7 @@ static void help(const char *argv0) {
" --volume=VOLUME Specify the initial (linear) volume in range 0...65536\n"
" --rate=SAMPLERATE The sample rate in Hz (defaults to 44100)\n"
" --format=SAMPLEFORMAT The sample type, one of s16le, s16be, u8, float32le,\n"
" float32be, ulaw, alaw (defaults to s16ne)\n"
" float32be, ulaw, alaw, s32le, s32be (defaults to s16ne)\n"
" --channels=CHANNELS The number of channels, 1 for mono, 2 for stereo\n"
" (defaults to 2)\n"
" --channel-map=CHANNELMAP Channel map to use instead of the default\n"
@ -695,7 +695,7 @@ int main(int argc, char *argv[]) {
goto quit;
}
if (channel_map_set && channel_map.channels != sample_spec.channels) {
if (channel_map_set && pa_channel_map_compatible(&channel_map, &sample_spec)) {
fprintf(stderr, _("Channel map doesn't match sample specification\n"));
goto quit;
}
@ -773,7 +773,10 @@ int main(int argc, char *argv[]) {
pa_context_set_state_callback(context, context_state_callback, NULL);
/* Connect the context */
pa_context_connect(context, server, 0, NULL);
if (pa_context_connect(context, server, 0, NULL) < 0) {
fprintf(stderr, _("pa_context_connect() failed: %s"), pa_strerror(pa_context_errno(context)));
goto quit;
}
if (verbose) {
struct timeval tv;