mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-31 22:25:33 -04:00
Merge branch 'master' into master-tx
This commit is contained in:
commit
c7a77657ff
27 changed files with 224 additions and 263 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
; resample-method = speex-float-3
|
||||
; disable-remixing = no
|
||||
; disable-lfe-remixing = yes
|
||||
|
||||
; no-cpu-limit = no
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue