diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/daemon/main.c | 3 | ||||
| -rw-r--r-- | src/map-file | 1 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-mixer.c | 24 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-sink.c | 5 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-source.c | 5 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-util.c | 24 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-util.h | 2 | ||||
| -rw-r--r-- | src/modules/alsa/mixer/paths/analog-output.conf.common | 17 | ||||
| -rw-r--r-- | src/modules/jack/module-jack-sink.c | 2 | ||||
| -rw-r--r-- | src/modules/jack/module-jack-source.c | 2 | ||||
| -rw-r--r-- | src/modules/module-lirc.c | 26 | ||||
| -rw-r--r-- | src/modules/module-mmkbd-evdev.c | 26 | ||||
| -rw-r--r-- | src/pulse/ext-device-manager.h | 24 | ||||
| -rw-r--r-- | src/pulse/volume.c | 10 | ||||
| -rw-r--r-- | src/pulse/volume.h | 4 | ||||
| -rw-r--r-- | src/pulsecore/core-util.c | 93 | ||||
| -rw-r--r-- | src/pulsecore/core-util.h | 3 | ||||
| -rw-r--r-- | src/pulsecore/protocol-native.c | 2 | ||||
| -rw-r--r-- | src/pulsecore/sink-input.c | 11 | 
19 files changed, 232 insertions, 52 deletions
| diff --git a/src/daemon/main.c b/src/daemon/main.c index cc6f24bd..48911827 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -648,7 +648,6 @@ int main(int argc, char *argv[]) {      if (conf->daemonize) {          pid_t child; -        int tty_fd;          if (pa_stdio_acquire() < 0) {              pa_log(_("Failed to acquire stdio.")); @@ -781,6 +780,8 @@ int main(int argc, char *argv[]) {      pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind())); +    pa_log_debug(_("Running in VM: %s"), pa_yes_no(pa_running_in_vm())); +  #ifdef __OPTIMIZE__      pa_log_debug(_("Optimized build: yes"));  #else diff --git a/src/map-file b/src/map-file index 50111224..1fffaff9 100644 --- a/src/map-file +++ b/src/map-file @@ -130,6 +130,7 @@ pa_cvolume_get_balance;  pa_cvolume_get_fade;  pa_cvolume_get_position;  pa_cvolume_inc; +pa_cvolume_inc_clamp;  pa_cvolume_init;  pa_cvolume_max;  pa_cvolume_max_mask; diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index f3ce681f..8b13239c 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -1712,7 +1712,9 @@ static int option_verify(pa_alsa_option *o) {          { "input-boost-on",            N_("Boost") },          { "input-boost-off",           N_("No Boost") },          { "output-amplifier-on",       N_("Amplifier") }, -        { "output-amplifier-off",      N_("No Amplifier") } +        { "output-amplifier-off",      N_("No Amplifier") }, +        { "output-speaker",            N_("Speaker") }, +        { "output-headphones",         N_("Headphones") }      };      pa_assert(o); @@ -1770,15 +1772,17 @@ static int element_verify(pa_alsa_element *e) {  static int path_verify(pa_alsa_path *p) {      static const struct description_map well_known_descriptions[] = { -        { "analog-input",              N_("Analog Input") }, -        { "analog-input-microphone",   N_("Analog Microphone") }, -        { "analog-input-linein",       N_("Analog Line-In") }, -        { "analog-input-radio",        N_("Analog Radio") }, -        { "analog-input-video",        N_("Analog Video") }, -        { "analog-output",             N_("Analog Output") }, -        { "analog-output-headphones",  N_("Analog Headphones") }, -        { "analog-output-lfe-on-mono", N_("Analog Output (LFE)") }, -        { "analog-output-mono",        N_("Analog Mono Output") } +        { "analog-input",               N_("Analog Input") }, +        { "analog-input-microphone",    N_("Analog Microphone") }, +        { "analog-input-linein",        N_("Analog Line-In") }, +        { "analog-input-radio",         N_("Analog Radio") }, +        { "analog-input-video",         N_("Analog Video") }, +        { "analog-output",              N_("Analog Output") }, +        { "analog-output-headphones",   N_("Analog Headphones") }, +        { "analog-output-lfe-on-mono",  N_("Analog Output (LFE)") }, +        { "analog-output-mono",         N_("Analog Mono Output") }, +        { "analog-output-headphones-2", N_("Analog Headphones 2") }, +        { "analog-output-speaker",      N_("Analog Speaker") }      };      pa_alsa_element *e; diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 37419d98..856adb14 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1698,10 +1698,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca          goto fail;      } -    if (use_tsched && !pa_rtclock_hrtimer()) { -        pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel."); -        use_tsched = FALSE; -    } +    use_tsched = pa_alsa_may_tsched(use_tsched);      u = pa_xnew0(struct userdata, 1);      u->core = m->core; diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 37dd6476..e775b20c 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -1541,10 +1541,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p          goto fail;      } -    if (use_tsched && !pa_rtclock_hrtimer()) { -        pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel."); -        use_tsched = FALSE; -    } +    use_tsched = pa_alsa_may_tsched(use_tsched);      u = pa_xnew0(struct userdata, 1);      u->core = m->core; diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index 0e22d17e..b8d13575 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -43,6 +43,7 @@  #include <pulsecore/once.h>  #include <pulsecore/thread.h>  #include <pulsecore/conf-parser.h> +#include <pulsecore/core-rtclock.h>  #include "alsa-util.h"  #include "alsa-mixer.h" @@ -1308,3 +1309,26 @@ const char* pa_alsa_strerror(int errnum) {      return translated;  } + +pa_bool_t pa_alsa_may_tsched(pa_bool_t want) { + +    if (!want) +        return FALSE; + +    if (!pa_rtclock_hrtimer()) { +        /* We cannot depend on being woken up in time when the timers +        are inaccurate, so let's fallback to classic IO based playback +        then. */ +        pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel."); +        return FALSE; } + +    if (pa_running_in_vm()) { +        /* We cannot depend on being woken up when we ask for in a VM, +         * so let's fallback to classic IO based playback then. */ +        pa_log_notice("Disabling timer-based scheduling because running inside a VM."); +        return FALSE; +    } + + +    return TRUE; +} diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h index f6206fe2..1d1256bd 100644 --- a/src/modules/alsa/alsa-util.h +++ b/src/modules/alsa/alsa-util.h @@ -142,4 +142,6 @@ pa_bool_t pa_alsa_pcm_is_modem(snd_pcm_t *pcm);  const char* pa_alsa_strerror(int errnum); +pa_bool_t pa_alsa_may_tsched(pa_bool_t want); +  #endif diff --git a/src/modules/alsa/mixer/paths/analog-output.conf.common b/src/modules/alsa/mixer/paths/analog-output.conf.common index 3c6ce803..fd7f0cfb 100644 --- a/src/modules/alsa/mixer/paths/analog-output.conf.common +++ b/src/modules/alsa/mixer/paths/analog-output.conf.common @@ -109,3 +109,20 @@ priority = 10  [Option External Amplifier:off]  name = output-amplifier-off  priority = 0 + +;;; 'Analog Output' + +[Element Analog Output] +enumeration = select + +[Option Analog Output:Speakers] +name = output-speaker +priority = 10 + +[Option Analog Output:Headphones] +name = output-headphones +priority = 9 + +[Option Analog Output:FP Headphones] +name = output-headphones +priority = 8 diff --git a/src/modules/jack/module-jack-sink.c b/src/modules/jack/module-jack-sink.c index fc976fa7..9f3e071f 100644 --- a/src/modules/jack/module-jack-sink.c +++ b/src/modules/jack/module-jack-sink.c @@ -334,7 +334,7 @@ int pa__init(pa_module*m) {          goto fail;      } -    ports = jack_get_ports(u->client, NULL, NULL, JackPortIsPhysical|JackPortIsInput); +    ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsInput);      channels = 0;      for (p = ports; *p; p++) diff --git a/src/modules/jack/module-jack-source.c b/src/modules/jack/module-jack-source.c index a898e0e5..6c68527b 100644 --- a/src/modules/jack/module-jack-source.c +++ b/src/modules/jack/module-jack-source.c @@ -286,7 +286,7 @@ int pa__init(pa_module*m) {          goto fail;      } -    ports = jack_get_ports(u->client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput); +    ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsOutput);      channels = 0;      for (p = ports; *p; p++) diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c index d0e902f6..e9778620 100644 --- a/src/modules/module-lirc.c +++ b/src/modules/module-lirc.c @@ -45,12 +45,14 @@ PA_MODULE_AUTHOR("Lennart Poettering");  PA_MODULE_DESCRIPTION("LIRC volume control");  PA_MODULE_VERSION(PACKAGE_VERSION);  PA_MODULE_LOAD_ONCE(TRUE); -PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name>"); +PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name> volume_limit=<volume limit> volume_step=<volume change step>");  static const char* const valid_modargs[] = {      "config",      "sink",      "appname", +    "volume_limit", +    "volume_step",      NULL,  }; @@ -61,10 +63,10 @@ struct userdata {      char *sink_name;      pa_module *module;      float mute_toggle_save; +    pa_volume_t volume_limit; +    pa_volume_t volume_step;  }; -#define DELTA (PA_VOLUME_NORM/20) -  static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {      struct userdata *u = userdata;      char *name = NULL, *code = NULL; @@ -125,12 +127,12 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event                      switch (volchange) {                          case UP: -                            pa_cvolume_inc(&cv, DELTA); +                            pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit);                              pa_sink_set_volume(s, &cv, TRUE, TRUE);                              break;                          case DOWN: -                            pa_cvolume_dec(&cv, DELTA); +                            pa_cvolume_dec(&cv, u->volume_step);                              pa_sink_set_volume(s, &cv, TRUE, TRUE);                              break; @@ -170,6 +172,8 @@ fail:  int pa__init(pa_module*m) {      pa_modargs *ma = NULL;      struct userdata *u; +    pa_volume_t volume_limit = PA_VOLUME_NORM*3/2; +    pa_volume_t volume_step = PA_VOLUME_NORM/20;      pa_assert(m); @@ -178,6 +182,16 @@ int pa__init(pa_module*m) {          goto fail;      } +    if (pa_modargs_get_value_u32(ma, "volume_limit", &volume_limit) < 0) { +        pa_log("Failed to parse volume limit"); +        goto fail; +    } + +    if (pa_modargs_get_value_u32(ma, "volume_step", &volume_step) < 0) { +        pa_log("Failed to parse volume step"); +        goto fail; +    } +      m->userdata = u = pa_xnew(struct userdata, 1);      u->module = m;      u->io = NULL; @@ -185,6 +199,8 @@ int pa__init(pa_module*m) {      u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));      u->lirc_fd = -1;      u->mute_toggle_save = 0; +    u->volume_limit = volume_limit; +    u->volume_step = volume_step;      if ((u->lirc_fd = lirc_init((char*) pa_modargs_get_value(ma, "appname", "pulseaudio"), 1)) < 0) {          pa_log("lirc_init() failed."); diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c index 14a9dd3d..193c1f40 100644 --- a/src/modules/module-mmkbd-evdev.c +++ b/src/modules/module-mmkbd-evdev.c @@ -48,13 +48,15 @@ PA_MODULE_AUTHOR("Lennart Poettering");  PA_MODULE_DESCRIPTION("Multimedia keyboard support via Linux evdev");  PA_MODULE_VERSION(PACKAGE_VERSION);  PA_MODULE_LOAD_ONCE(FALSE); -PA_MODULE_USAGE("device=<evdev device> sink=<sink name>"); +PA_MODULE_USAGE("device=<evdev device> sink=<sink name> volume_limit=<volume limit> volume_step=<volume change step>");  #define DEFAULT_DEVICE "/dev/input/event0"  static const char* const valid_modargs[] = {      "device",      "sink", +    "volume_limit", +    "volume_step",      NULL,  }; @@ -63,10 +65,10 @@ struct userdata {      pa_io_event *io;      char *sink_name;      pa_module *module; +    pa_volume_t volume_limit; +    pa_volume_t volume_step;  }; -#define DELTA (PA_VOLUME_NORM/20) -  static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {      struct userdata *u = userdata; @@ -120,12 +122,12 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event                      switch (volchange) {                          case UP: -                            pa_cvolume_inc(&cv, DELTA); +                            pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit);                              pa_sink_set_volume(s, &cv, TRUE, TRUE);                              break;                          case DOWN: -                            pa_cvolume_dec(&cv, DELTA); +                            pa_cvolume_dec(&cv, u->volume_step);                              pa_sink_set_volume(s, &cv, TRUE, TRUE);                              break; @@ -160,6 +162,8 @@ int pa__init(pa_module*m) {      struct input_id input_id;      char name[256];      uint8_t evtype_bitmask[EV_MAX/8 + 1]; +    pa_volume_t volume_limit = PA_VOLUME_NORM*3/2; +    pa_volume_t volume_step = PA_VOLUME_NORM/20;      pa_assert(m); @@ -168,12 +172,24 @@ int pa__init(pa_module*m) {          goto fail;      } +    if (pa_modargs_get_value_u32(ma, "volume_limit", &volume_limit) < 0) { +        pa_log("Failed to parse volume limit"); +        goto fail; +    } + +    if (pa_modargs_get_value_u32(ma, "volume_step", &volume_step) < 0) { +        pa_log("Failed to parse volume step"); +        goto fail; +    } +      m->userdata = u = pa_xnew(struct userdata, 1);      u->module = m;      u->io = NULL;      u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));      u->fd = -1;      u->fd_type = 0; +    u->volume_limit = volume_limit; +    u->volume_step = volume_step;      if ((u->fd = pa_open_cloexec(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY, 0)) < 0) {          pa_log("Failed to open evdev device: %s", pa_cstrerror(errno)); diff --git a/src/pulse/ext-device-manager.h b/src/pulse/ext-device-manager.h index 1442a1a9..8264b8f7 100644 --- a/src/pulse/ext-device-manager.h +++ b/src/pulse/ext-device-manager.h @@ -39,7 +39,7 @@ typedef struct pa_ext_device_manager_role_priority_info {  } pa_ext_device_manager_role_priority_info;  /** Stores information about one device in the device database that is - * maintained by module-device-manager. \since 0.9.19 */ + * maintained by module-device-manager. \since 0.9.20 */  typedef struct pa_ext_device_manager_info {      const char *name;            /**< Identifier string of the device. A string like "sink:" or similar followed by the name of the device. */      const char *description;     /**< The description of the device when it was last seen, if applicable and saved */ @@ -49,32 +49,32 @@ typedef struct pa_ext_device_manager_info {      pa_ext_device_manager_role_priority_info *role_priorities; /**< An array of role priority structures or NULL */  } pa_ext_device_manager_info; -/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.19 */ +/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.20 */  typedef void (*pa_ext_device_manager_test_cb_t)(          pa_context *c,          uint32_t version,          void *userdata); -/** Test if this extension module is available in the server. \since 0.9.19 */ +/** Test if this extension module is available in the server. \since 0.9.20 */  pa_operation *pa_ext_device_manager_test(          pa_context *c,          pa_ext_device_manager_test_cb_t cb,          void *userdata); -/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.19 */ +/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.20 */  typedef void (*pa_ext_device_manager_read_cb_t)(          pa_context *c,          const pa_ext_device_manager_info *info,          int eol,          void *userdata); -/** Read all entries from the device database. \since 0.9.19 */ +/** Read all entries from the device database. \since 0.9.20 */  pa_operation *pa_ext_device_manager_read(          pa_context *c,          pa_ext_device_manager_read_cb_t cb,          void *userdata); -/** Sets the description for a device. \since 0.9.19 */ +/** Sets the description for a device. \since 0.9.20 */  pa_operation *pa_ext_device_manager_set_device_description(          pa_context *c,          const char* device, @@ -82,21 +82,21 @@ pa_operation *pa_ext_device_manager_set_device_description(          pa_context_success_cb_t cb,          void *userdata); -/** Delete entries from the device database. \since 0.9.19 */ +/** Delete entries from the device database. \since 0.9.20 */  pa_operation *pa_ext_device_manager_delete(          pa_context *c,          const char *const s[],          pa_context_success_cb_t cb,          void *userdata); -/** Enable the role-based device-priority routing mode. \since 0.9.19 */ +/** Enable the role-based device-priority routing mode. \since 0.9.20 */  pa_operation *pa_ext_device_manager_enable_role_device_priority_routing(          pa_context *c,          int enable,          pa_context_success_cb_t cb,          void *userdata); -/** Prefer a given device in the priority list. \since 0.9.19 */ +/** Prefer a given device in the priority list. \since 0.9.20 */  pa_operation *pa_ext_device_manager_reorder_devices_for_role(          pa_context *c,          const char* role, @@ -104,20 +104,20 @@ pa_operation *pa_ext_device_manager_reorder_devices_for_role(          pa_context_success_cb_t cb,          void *userdata); -/** Subscribe to changes in the device database. \since 0.9.19 */ +/** Subscribe to changes in the device database. \since 0.9.20 */  pa_operation *pa_ext_device_manager_subscribe(          pa_context *c,          int enable,          pa_context_success_cb_t cb,          void *userdata); -/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.19 */ +/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.20 */  typedef void (*pa_ext_device_manager_subscribe_cb_t)(          pa_context *c,          void *userdata);  /** Set the subscription callback that is called when - * pa_ext_device_manager_subscribe() was called. \since 0.9.19 */ + * pa_ext_device_manager_subscribe() was called. \since 0.9.20 */  void pa_ext_device_manager_set_subscribe_cb(          pa_context *c,          pa_ext_device_manager_subscribe_cb_t cb, diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 2d2bba25..59e9a189 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -885,7 +885,7 @@ pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvo      return dest;  } -pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc) { +pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit) {      pa_volume_t m;      pa_assert(v); @@ -895,14 +895,18 @@ pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc) {      m = pa_cvolume_max(v); -    if (m >= PA_VOLUME_MAX - inc) -        m = PA_VOLUME_MAX; +    if (m >= limit - inc) +        m = limit;      else          m += inc;      return pa_cvolume_scale(v, m);  } +pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc){ +    return pa_cvolume_inc_clamp(v, inc, PA_VOLUME_MAX); +} +  pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) {      pa_volume_t m; diff --git a/src/pulse/volume.h b/src/pulse/volume.h index c964020a..ded4422e 100644 --- a/src/pulse/volume.h +++ b/src/pulse/volume.h @@ -348,6 +348,10 @@ pa_volume_t pa_cvolume_get_position(pa_cvolume *cv, const pa_channel_map *map, p   * and dest may point to the same structure. \since 0.9.16 */  pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b); +/** Increase the volume passed in by 'inc', but not exceeding 'limit'. + * The proportions between the channels are kept. \since 0.9.19 */ +pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit); +  /** Increase the volume passed in by 'inc'. The proportions between   * the channels are kept. \since 0.9.16 */  pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc); diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 2b0a60a8..d596c481 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -117,6 +117,7 @@  #include <pulsecore/strbuf.h>  #include <pulsecore/usergroup.h>  #include <pulsecore/strlist.h> +#include <pulsecore/cpu-x86.h>  #include "core-util.h" @@ -2944,6 +2945,7 @@ int pa_pipe_cloexec(int pipefd[2]) {      if (errno != EINVAL && errno != ENOSYS)          return r; +  #endif      if ((r = pipe(pipefd)) < 0) @@ -2965,6 +2967,7 @@ int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {      if (errno != EINVAL && errno != ENOSYS)          return fd; +  #endif      if ((fd = accept(sockfd, addr, addrlen)) < 0) @@ -3015,3 +3018,93 @@ void pa_nullify_stdfds(void) {  #endif  } + +char *pa_read_line_from_file(const char *fn) { +    FILE *f; +    char ln[256] = "", *r; + +    if (!(f = pa_fopen_cloexec(fn, "r"))) +        return NULL; + +    r = fgets(ln, sizeof(ln)-1, f); +    fclose(f); + +    if (!r) { +        errno = EIO; +        return NULL; +    } + +    pa_strip_nl(ln); +    return pa_xstrdup(ln); +} + +pa_bool_t pa_running_in_vm(void) { + +#if defined(__i386__) || defined(__x86_64__) + +    /* Both CPUID and DMI are x86 specific interfaces... */ + +    uint32_t eax = 0x40000000; +    union { +        uint32_t sig32[3]; +        char text[13]; +    } sig; + +#ifdef __linux__ +    const char *const dmi_vendors[] = { +        "/sys/class/dmi/id/sys_vendor", +        "/sys/class/dmi/id/board_vendor", +        "/sys/class/dmi/id/bios_vendor" +    }; + +    unsigned i; + +    for (i = 0; i < PA_ELEMENTSOF(dmi_vendors); i++) { +        char *s; + +        if ((s = pa_read_line_from_file(dmi_vendors[i]))) { + +            if (pa_startswith(s, "QEMU") || +                /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ +                pa_startswith(s, "VMware") || +                pa_startswith(s, "VMW") || +                pa_startswith(s, "Microsoft Corporation") || +                pa_startswith(s, "innotek GmbH") || +                pa_startswith(s, "Xen")) { + +                pa_xfree(s); +                return TRUE; +            } + +            pa_xfree(s); +        } +    } + +#endif + +    /* http://lwn.net/Articles/301888/ */ +    pa_zero(sig); + +    __asm__ __volatile__ ( +        /* ebx/rbx is being used for PIC! */ +        "  push %%"PA_REG_b"         \n\t" +        "  cpuid                     \n\t" +        "  mov %%ebx, %1             \n\t" +        "  pop %%"PA_REG_b"          \n\t" + +        : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2]) +        : "0" (eax) +    ); + +    if (pa_streq(sig.text, "XenVMMXenVMM") || +        pa_streq(sig.text, "KVMKVMKVM") || +        /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ +        pa_streq(sig.text, "VMwareVMware") || +        /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */ +        pa_streq(sig.text, "Microsoft Hv")) +        return TRUE; + +#endif + +    return FALSE; +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 9c9cf78a..31a83bcc 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -267,4 +267,7 @@ FILE* pa_fopen_cloexec(const char *path, const char *mode);  void pa_nullify_stdfds(void); +char *pa_read_line_from_file(const char *fn); +pa_bool_t pa_running_in_vm(void); +  #endif diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index bb29a196..d49a78e5 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2631,7 +2631,7 @@ static void command_get_record_latency(pa_pdispatch *pd, uint32_t command, uint3      pa_tagstruct_put_usec(reply, s->current_monitor_latency);      pa_tagstruct_put_usec(reply,                            s->current_source_latency + -                          pa_bytes_to_usec(s->on_the_fly_snapshot, &s->source_output->sample_spec)); +                          pa_bytes_to_usec(s->on_the_fly_snapshot, &s->source_output->source->sample_spec));      pa_tagstruct_put_boolean(reply,                               pa_source_get_state(s->source_output->source) == PA_SOURCE_RUNNING &&                               pa_source_output_get_state(s->source_output) == PA_SOURCE_OUTPUT_RUNNING); diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 1af2823f..aa84ccb1 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -717,14 +717,15 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p                  pa_memchunk rchunk;                  pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk); -                if (nvfs) { -                    pa_memchunk_make_writable(&rchunk, 0); -                    pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink); -                } -  /*                 pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */                  if (rchunk.memblock) { + +                    if (nvfs) { +                        pa_memchunk_make_writable(&rchunk, 0); +                        pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink); +                    } +                      pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);                      pa_memblock_unref(rchunk.memblock);                  } | 
