diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/.gitignore | 2 | ||||
| -rw-r--r-- | src/Makefile.am | 26 | ||||
| -rw-r--r-- | src/daemon/daemon-conf.c | 2 | ||||
| -rw-r--r-- | src/daemon/daemon.conf.in | 2 | ||||
| -rwxr-xr-x | src/daemon/default.pa.in | 30 | ||||
| -rw-r--r-- | src/daemon/main.c | 9 | ||||
| -rw-r--r-- | src/daemon/pulseaudio-module-xsmp.desktop | 10 | ||||
| -rw-r--r-- | src/daemon/pulseaudio.desktop | 10 | ||||
| -rwxr-xr-x | src/daemon/start-pulseaudio-x11.in | 31 | ||||
| -rwxr-xr-x | src/daemon/system.pa.in | 54 | ||||
| -rw-r--r-- | src/modules/module-bt-proximity.c | 1 | ||||
| -rw-r--r-- | src/modules/module-console-kit.c | 51 | ||||
| -rw-r--r-- | src/modules/module-hal-detect.c | 20 | ||||
| -rw-r--r-- | src/modules/module-x11-xsmp.c | 2 | ||||
| -rw-r--r-- | src/pulse/channelmap.h | 6 | ||||
| -rw-r--r-- | src/pulse/client-conf.c | 2 | ||||
| -rw-r--r-- | src/pulse/client.conf.in | 2 | ||||
| -rw-r--r-- | src/pulse/context.h | 5 | ||||
| -rw-r--r-- | src/pulse/def.h | 72 | ||||
| -rw-r--r-- | src/pulse/introspect.h | 10 | ||||
| -rw-r--r-- | src/pulse/proplist.h | 34 | ||||
| -rw-r--r-- | src/pulse/pulseaudio.h | 10 | ||||
| -rw-r--r-- | src/pulse/sample.h | 2 | ||||
| -rw-r--r-- | src/pulse/stream.h | 113 | ||||
| -rw-r--r-- | src/pulsecore/core-util.c | 25 | ||||
| -rw-r--r-- | src/pulsecore/sink.c | 17 | ||||
| -rw-r--r-- | src/pulsecore/source.c | 17 | 
27 files changed, 416 insertions, 149 deletions
| diff --git a/src/.gitignore b/src/.gitignore index f3ed2e2e..6902eb9f 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -15,6 +15,7 @@ cpulimit-test  cpulimit-test2  daemon.conf  default.pa +system.pa  envelope-test  esdcompat  flist-test @@ -54,3 +55,4 @@ thread-mainloop-test  thread-test  utf8-test  voltest +start-pulseaudio-x11 diff --git a/src/Makefile.am b/src/Makefile.am index 788857cd..51fd9976 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -96,23 +96,26 @@ EXTRA_DIST = \  		pulse/version.h.in \  		daemon/daemon.conf.in \  		daemon/default.pa.in \ +		daemon/system.pa.in \  		daemon/default.pa.win32 \  		depmod.py \  		daemon/esdcompat.in \ +		daemon/start-pulseaudio-x11.in \  		utils/padsp \  		modules/module-defs.h.m4 \ -		daemon/pulseaudio-module-xsmp.desktop \ +		daemon/pulseaudio.desktop \  		map-file \  		daemon/org.pulseaudio.policy  pulseconf_DATA = \  		default.pa \ +		system.pa \  		daemon.conf \  		client.conf  if HAVE_X11  xdgautostart_DATA = \ -		daemon/pulseaudio-module-xsmp.desktop +		daemon/pulseaudio.desktop  endif  BUILT_SOURCES = \ @@ -184,7 +187,7 @@ if HAVE_AVAHI  bin_PROGRAMS += pabrowse  endif -bin_SCRIPTS = esdcompat +bin_SCRIPTS = esdcompat start-pulseaudio-x11  pacat_SOURCES = utils/pacat.c  pacat_LDADD = $(AM_LDADD) libpulse.la @@ -585,7 +588,7 @@ endif  libpulse_la_CFLAGS = $(AM_CFLAGS)  libpulse_la_LDFLAGS = -version-info $(LIBPULSE_VERSION_INFO) -Wl,-version-script=$(srcdir)/map-file -libpulse_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) $(LIBICONV) +libpulse_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) $(LTLIBICONV)  if HAVE_X11  libpulse_la_CFLAGS += $(X_CFLAGS) @@ -801,7 +804,7 @@ endif  libpulsecore_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBOIL_CFLAGS)  libpulsecore_la_LDFLAGS = -version-info $(LIBPULSECORE_VERSION_INFO) -libpulsecore_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(LIBSPEEX_LIBS) $(WINSOCK_LIBS) $(LIBOIL_LIBS) $(LIBICONV) libffmpeg-resampler.la +libpulsecore_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(LIBSPEEX_LIBS) $(WINSOCK_LIBS) $(LIBOIL_LIBS) $(LTLIBICONV) libffmpeg-resampler.la  ###################################  #   Plug-in support libraries     # @@ -1542,7 +1545,7 @@ suid: pulseaudio .libs/lt-pulseaudio  	chown root $^  	chmod u+s $^ -CLEANFILES = esdcompat client.conf default.pa daemon.conf +CLEANFILES = esdcompat client.conf default.pa system.pa daemon.conf start-pulseaudio-x11  esdcompat: daemon/esdcompat.in Makefile  	sed -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \ @@ -1550,17 +1553,28 @@ esdcompat: daemon/esdcompat.in Makefile  		-e 's,@PA_BINARY\@,$(PA_BINARY),g' < $< > $@  	chmod +x esdcompat +start-pulseaudio-x11: daemon/start-pulseaudio-x11.in Makefile +	sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' \ +		-e 's,@PACTL_BINARY\@,$(bindir)/pactl,g' < $< > $@ +	chmod +x start-pulseaudio-x11 +  client.conf: pulse/client.conf.in Makefile  	sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' < $< > $@  if OS_IS_WIN32  default.pa: daemon/default.pa.win32  	cp $< $@ +system.pa: daemon/default.pa.win32 +	cp $< $@  else  default.pa: daemon/default.pa.in Makefile  	sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' \              -e 's,@PA_DLSEARCHPATH\@,$(modlibexecdir),g' \  	    -e 's,@PA_SOEXT\@,.so,g' < $< > $@ +system.pa: daemon/system.pa.in Makefile +	sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' \ +            -e 's,@PA_DLSEARCHPATH\@,$(modlibexecdir),g' \ +	    -e 's,@PA_SOEXT\@,.so,g' < $< > $@  endif  daemon.conf: daemon/daemon.conf.in Makefile diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index 9ac40901..50b812dc 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -62,7 +62,7 @@ static const pa_daemon_conf default_conf = {      .realtime_scheduling = FALSE,      .realtime_priority = 5,  /* Half of JACK's default rtprio */      .disallow_module_loading = FALSE, -    .exit_idle_time = -1, +    .exit_idle_time = 20,      .module_idle_time = 20,      .scache_idle_time = 20,      .auto_log_target = 1, diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in index dfabcfb2..41c26e2a 100644 --- a/src/daemon/daemon.conf.in +++ b/src/daemon/daemon.conf.in @@ -32,7 +32,7 @@  ; realtime-scheduling = no  ; realtime-priority = 5 -; exit-idle-time = -1 +; exit-idle-time = 20  ; module-idle-time = 20  ; scache-idle-time = 20 diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index aad9f5d6..917fc309 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -16,6 +16,9 @@  # along with PulseAudio; if not, write to the Free Software Foundation,  # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +# This startup script is used only if PulseAudio is started per-user +# (i.e. not in system mode) +  .nofail  ### Load something into the sample cache @@ -80,14 +83,6 @@ load-module module-always-sink  ### Automatically suspend sinks/sources that become idle for too long  load-module module-suspend-on-idle -### Load X11 bell module -#load-module module-x11-bell sample=bell-windowing-system - -### Register ourselves in the X11 session manager -# Deactivated by default, to avoid deadlock when PA is started as esd from gnome-session -# Instead we load this via /etc/xdg/autostart/ and "pactl load-module" now -#load-module module-x11-xsmp -  ### If autoexit on idle is enabled we want to make sure we only quit  ### when no local session needs us anymore.  load-module module-console-kit @@ -104,12 +99,21 @@ load-module module-gconf  .fail  .endif +# X11 modules should not be started from default.pa so that one daemon +# can be shared by multiple sessions. + +### Load X11 bell module +#load-module module-x11-bell sample=bell-windowing-system + +### Register ourselves in the X11 session manager +#load-module module-x11-xsmp +  ### Publish connection data in the X11 root window -.ifexists module-x11-publish@PA_SOEXT@ -.nofail -load-module module-x11-publish -.fail -.endif +#.ifexists module-x11-publish@PA_SOEXT@ +#.nofail +#load-module module-x11-publish +#.fail +#.endif  ### Make some devices default  #set-default-sink output diff --git a/src/daemon/main.c b/src/daemon/main.c index 14594416..5fc9f01c 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -496,7 +496,7 @@ int main(int argc, char *argv[]) {      if (conf->high_priority && (conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START))          pa_raise_priority(conf->nice_level); -    if (pa_have_caps()) { +    if (!real_root && pa_have_caps()) {          pa_bool_t drop;          drop = (conf->cmd != PA_CMD_DAEMON && conf->cmd != PA_CMD_START) || !conf->realtime_scheduling; @@ -627,6 +627,11 @@ int main(int argc, char *argv[]) {          goto finish;      } +    if (conf->cmd == PA_CMD_START && conf->system_instance) { +        pa_log("--start not supported for system instances."); +        goto finish; +    } +      if (conf->cmd == PA_CMD_START) {          /* If we shall start PA only when it is not running yet, we           * first take the autospawn lock to make things @@ -762,8 +767,6 @@ int main(int argc, char *argv[]) {                  /* If we are already running and with are run in                   * --start mode, then let's return this as success. */ -                pa_log_info("z=%i rock!", z); -                  retval = 0;                  goto finish;              } diff --git a/src/daemon/pulseaudio-module-xsmp.desktop b/src/daemon/pulseaudio-module-xsmp.desktop deleted file mode 100644 index fa719a73..00000000 --- a/src/daemon/pulseaudio-module-xsmp.desktop +++ /dev/null @@ -1,10 +0,0 @@ -[Desktop Entry] -Version=1.0 -Encoding=UTF-8 -Name=PulseAudio Session Management -Comment=Load module-x11-xsmp into PulseAudio -Exec=pactl load-module module-x11-xsmp -Terminal=false -Type=Application -Categories= -GenericName= diff --git a/src/daemon/pulseaudio.desktop b/src/daemon/pulseaudio.desktop new file mode 100644 index 00000000..57a7a6e4 --- /dev/null +++ b/src/daemon/pulseaudio.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Encoding=UTF-8 +Name=PulseAudio Sound System +Comment=Start the PulseAudio Sound System +Exec=start-pulseaudio-x11 +Terminal=false +Type=Application +Categories= +GenericName= diff --git a/src/daemon/start-pulseaudio-x11.in b/src/daemon/start-pulseaudio-x11.in new file mode 100755 index 00000000..3cccc4dc --- /dev/null +++ b/src/daemon/start-pulseaudio-x11.in @@ -0,0 +1,31 @@ +#!/bin/sh + +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. + +set -e + +@PA_BINARY@ --start "$@" + +if [ x"$DISPLAY" != x ] ; then + +    @PACTL_BINARY@ load-module module-x11-publish "display=$DISPLAY" > /dev/null + +    if [ x"$SESSION_MANAGER" != x ] ; then +	@PACTL_BINARY@ load-module module-x11-xsmp "display=$DISPLAY session_manager=$SESSION_MANAGER" > /dev/null +    fi +fi diff --git a/src/daemon/system.pa.in b/src/daemon/system.pa.in new file mode 100755 index 00000000..f6052c4b --- /dev/null +++ b/src/daemon/system.pa.in @@ -0,0 +1,54 @@ +#!@PA_BINARY@ -nF +# +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +# This startup script is used only if PulseAudio is started in system +# mode. + +### Automatically load driver modules depending on the hardware available +.ifexists module-hal-detect@PA_SOEXT@ +load-module module-hal-detect +.else +### Alternatively use the static hardware detection module (for systems that +### lack HAL support) +load-module module-detect +.endif + +### Load several protocols +.ifexists module-esound-protocol-unix@PA_SOEXT@ +load-module module-esound-protocol-unix +.endif +load-module module-native-protocol-unix + +### Automatically restore the volume of playback streams +load-module module-volume-restore + +### Automatically restore the default sink/source when changed by the user during runtime +load-module module-default-device-restore + +### Automatically move streams to the default sink if the sink they are +### connected to dies, similar for sources +load-module module-rescue-streams + +### Make sure we always have a sink around, even if it is a null sink. +load-module module-always-sink + +### Automatically suspend sinks/sources that become idle for too long +load-module module-suspend-on-idle + +### Enable positioned event sounds +load-module module-position-event-sounds diff --git a/src/modules/module-bt-proximity.c b/src/modules/module-bt-proximity.c index 77b95868..f924c3cb 100644 --- a/src/modules/module-bt-proximity.c +++ b/src/modules/module-bt-proximity.c @@ -358,7 +358,6 @@ static int add_matches(struct userdata *u, pa_bool_t add) {      } else          dbus_bus_remove_match(pa_dbus_connection_get(u->dbus_connection), filter2, &e); -      if (add)          pa_assert_se(dbus_connection_add_filter(pa_dbus_connection_get(u->dbus_connection), filter_func, u, NULL));      else diff --git a/src/modules/module-console-kit.c b/src/modules/module-console-kit.c index 3adee99e..e1933c28 100644 --- a/src/modules/module-console-kit.c +++ b/src/modules/module-console-kit.c @@ -71,7 +71,7 @@ struct userdata {  static void add_session(struct userdata *u, const char *id) {      DBusError error;      DBusMessage *m = NULL, *reply = NULL; -    int32_t uid; +    uint32_t uid;      struct session *session;      char *t; @@ -92,10 +92,14 @@ static void add_session(struct userdata *u, const char *id) {          goto fail;      } -    /* FIXME: Why is this in int32? and not an uint32? */ -    if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID)) { -        pa_log("Failed to parse GetUnixUser() result: %s: %s", error.name, error.message); -        goto fail; +    /* CK 0.3 this changed from int32 to uint32 */ +    if (!dbus_message_get_args(reply, &error, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID)) { +        dbus_error_free(&error); + +        if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID)) { +            pa_log("Failed to parse GetUnixUser() result: %s: %s", error.name, error.message); +            goto fail; +        }      }      /* We only care about our own sessions */ @@ -163,27 +167,39 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo      if (dbus_message_is_signal(message, "org.freedesktop.ConsoleKit.Seat", "SessionAdded")) { -        if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID) || dbus_error_is_set(&error)) { -            pa_log_error("Failed to parse SessionAdded message: %s: %s", error.name, error.message); -            goto finish; +        /* CK API changed to match spec in 0.3 */ +        if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) { +            dbus_error_free(&error); + +            if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) { +                pa_log_error("Failed to parse SessionAdded message: %s: %s", error.name, error.message); +                goto finish; +            }          }          add_session(u, path); +        return DBUS_HANDLER_RESULT_HANDLED;      } else if (dbus_message_is_signal(message, "org.freedesktop.ConsoleKit.Seat", "SessionRemoved")) { -        if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID) || dbus_error_is_set(&error)) { -            pa_log_error("Failed to parse SessionRemoved message: %s: %s", error.name, error.message); -            goto finish; +        /* CK API changed to match spec in 0.3 */ +        if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) { +            dbus_error_free(&error); + +            if (!dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) { +                pa_log_error("Failed to parse SessionRemoved message: %s: %s", error.name, error.message); +                goto finish; +            }          }          remove_session(u, path); +        return DBUS_HANDLER_RESULT_HANDLED;      }  finish:      dbus_error_free(&error); -    return DBUS_HANDLER_RESULT_HANDLED; +    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;  }  static int get_session_list(struct userdata *u) { @@ -327,8 +343,17 @@ void pa__done(pa_module *m) {          pa_hashmap_free(u->sessions, NULL, NULL);      } -    if (u->connection) +    if (u->connection) { +        DBusError error; +        dbus_error_init(&error); + +        dbus_bus_remove_match(pa_dbus_connection_get(u->connection), "type='signal',sender='org.freedesktop.ConsoleKit', interface='org.freedesktop.ConsoleKit.Seat'", &error); +        dbus_error_free(&error); + +        dbus_connection_remove_filter(pa_dbus_connection_get(u->connection), filter_cb, u); +          pa_dbus_connection_unref(u->connection); +    }      pa_xfree(u);  } diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 19430a3d..ab5b206f 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -615,6 +615,8 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo                  device_added_cb(u->context, udi);          } +        return DBUS_HANDLER_RESULT_HANDLED; +      } else if (dbus_message_is_signal(message, "org.pulseaudio.Server", "DirtyGiveUpMessage")) {          /* We use this message to avoid a dirty race condition when we             get an ACLAdded message before the previously owning PA @@ -661,12 +663,14 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo          } else              /* Yes, we don't check the UDI for validity, but hopefully HAL will */              device_added_cb(u->context, udi); + +        return DBUS_HANDLER_RESULT_HANDLED;      }  finish:      dbus_error_free(&error); -    return DBUS_HANDLER_RESULT_HANDLED; +    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;  }  static void hal_context_free(LibHalContext* hal_context) { @@ -842,8 +846,20 @@ void pa__done(pa_module *m) {      if (u->devices)          pa_hashmap_free(u->devices, hal_device_free_cb, NULL); -    if (u->connection) +    if (u->connection) { +        DBusError error; +        dbus_error_init(&error); + +        dbus_bus_remove_match(pa_dbus_connection_get(u->connection), "type='signal',sender='org.freedesktop.Hal', interface='org.freedesktop.Hal.Device.AccessControl'", &error); +        dbus_error_free(&error); + +        dbus_bus_remove_match(pa_dbus_connection_get(u->connection), "type='signal',interface='org.pulseaudio.Server'", &error); +        dbus_error_free(&error); + +        dbus_connection_remove_filter(pa_dbus_connection_get(u->connection), filter_cb, u); +          pa_dbus_connection_unref(u->connection); +    }      pa_xfree(u);  } diff --git a/src/modules/module-x11-xsmp.c b/src/modules/module-x11-xsmp.c index 696826d8..0b2e375a 100644 --- a/src/modules/module-x11-xsmp.c +++ b/src/modules/module-x11-xsmp.c @@ -47,7 +47,7 @@  PA_MODULE_AUTHOR("Lennart Poettering");  PA_MODULE_DESCRIPTION("X11 session management");  PA_MODULE_VERSION(PACKAGE_VERSION); -PA_MODULE_LOAD_ONCE(TRUE); +PA_MODULE_LOAD_ONCE(FALSE);  PA_MODULE_USAGE("session_manager=<session manager string> display=<X11 display>");  static pa_bool_t ice_in_use = FALSE; diff --git a/src/pulse/channelmap.h b/src/pulse/channelmap.h index 2551eae9..7c32b868 100644 --- a/src/pulse/channelmap.h +++ b/src/pulse/channelmap.h @@ -47,8 +47,10 @@   *   * \li pa_channel_map_init_mono() - Create a channel map with only mono audio.   * \li pa_channel_map_init_stereo() - Create a standard stereo mapping. - * \li pa_channel_map_init_auto() - Create a standard channel map for up to - *                                  six channels. + * \li pa_channel_map_init_auto() - Create a standard channel map for a specific number of channels + * \li pa_channel_map_init_extend() - Similar to + * pa_channel_map_init_auto() but synthesize a channel map if noone + * predefined one is known for the specified number of channels.   *   * \section conv_sec Convenience Functions   * diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c index 2ead871f..915d0ccb 100644 --- a/src/pulse/client-conf.c +++ b/src/pulse/client-conf.c @@ -66,7 +66,7 @@ pa_client_conf *pa_client_conf_new(void) {      pa_client_conf *c = pa_xmemdup(&default_conf, sizeof(default_conf));      c->daemon_binary = pa_xstrdup(PA_BINARY); -    c->extra_arguments = pa_xstrdup("--log-target=syslog --exit-idle-time=5"); +    c->extra_arguments = pa_xstrdup("--log-target=syslog");      c->cookie_file = pa_xstrdup(PA_NATIVE_COOKIE_FILE);      return c; diff --git a/src/pulse/client.conf.in b/src/pulse/client.conf.in index 749e9688..8339d651 100644 --- a/src/pulse/client.conf.in +++ b/src/pulse/client.conf.in @@ -25,7 +25,7 @@  ; autospawn = yes  ; daemon-binary = @PA_BINARY@ -; extra-arguments = --log-target=syslog --exit-idle-time=5 +; extra-arguments = --log-target=syslog  ; cookie-file = diff --git a/src/pulse/context.h b/src/pulse/context.h index 8dff7642..3b513976 100644 --- a/src/pulse/context.h +++ b/src/pulse/context.h @@ -35,7 +35,7 @@   * \section overv_sec Overview   *   * The asynchronous API is the native interface to the PulseAudio library. - * It allows full access to all available functions. This also means that + * It allows full access to all available functionality. This however means that   * it is rather complex and can take some time to fully master.   *   * \section mainloop_sec Main Loop Abstraction @@ -64,8 +64,7 @@   *                                  implementation where all of PulseAudio's   *                                  internal handling runs in a separate   *                                  thread. - * \li \subpage glib-mainloop - A wrapper around GLIB's main loop. Available - *                              for both GLIB 1.2 and GLIB 2.x. + * \li \subpage glib-mainloop - A wrapper around GLib's main loop.   *   * UNIX signals may be hooked to a main loop using the functions from   * \ref mainloop-signal.h. These rely only on the main loop abstraction diff --git a/src/pulse/def.h b/src/pulse/def.h index 8407ddeb..95071978 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -233,12 +233,11 @@ typedef enum pa_stream_flags {      PA_STREAM_START_MUTED = 4096,  /**< Create in muted state. \since 0.9.11 */ -      PA_STREAM_ADJUST_LATENCY = 8192, /**< Try to adjust the latency of                                        * the sink/source based on the                                        * requested buffer metrics and                                        * adjust buffer metrics -                                      * accordingly. \since 0.9.11 */ +                                      * accordingly. See pa_buffer_attr \since 0.9.11 */  } pa_stream_flags_t; @@ -248,53 +247,86 @@ typedef enum pa_stream_flags {  /** Playback and record buffer metrics */  typedef struct pa_buffer_attr {      uint32_t maxlength;      /**< Maximum length of the -                              * buffer. Setting this to 0 will +                              * buffer. Setting this to (uint32_t) -1 will                                * initialize this to the maximum value                                * supported by server, which is                                * recommended. */      uint32_t tlength;        /**< Playback only: target length of the                                * buffer. The server tries to assure                                * that at least tlength bytes are always -                              * available in the buffer. It is -                              * recommended to set this to 0, which -                              * will initialize this to a value that -                              * is deemed sensible by the +                              * available in the per-stream +                              * server-side playback buffer. It is +                              * recommended to set this to (uint32_t) +                              * -1, which will initialize this to a +                              * value that is deemed sensible by the                                * server. However, this value will                                * default to something like 2s, i.e. for                                * applications that have specific                                * latency requirements this value should                                * be set to the maximum latency that the -                              * application can deal with.  */ +                              * application can deal with. When +                              * PA_STREAM_ADJUST_LATENCY is not set +                              * this value will influence only the +                              * per-stream playback buffer size. When +                              * PA_STREAM_ADJUST_LATENCY is set the +                              * overall latency of the sink plus the +                              * playback buffer size is configured to +                              * this value. Set +                              * PA_STREAM_ADJUST_LATENCY if you are +                              * interested in adjusting the overall +                              * latency. Don't set it if you are +                              * interested in configuring the +                              * server-sider per-stream playback +                              * buffer size. */      uint32_t prebuf;         /**< Playback only: pre-buffering. The                                * server does not start with playback                                * before at least prebug bytes are                                * available in the buffer. It is -                              * recommended to set this to 0, which -                              * will initialize this to the same value -                              * as tlength, whatever that may be. */ +                              * recommended to set this to (uint32_t) +                              * -1, which will initialize this to the +                              * same value as tlength, whatever that +                              * may be. Initialize to 0 to enable +                              * manual start/stop control of the +                              * stream. This means that playback will +                              * not stop on underrun and playback will +                              * not start automatically. Instead +                              * pa_stream_corked() needs to be called +                              * explicitly. If you set this value to 0 +                              * you should also set +                              * PA_STREAM_START_CORKED. */      uint32_t minreq;         /**< Playback only: minimum request. The                                * server does not request less than                                * minreq bytes from the client, instead                                * waits until the buffer is free enough                                * to request more bytes at once. It is -                              * recommended to set this to 0, which -                              * will initialize this to a value that -                              * is deemed sensible by the server. */ +                              * recommended to set this to (uint32_t) +                              * -1, which will initialize this to a +                              * value that is deemed sensible by the +                              * server. This should be set to a value +                              * that gives PulseAudio enough time to +                              * move the data from the per-stream +                              * playback buffer into the hardware +                              * playback buffer. */      uint32_t fragsize;       /**< Recording only: fragment size. The                                * server sends data in blocks of                                * fragsize bytes size. Large values                                * deminish interactivity with other                                * operations on the connection context                                * but decrease control overhead. It is -                              * recommended to set this to 0, which -                              * will initialize this to a value that -                              * is deemed sensible by the +                              * recommended to set this to (uint32_t) +                              * -1, which will initialize this to a +                              * value that is deemed sensible by the                                * server. However, this value will                                * default to something like 2s, i.e. for                                * applications that have specific                                * latency requirements this value should                                * be set to the maximum latency that the -                              * application can deal with. */ +                              * application can deal with. If +                              * PA_STREAM_ADJUST_LATENCY is set the +                              * overall source latency will be +                              * adjusted according to this value. If +                              * it is not set the source latency is +                              * left unmodified. */  } pa_buffer_attr;  /** Error values as used by pa_context_errno(). Use pa_strerror() to convert these values to human readable strings */ @@ -431,9 +463,9 @@ typedef struct pa_timing_info {                                 * PA_SEEK_RELATIVE_ON_READ                                 * instead. */ -    pa_usec_t configured_sink_usec;   /**< The static configured latency for +    pa_usec_t configured_sink_usec;   /**< The configured latency for                                  * the sink. \since 0.9.11 */ -    pa_usec_t configured_source_usec; /**< The static configured latency for +    pa_usec_t configured_source_usec; /**< The configured latency for                                  * the source. \since 0.9.11 */      int64_t since_underrun;    /**< Bytes that were handed to the sink diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h index c8c13a75..6a6755e7 100644 --- a/src/pulse/introspect.h +++ b/src/pulse/introspect.h @@ -130,8 +130,10 @@   *   * \subsection autoload_subsec Autoload Entries   * - * Modules can be autoloaded as a result of a client requesting a certain - * sink or source. This mapping between sink/source names and modules can be + * Modules can be autoloaded as a result of a client requesting a + * certain sink or source. Please note that autoloading is deprecated + * in 0.9.11. and is likely to be removed from the API in a later + * version. This mapping between sink/source names and modules can be   * queried from the server:   *   * \li By index - pa_context_get_autoload_info_by_index() @@ -191,7 +193,9 @@   *   * New module autoloading rules can be added, and existing can be removed   * using pa_context_add_autoload() and pa_context_remove_autoload_by_index() - * / pa_context_remove_autoload_by_name(). + * / pa_context_remove_autoload_by_name(). Please note that autoloading is deprecated + * in 0.9.11. and is likely to be removed from the API in a later + * version.   *   * \subsection client_subsec Clients   * diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h index f75cca54..39d53303 100644 --- a/src/pulse/proplist.h +++ b/src/pulse/proplist.h @@ -36,19 +36,20 @@ PA_C_DECL_BEGIN   *    media.artist                  "Guns'N'Roses"   *    media.language                "de_DE"   *    media.filename - *    media.icon - *    media.icon_name + *    media.icon                    Binary blob containing PNG icon data + *    media.icon_name               Name from XDG icon naming spec   *    media.role                    video, music, game, event, phone, production, filter, abstract, stream - *    event.id                      button-click, session-login + *    event.id                      Name from XDG sound naming spec + *    event.description             "Button blabla clicked" for a11y   *    event.mouse.x   *    event.mouse.y - *    event.mouse.hpos - *    event.mouse.vpos - *    event.mouse.button + *    event.mouse.hpos              Float formatted as string in range 0..1 + *    event.mouse.vpos              Float formatted as string in range 0..1 + *    event.mouse.button            Button number following X11 ordering   *    window.name - *    window.id - *    window.icon - *    window.icon_name + *    window.id                     "org.gnome.rhytmbox.MainWindow" + *    window.icon                   Binary blob containing PNG icon data + *    window.icon_name              Name from XDG icon naming spec   *    window.x11.display   *    window.x11.screen   *    window.x11.monitor @@ -56,23 +57,23 @@ PA_C_DECL_BEGIN   *    application.name              "Rhythmbox Media Player"   *    application.id                "org.gnome.rhythmbox"   *    application.version - *    application.icon - *    application.icon_name + *    application.icon              Binary blob containing PNG icon data + *    application.icon_name         Name from XDG icon naming spec   *    application.language   *    application.process.id   *    application.process.binary   *    application.process.user   *    application.process.host   *    device.string - *    device.api                     oss, alsa, sunaudio + *    device.api                    oss, alsa, sunaudio   *    device.description   *    device.bus_path   *    device.serial   *    device.vendor_product_id - *    device.class                   sound, modem, monitor, filter, abstract - *    device.form_factor             laptop-speakers, external-speakers, telephone, tv-capture, webcam-capture, microphone-capture, headset - *    device.connector               isa, pci, usb, firewire, bluetooth - *    device.access_mode             mmap, mmap_rewrite, serial + *    device.class                  sound, modem, monitor, filter, abstract + *    device.form_factor            laptop-speakers, external-speakers, telephone, tv-capture, webcam-capture, microphone-capture, headset + *    device.connector              isa, pci, usb, firewire, bluetooth + *    device.access_mode            mmap, mmap_rewrite, serial   *    device.master_device   *    device.bufferin.buffer_size   *    device.bufferin.fragment_size @@ -86,6 +87,7 @@ PA_C_DECL_BEGIN  #define PA_PROP_MEDIA_ICON_NAME                "media.icon_name"  #define PA_PROP_MEDIA_ROLE                     "media.role"  #define PA_PROP_EVENT_ID                       "event.id" +#define PA_PROP_EVENT_DESCRIPTION              "event.description"  #define PA_PROP_EVENT_MOUSE_X                  "event.mouse.x"  #define PA_PROP_EVENT_MOUSE_Y                  "event.mouse.y"  #define PA_PROP_EVENT_MOUSE_HPOS               "event.mouse.hpos" diff --git a/src/pulse/pulseaudio.h b/src/pulse/pulseaudio.h index 4a4531e6..e09cacaf 100644 --- a/src/pulse/pulseaudio.h +++ b/src/pulse/pulseaudio.h @@ -89,17 +89,17 @@   *   * \section thread_sec Threads   * - * The PulseAudio client libraries are not designed to be used in a - * heavily threaded environment. They are however designed to be reentrant - * safe. + * The PulseAudio client libraries are not designed to be directly + * thread-safe. They are however designed to be reentrant and + * threads-aware.   * - * To use a the libraries in a threaded environment, you must assure that + * To use the libraries in a threaded environment, you must assure that   * all objects are only used in one thread at a time. Normally, this means   * that all objects belonging to a single context must be accessed from the   * same thread.   *   * The included main loop implementation is also not thread safe. Take care - * to make sure event lists are not manipulated when any other code is + * to make sure event objects are not manipulated when any other code is   * using the main loop.   *   * \section pkgconfig pkg-config diff --git a/src/pulse/sample.h b/src/pulse/sample.h index 1ba3f871..2680cf7e 100644 --- a/src/pulse/sample.h +++ b/src/pulse/sample.h @@ -52,7 +52,7 @@   * \li PA_SAMPLE_S32LE - Signed 32 bit integer PCM, little endian.   * \li PA_SAMPLE_S32BE - Signed 32 bit integer PCM, big endian.   * - * The floating point sample formats have the range from -1 to 1. + * The floating point sample formats have the range from -1.0 to 1.0.   *   * The sample formats that are sensitive to endianness have convenience   * macros for native endian (NE), and reverse endian (RE). diff --git a/src/pulse/stream.h b/src/pulse/stream.h index fbf0ae44..2a8f7a8b 100644 --- a/src/pulse/stream.h +++ b/src/pulse/stream.h @@ -70,35 +70,85 @@   *   * \subsection bufattr_subsec Buffer Attributes   * - * Playback and record streams always have a server side buffer as - * part of the data flow.  The size of this buffer strikes a - * compromise between low latency and sensitivity for buffer + * Playback and record streams always have a server-side buffer as + * part of the data flow.  The size of this buffer needs to be chosen + * in a compromise between low latency and sensitivity for buffer   * overflows/underruns.   *   * The buffer metrics may be controlled by the application. They are   * described with a pa_buffer_attr structure which contains a number   * of fields:   * - * \li maxlength - The absolute maximum number of bytes that can be stored in - *                 the buffer. If this value is exceeded then data will be - *                 lost. - * \li tlength - The target length of a playback buffer. The server will only - *               send requests for more data as long as the buffer has less - *               than this number of bytes of data. + * \li maxlength - The absolute maximum number of bytes that can be + *                 stored in the buffer. If this value is exceeded + *                 then data will be lost. It is recommended to pass + *                 (uint32_t) -1 here which will cause the server to + *                 fill in the maximum possible value. + * + * \li tlength - The target fill level of the playback buffer. The + *               server will only send requests for more data as long + *               as the buffer has less than this number of bytes of + *               data. If you pass (uint32_t) -1 (which is + *               recommended) here the server will choose the longest + *               target buffer fill level possible to minimize the + *               number of necessary wakeups and maximize drop-out + *               safety. This can exceed 2s of buffering. For + *               low-latency applications or applications where + *               latency matters you should pass a proper value here. + *   * \li prebuf - Number of bytes that need to be in the buffer before - * playback will commence. Start of playback can be forced using - * pa_stream_trigger() even though the prebuffer size hasn't been - * reached. If a buffer underrun occurs, this prebuffering will be - * again enabled. If the playback shall never stop in case of a buffer - * underrun, this value should be set to 0. In that case the read - * index of the output buffer overtakes the write index, and hence the - * fill level of the buffer is negative. - * \li minreq - Minimum free number of the bytes in the playback buffer before - *              the server will request more data. - * \li fragsize - Maximum number of bytes that the server will push in one - *                chunk for record streams. - * - * The server side playback buffers are indexed by a write and a read + *              playback will commence. Start of playback can be + *              forced using pa_stream_trigger() even though the + *              prebuffer size hasn't been reached. If a buffer + *              underrun occurs, this prebuffering will be again + *              enabled. If the playback shall never stop in case of a + *              buffer underrun, this value should be set to 0. In + *              that case the read index of the output buffer + *              overtakes the write index, and hence the fill level of + *              the buffer is negative. If you pass (uint32_t) -1 here + *              (which is recommended) the server will choose the same + *              value as tlength here. + * + * \li minreq - Minimum free number of the bytes in the playback + *              buffer before the server will request more data. It is + *              recommended to fill in (uint32_t) -1 here. This value + *              influences how much time the sound server has to move + *              data from the per-stream server-side playback buffer + *              to the hardware playback buffer. + * + * \li fragsize - Maximum number of bytes that the server will push in + *                one chunk for record streams. If you pass (uint32_t) + *                -1 (which is recommended) here, the server will + *                choose the longest fragment setting possible to + *                minimize the number of necessary wakeups and + *                maximize drop-out safety. This can exceed 2s of + *                buffering. For low-latency applications or + *                applications where latency matters you should pass a + *                proper value here. + * + * If PA_STREAM_ADJUST_LATENCY is set, then the tlength/fragsize + * parameters will be interpreted slightly differently than described + * above when passed to pa_stream_connect_record() and + * pa_stream_connect_playback(): the overall latency that is comprised + * of both the server side playback buffer length, the hardware + * playback buffer length and additional latencies will be adjusted in + * a way that it matches tlength resp. fragsize. Set + * PA_STREAM_ADJUST_LATENCY if you want to control the overall + * playback latency for your stream. Unset it if you want to control + * only the latency induced by the server-side, rewritable playback + * buffer. The server will try to fulfill the clients latency requests + * as good as possible. However if the underlying hardware cannot + * change the hardware buffer length or only in a limited range, the + * actually resulting latency might be different from what the client + * requested. Thus, for synchronization clients always need to check + * the actual measured latency via pa_stream_get_latency() or a + * similar call, and not make any assumptions. about the latency + * available. The function pa_stream_get_buffer_attr() will always + * return the actual size of the server-side per-stream buffer in + * tlength/fragsize, regardless whether PA_STREAM_ADJUST_LATENCY is + * set or not. + * + * The server-side per-stream playback buffers are indexed by a write and a read   * index. The application writes to the write index and the sound   * device reads from the read index. The read index is increased   * monotonically, while the write index may be freely controlled by @@ -196,10 +246,10 @@   * accordingly.   *   * The raw timing data in the pa_timing_info structure is usually hard - * to deal with. Therefore a more simplistic interface is available: + * to deal with. Therefore a simpler interface is available:   * you can call pa_stream_get_time() or pa_stream_get_latency(). The   * former will return the current playback time of the hardware since - * the stream has been started. The latter returns the time a sample + * the stream has been started. The latter returns the overall time a sample   * that you write now takes to be played by the hardware. These two   * functions base their calculations on the same data that is returned   * by pa_stream_get_timing_info(). Hence the same rules for keeping @@ -512,9 +562,14 @@ const pa_sample_spec* pa_stream_get_sample_spec(pa_stream *s);  /** Return a pointer to the stream's channel map. */  const pa_channel_map* pa_stream_get_channel_map(pa_stream *s); -/** Return the buffer metrics of the stream. Only valid after the - * stream has been connected successfuly and if the server is at least - * PulseAudio 0.9. \since 0.9.0 */ +/** Return the per-stream server-side buffer metrics of the + * stream. Only valid after the stream has been connected successfuly + * and if the server is at least PulseAudio 0.9. This will return the + * actual configured buffering metrics, which may differ from what was + * requested during pa_stream_connect_record() or + * pa_stream_connect_playback(). This call will always return the + * actually per-stream server-side buffer metrics, regardless whether + * PA_STREAM_ADJUST_LATENCY is set or not. \since 0.9.0 */  const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s);  /** Change the buffer metrics of the stream during playback. The @@ -522,7 +577,9 @@ const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s);   * requested. The selected metrics may be queried with   * pa_stream_get_buffer_attr() as soon as the callback is called. Only   * valid after the stream has been connected successfully and if the - * server is at least PulseAudio 0.9.8. \since 0.9.8 */ + * server is at least PulseAudio 0.9.8. Please be aware of the + * slightly different semantics of the call depending whether + * PA_STREAM_ADJUST_LATENCY is set or not. \since 0.9.8 */  pa_operation *pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr, pa_stream_success_cb_t cb, void *userdata);  /** Change the stream sampling rate during playback. You need to pass diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index d259fb16..c4818e39 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -177,7 +177,7 @@ int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {  #else      {      mode_t u; -    u = umask(~m); +    u = umask((~m) & 0777);      r = mkdir(dir, m);      umask(u);      } @@ -1887,17 +1887,21 @@ int pa_close_allv(const int except_fds[]) {      if (getrlimit(RLIMIT_NOFILE, &rl) < 0)          return -1; -    for (fd = 0; fd < (int) rl.rlim_max; fd++) { +    for (fd = 3; fd < (int) rl.rlim_max; fd++) {          int i; +        pa_bool_t found; -        if (fd <= 3) -            continue; - +        found = FALSE;          for (i = 0; except_fds[i] >= 0; i++) -            if (except_fds[i] == fd) -                continue; +            if (except_fds[i] == fd) { +                found = TRUE; +                break; +            } -        if (close(fd) < 0 && errno != EBADF) +        if (found) +            continue; + +        if (pa_close(fd) < 0 && errno != EBADF)              return -1;      } @@ -1972,10 +1976,11 @@ int pa_reset_sigs(int except, ...) {      i = 0;      if (except >= 1) { +        int sig;          p[i++] = except; -        while ((p[i++] = va_arg(ap, int)) >= 0) -            ; +        while ((sig = va_arg(ap, int)) >= 0) +            sig = p[i++];      }      p[i] = -1; diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 74971035..4102f31d 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -261,22 +261,31 @@ pa_sink* pa_sink_new(  static int sink_set_state(pa_sink *s, pa_sink_state_t state) {      int ret;      pa_bool_t suspend_change; +    pa_sink_state_t original_state;      pa_assert(s);      if (s->state == state)          return 0; +    original_state = s->state; +      suspend_change = -        (s->state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(state)) || -        (PA_SINK_IS_OPENED(s->state) && state == PA_SINK_SUSPENDED); +        (original_state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(state)) || +        (PA_SINK_IS_OPENED(original_state) && state == PA_SINK_SUSPENDED);      if (s->set_state)          if ((ret = s->set_state(s, state)) < 0) -            return -1; +            return ret;      if (s->asyncmsgq) -        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0); +        if ((ret = pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL)) < 0) { + +            if (s->set_state) +                s->set_state(s, original_state); + +            return ret; +        }      s->state = state; diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index e62c6c24..95007af4 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -224,22 +224,31 @@ pa_source* pa_source_new(  static int source_set_state(pa_source *s, pa_source_state_t state) {      int ret;      pa_bool_t suspend_change; +    pa_source_state_t original_state;      pa_assert(s);      if (s->state == state)          return 0; +    original_state = s->state; +      suspend_change = -        (s->state == PA_SOURCE_SUSPENDED && PA_SOURCE_IS_OPENED(state)) || -        (PA_SOURCE_IS_OPENED(s->state) && state == PA_SOURCE_SUSPENDED); +        (original_state == PA_SOURCE_SUSPENDED && PA_SOURCE_IS_OPENED(state)) || +        (PA_SOURCE_IS_OPENED(original_state) && state == PA_SOURCE_SUSPENDED);      if (s->set_state)          if ((ret = s->set_state(s, state)) < 0) -            return -1; +            return ret;      if (s->asyncmsgq) -        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0); +        if ((ret = pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL)) < 0) { + +            if (s->set_state) +                s->set_state(s, original_state); + +            return ret; +        }      s->state = state; | 
