diff options
Diffstat (limited to 'src/modules')
87 files changed, 861 insertions, 503 deletions
diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 7768b38e..7bf16c3c 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -148,7 +148,7 @@ static void reserve_update(struct userdata *u) { const char *description; pa_assert(u); - if (!u->sink) + if (!u->sink || !u->reserve) return; if ((description = pa_proplist_gets(u->sink->proplist, PA_PROP_DEVICE_DESCRIPTION))) @@ -164,6 +164,9 @@ static int reserve_init(struct userdata *u, const char *dname) { if (u->reserve) return 0; + if (pa_in_system_mode()) + return 0; + /* We are resuming, try to lock the device */ if (!(rname = pa_alsa_get_reserve_name(dname))) return 0; @@ -1187,17 +1190,11 @@ static int process_rewind(struct userdata *u) { /* Figure out how much we shall rewind and reset the counter */ rewind_nbytes = u->sink->thread_info.rewind_nbytes; - u->sink->thread_info.rewind_nbytes = 0; - if (rewind_nbytes <= 0) - goto finish; - - pa_assert(rewind_nbytes > 0); pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes); - snd_pcm_hwsync(u->pcm_handle); - if ((unused = snd_pcm_avail_update(u->pcm_handle)) < 0) { - pa_log("snd_pcm_avail_update() failed: %s", snd_strerror((int) unused)); + if (PA_UNLIKELY((unused = pa_alsa_safe_avail(u->pcm_handle, u->hwbuf_size, &u->sink->sample_spec)) < 0)) { + pa_log("snd_pcm_avail() failed: %s", snd_strerror((int) unused)); return -1; } @@ -1239,12 +1236,8 @@ static int process_rewind(struct userdata *u) { } else pa_log_debug("Mhmm, actually there is nothing to rewind."); -finish: - pa_sink_process_rewind(u->sink, 0); - return 0; - } static void thread_func(void *userdata) { @@ -1273,7 +1266,7 @@ static void thread_func(void *userdata) { int work_done; pa_usec_t sleep_usec = 0; - if (u->sink->thread_info.rewind_requested) + if (PA_UNLIKELY(u->sink->thread_info.rewind_requested)) if (process_rewind(u) < 0) goto fail; @@ -1699,11 +1692,10 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca u->watermark_step = pa_usec_to_bytes(TSCHED_WATERMARK_STEP_USEC, &u->sink->sample_spec); } - u->sink->thread_info.max_rewind = use_tsched ? u->hwbuf_size : 0; - u->sink->thread_info.max_request = u->hwbuf_size; - + pa_sink_set_max_rewind(u->sink, use_tsched ? u->hwbuf_size : 0); + pa_sink_set_max_request(u->sink, u->hwbuf_size); pa_sink_set_latency_range(u->sink, - !use_tsched ? pa_bytes_to_usec(u->hwbuf_size, &ss) : (pa_usec_t) -1, + use_tsched ? (pa_usec_t) -1 : pa_bytes_to_usec(u->hwbuf_size, &ss), pa_bytes_to_usec(u->hwbuf_size, &ss)); pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms", diff --git a/src/modules/alsa/alsa-sink.h b/src/modules/alsa/alsa-sink.h index 47ece9e0..bbf64234 100644 --- a/src/modules/alsa/alsa-sink.h +++ b/src/modules/alsa/alsa-sink.h @@ -9,7 +9,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index def638ec..f4acad8c 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -146,7 +146,7 @@ static void reserve_update(struct userdata *u) { const char *description; pa_assert(u); - if (!u->source) + if (!u->source || !u->reserve) return; if ((description = pa_proplist_gets(u->source->proplist, PA_PROP_DEVICE_DESCRIPTION))) @@ -162,6 +162,9 @@ static int reserve_init(struct userdata *u, const char *dname) { if (u->reserve) return 0; + if (pa_in_system_mode()) + return 0; + /* We are resuming, try to lock the device */ if (!(rname = pa_alsa_get_reserve_name(dname))) return 0; @@ -1542,7 +1545,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p } pa_source_set_latency_range(u->source, - !use_tsched ? pa_bytes_to_usec(u->hwbuf_size, &ss) : (pa_usec_t) -1, + use_tsched ? (pa_usec_t) -1 : pa_bytes_to_usec(u->hwbuf_size, &ss), pa_bytes_to_usec(u->hwbuf_size, &ss)); pa_log_info("Using %u fragments of size %lu bytes, buffer time is %0.2fms", diff --git a/src/modules/alsa/alsa-source.h b/src/modules/alsa/alsa-source.h index 5fed6cc8..9cbb0e17 100644 --- a/src/modules/alsa/alsa-source.h +++ b/src/modules/alsa/alsa-source.h @@ -9,7 +9,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index 7d833ff7..454cfd4e 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h index a8397ae9..fe0f71e0 100644 --- a/src/modules/alsa/alsa-util.h +++ b/src/modules/alsa/alsa-util.h @@ -9,7 +9,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c index 9e149a48..d5e2cdc2 100644 --- a/src/modules/alsa/module-alsa-card.c +++ b/src/modules/alsa/module-alsa-card.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -310,8 +310,9 @@ int pa__init(pa_module *m) { pa_snprintf(rname, sizeof(rname), "Audio%i", alsa_card_index); - if (!(reserve = pa_reserve_wrapper_get(m->core, rname))) - goto fail; + if (!pa_in_system_mode()) + if (!(reserve = pa_reserve_wrapper_get(m->core, rname))) + goto fail; pa_card_new_data_init(&data); data.driver = __FILE__; diff --git a/src/modules/alsa/module-alsa-sink.c b/src/modules/alsa/module-alsa-sink.c index 4f844e08..c728a446 100644 --- a/src/modules/alsa/module-alsa-sink.c +++ b/src/modules/alsa/module-alsa-sink.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/alsa/module-alsa-source.c b/src/modules/alsa/module-alsa-source.c index c35936df..6188019f 100644 --- a/src/modules/alsa/module-alsa-source.c +++ b/src/modules/alsa/module-alsa-source.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 6b522200..dfd3a306 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -5,7 +5,7 @@ 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 + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index 2c3ec649..0364c972 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -8,7 +8,7 @@ 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 + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/bluetooth/ipc.h b/src/modules/bluetooth/ipc.h index 4203150b..f030acfa 100644 --- a/src/modules/bluetooth/ipc.h +++ b/src/modules/bluetooth/ipc.h @@ -160,7 +160,8 @@ struct bt_get_capabilities_req { #define BT_HFP_CODEC_PCM 0x00 -#define BT_PCM_FLAG_NREC 1 +#define BT_PCM_FLAG_NREC 0x01 +#define BT_PCM_FLAG_PCM_ROUTING 0x02 typedef struct { uint8_t transport; diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 3332df2c..72cf2084 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -5,7 +5,7 @@ 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 + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/bluetooth/module-bluetooth-discover.c b/src/modules/bluetooth/module-bluetooth-discover.c index e9740749..521a9127 100644 --- a/src/modules/bluetooth/module-bluetooth-discover.c +++ b/src/modules/bluetooth/module-bluetooth-discover.c @@ -5,7 +5,7 @@ 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 + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/bluetooth/module-bluetooth-proximity.c b/src/modules/bluetooth/module-bluetooth-proximity.c index f30d39fe..a3b525ee 100644 --- a/src/modules/bluetooth/module-bluetooth-proximity.c +++ b/src/modules/bluetooth/module-bluetooth-proximity.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/dbus-util.c b/src/modules/dbus-util.c index 4218bca5..d51befb9 100644 --- a/src/modules/dbus-util.c +++ b/src/modules/dbus-util.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/dbus-util.h b/src/modules/dbus-util.h index fd974673..90abbc7b 100644 --- a/src/modules/dbus-util.h +++ b/src/modules/dbus-util.h @@ -8,7 +8,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/gconf/gconf-helper.c b/src/modules/gconf/gconf-helper.c index f5016faf..fbd8cfd8 100644 --- a/src/modules/gconf/gconf-helper.c +++ b/src/modules/gconf/gconf-helper.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/gconf/module-gconf.c b/src/modules/gconf/module-gconf.c index 845ede50..c01ebbf6 100644 --- a/src/modules/gconf/module-gconf.c +++ b/src/modules/gconf/module-gconf.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/hal-util.c b/src/modules/hal-util.c index 6959a706..422ae4ec 100644 --- a/src/modules/hal-util.c +++ b/src/modules/hal-util.c @@ -5,7 +5,7 @@ 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 + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/hal-util.h b/src/modules/hal-util.h index 3c0e0943..19e41d77 100644 --- a/src/modules/hal-util.h +++ b/src/modules/hal-util.h @@ -8,7 +8,7 @@ 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 + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-always-sink.c b/src/modules/module-always-sink.c index 591695fb..aee1c650 100644 --- a/src/modules/module-always-sink.c +++ b/src/modules/module-always-sink.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-augment-properties.c b/src/modules/module-augment-properties.c index 99111868..c3e5997a 100644 --- a/src/modules/module-augment-properties.c +++ b/src/modules/module-augment-properties.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c index c7696058..0afb9353 100644 --- a/src/modules/module-card-restore.c +++ b/src/modules/module-card-restore.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-cli.c b/src/modules/module-cli.c index 439aa8b0..fd9452b4 100644 --- a/src/modules/module-cli.c +++ b/src/modules/module-cli.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 6ed4f141..4b2d6f9b 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -487,7 +487,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { struct output *o; pa_sink_input_assert_ref(i); - pa_assert(o = i->userdata); + pa_assert_se(o = i->userdata); pa_module_unload_request(o->userdata->module, TRUE); output_free(o); diff --git a/src/modules/module-console-kit.c b/src/modules/module-console-kit.c index 805f5eef..3fba7ef6 100644 --- a/src/modules/module-console-kit.c +++ b/src/modules/module-console-kit.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-cork-music-on-phone.c b/src/modules/module-cork-music-on-phone.c index fb90cf34..c0f5eea4 100644 --- a/src/modules/module-cork-music-on-phone.c +++ b/src/modules/module-cork-music-on-phone.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-default-device-restore.c b/src/modules/module-default-device-restore.c index d299f40b..a25aafcb 100644 --- a/src/modules/module-default-device-restore.c +++ b/src/modules/module-default-device-restore.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-detect.c b/src/modules/module-detect.c index 773e1d87..49127abc 100644 --- a/src/modules/module-detect.c +++ b/src/modules/module-detect.c @@ -7,7 +7,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c index e6a48814..0ca3dd83 100644 --- a/src/modules/module-device-restore.c +++ b/src/modules/module-device-restore.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-esound-compat-spawnfd.c b/src/modules/module-esound-compat-spawnfd.c index 578ad3b5..56cda4df 100644 --- a/src/modules/module-esound-compat-spawnfd.c +++ b/src/modules/module-esound-compat-spawnfd.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-esound-compat-spawnpid.c b/src/modules/module-esound-compat-spawnpid.c index 882dba8c..5925f591 100644 --- a/src/modules/module-esound-compat-spawnpid.c +++ b/src/modules/module-esound-compat-spawnpid.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-esound-sink.c b/src/modules/module-esound-sink.c index 552cf75e..2b45e302 100644 --- a/src/modules/module-esound-sink.c +++ b/src/modules/module-esound-sink.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index ce04f367..fe601100 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c index 1739f46a..63fdd2db 100644 --- a/src/modules/module-jack-sink.c +++ b/src/modules/module-jack-sink.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-jack-source.c b/src/modules/module-jack-source.c index 38b63751..c77c9581 100644 --- a/src/modules/module-jack-source.c +++ b/src/modules/module-jack-source.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -163,7 +163,7 @@ static int jack_process(jack_nframes_t nframes, void *arg) { pa_assert(u); for (c = 0; c < u->channels; c++) - pa_assert(buffer[c] = jack_port_get_buffer(u->port[c], nframes)); + pa_assert_se(buffer[c] = jack_port_get_buffer(u->port[c], nframes)); /* We interleave the data and pass it on to the other RT thread */ diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index a4007b1a..33562b10 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c index 9a782cac..bdb8bb71 100644 --- a/src/modules/module-lirc.c +++ b/src/modules/module-lirc.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-match.c b/src/modules/module-match.c index 17936110..d7365ca7 100644 --- a/src/modules/module-match.c +++ b/src/modules/module-match.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c index a379923a..2f87dd22 100644 --- a/src/modules/module-mmkbd-evdev.c +++ b/src/modules/module-mmkbd-evdev.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-native-protocol-fd.c b/src/modules/module-native-protocol-fd.c index f17f435a..eed0505b 100644 --- a/src/modules/module-native-protocol-fd.c +++ b/src/modules/module-native-protocol-fd.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index e18da5fd..183d4b2e 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index f3b0e8b0..def4f758 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index a42c53c3..3d40fdf3 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-position-event-sounds.c b/src/modules/module-position-event-sounds.c index 6252ebab..e191ec33 100644 --- a/src/modules/module-position-event-sounds.c +++ b/src/modules/module-position-event-sounds.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-protocol-stub.c b/src/modules/module-protocol-stub.c index ca9274d8..ce3dcd03 100644 --- a/src/modules/module-protocol-stub.c +++ b/src/modules/module-protocol-stub.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-raop-discover.c b/src/modules/module-raop-discover.c index df393151..5c2e0623 100644 --- a/src/modules/module-raop-discover.c +++ b/src/modules/module-raop-discover.c @@ -6,7 +6,7 @@ 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 + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -152,11 +152,18 @@ static void resolver_cb( if (event != AVAHI_RESOLVER_FOUND) pa_log("Resolving of '%s' failed: %s", name, avahi_strerror(avahi_client_errno(u->client))); else { - char *device = NULL, *dname, *vname, *args; + char *device = NULL, *nicename, *dname, *vname, *args; char at[AVAHI_ADDRESS_STR_MAX]; AvahiStringList *l; pa_module *m; + if ((nicename = strstr(name, "@"))) { + ++nicename; + if (strlen(nicename) > 0) { + pa_log_debug("Found RAOP: %s", nicename); + } + } + for (l = txt; l; l = l->next) { char *key, *value; pa_assert_se(avahi_string_list_get_pair(l, &key, &value, NULL) == 0); @@ -190,10 +197,20 @@ static void resolver_cb( "sink_name=%s", avahi_address_snprint(at, sizeof(at), a), port, vname);*/ - args = pa_sprintf_malloc("server=%s " - "sink_name=%s", - avahi_address_snprint(at, sizeof(at), a), - vname); + if (nicename) { + args = pa_sprintf_malloc("server=%s " + "sink_name=%s " + "description=\"%s\"", + avahi_address_snprint(at, sizeof(at), a), + vname, + nicename); + + } else { + args = pa_sprintf_malloc("server=%s " + "sink_name=%s", + avahi_address_snprint(at, sizeof(at), a), + vname); + } pa_log_debug("Loading module-raop-sink with arguments '%s'", args); diff --git a/src/modules/module-raop-sink.c b/src/modules/module-raop-sink.c index da338f5d..00f0c63c 100644 --- a/src/modules/module-raop-sink.c +++ b/src/modules/module-raop-sink.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -72,6 +72,7 @@ PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_LOAD_ONCE(FALSE); PA_MODULE_USAGE( "sink_name=<name for the sink> " + "description=<description for the sink> " "server=<address> " "format=<sample format> " "channels=<number of channels> " @@ -122,6 +123,7 @@ static const char* const valid_modargs[] = { "format", "channels", "sink_name", + "description", NULL }; @@ -502,7 +504,7 @@ int pa__init(pa_module*m) { struct userdata *u = NULL; pa_sample_spec ss; pa_modargs *ma = NULL; - const char *server; + const char *server, *desc; pa_sink_new_data data; pa_assert(m); @@ -564,7 +566,10 @@ int pa__init(pa_module*m) { pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME)); pa_sink_new_data_set_sample_spec(&data, &ss); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, server); - pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "RAOP sink '%s'", server); + if ((desc = pa_modargs_get_value(ma, "description", NULL))) + pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, desc); + else + pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "RAOP sink '%s'", server); u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY|PA_SINK_NETWORK); pa_sink_new_data_done(&data); diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c index 89ddf953..31824bc5 100644 --- a/src/modules/module-remap-sink.c +++ b/src/modules/module-remap-sink.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c index e52e39c1..4f616e05 100644 --- a/src/modules/module-rescue-streams.c +++ b/src/modules/module-rescue-streams.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-sine-source.c b/src/modules/module-sine-source.c index 5626c2ab..206c45f4 100644 --- a/src/modules/module-sine-source.c +++ b/src/modules/module-sine-source.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index ce08c01d..0be1d722 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-solaris.c b/src/modules/module-solaris.c index 6f50543a..995b3c63 100644 --- a/src/modules/module-solaris.c +++ b/src/modules/module-solaris.c @@ -3,10 +3,11 @@ Copyright 2006 Lennart Poettering Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB + Copyright 2009 Finn Thain 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -44,6 +45,7 @@ #include <pulse/mainloop-signal.h> #include <pulse/xmalloc.h> #include <pulse/timeval.h> +#include <pulse/util.h> #include <pulsecore/iochannel.h> #include <pulsecore/sink.h> @@ -57,22 +59,25 @@ #include <pulsecore/thread-mq.h> #include <pulsecore/rtpoll.h> #include <pulsecore/thread.h> +#include <pulsecore/rtclock.h> #include "module-solaris-symdef.h" -PA_MODULE_AUTHOR("Pierre Ossman") -PA_MODULE_DESCRIPTION("Solaris Sink/Source") -PA_MODULE_VERSION(PACKAGE_VERSION) +PA_MODULE_AUTHOR("Pierre Ossman"); +PA_MODULE_DESCRIPTION("Solaris Sink/Source"); +PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_USAGE( "sink_name=<name for the sink> " "source_name=<name for the source> " - "device=<OSS device> record=<enable source?> " + "device=<audio device file name> " + "record=<enable source?> " "playback=<enable sink?> " "format=<sample format> " "channels=<number of channels> " "rate=<sample rate> " "buffer_size=<record buffer size> " - "channel_map=<channel map>") + "channel_map=<channel map>"); +PA_MODULE_LOAD_ONCE(FALSE); struct userdata { pa_core *core; @@ -87,15 +92,24 @@ struct userdata { pa_memchunk memchunk; - unsigned int page_size; - uint32_t frame_size; - uint32_t buffer_size; - unsigned int written_bytes, read_bytes; + int32_t buffer_size; + volatile uint64_t written_bytes, read_bytes; + pa_mutex *written_bytes_lock; + char *device_name; + int mode; int fd; pa_rtpoll_item *rtpoll_item; pa_module *module; + + pa_bool_t sink_suspended, source_suspended; + + uint32_t play_samples_msw, record_samples_msw; + uint32_t prev_playback_samples, prev_record_samples; + pa_mutex *sample_counter_lock; + + size_t min_request; }; static const char* const valid_modargs[] = { @@ -112,89 +126,303 @@ static const char* const valid_modargs[] = { NULL }; -#define DEFAULT_SINK_NAME "solaris_output" -#define DEFAULT_SOURCE_NAME "solaris_input" #define DEFAULT_DEVICE "/dev/audio" +#define MIN_BUFFER_SIZE (640) +#define MAX_RENDER_HZ (300) -static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { - struct userdata *u = PA_SINK(o)->userdata; +/* This render rate limit implies a minimum latency, but without it we waste too much CPU time in the + * IO thread. The maximum render rate and minimum latency (or minimum buffer size) are unachievable on + * common hardware anyway. Note that MIN_BUFFER_SIZE * MAX_RENDER_HZ >= 4 * 48000 Bps. + */ + +static uint64_t get_playback_buffered_bytes(struct userdata *u) { + audio_info_t info; + uint64_t played_bytes; int err; + + pa_assert(u->sink); + + pa_mutex_lock(u->sample_counter_lock); + + err = ioctl(u->fd, AUDIO_GETINFO, &info); + pa_assert(err >= 0); + + /* Handle wrap-around of the device's sample counter, which is a uint_32. */ + if (u->prev_playback_samples > info.play.samples) { + /* Unfortunately info.play.samples can sometimes go backwards, even before it wraps! */ + if (u->prev_playback_samples + info.play.samples < 240000) { + ++u->play_samples_msw; + } else { + pa_log_debug("play.samples went backwards %d bytes", u->prev_playback_samples - info.play.samples); + } + } + u->prev_playback_samples = info.play.samples; + played_bytes = (((uint64_t)u->play_samples_msw << 32) + info.play.samples) * u->frame_size; + + pa_mutex_unlock(u->sample_counter_lock); + + return u->written_bytes - played_bytes; +} + +static pa_usec_t sink_get_latency(struct userdata *u, pa_sample_spec *ss) { + pa_usec_t r = 0; + + pa_assert(u); + pa_assert(ss); + + if (u->fd >= 0) { + pa_mutex_lock(u->written_bytes_lock); + r = pa_bytes_to_usec(get_playback_buffered_bytes(u), ss); + if (u->memchunk.memblock) + r += pa_bytes_to_usec(u->memchunk.length, ss); + pa_mutex_unlock(u->written_bytes_lock); + } + return r; +} + +static uint64_t get_recorded_bytes(struct userdata *u) { audio_info_t info; + uint64_t result; + int err; - switch (code) { - case PA_SINK_MESSAGE_GET_LATENCY: { - pa_usec_t r = 0; + pa_assert(u->source); - if (u->fd >= 0) { + err = ioctl(u->fd, AUDIO_GETINFO, &info); + pa_assert(err >= 0); - err = ioctl(u->fd, AUDIO_GETINFO, &info); - pa_assert(err >= 0); + if (u->prev_record_samples > info.record.samples) + ++u->record_samples_msw; + u->prev_record_samples = info.record.samples; + result = (((uint64_t)u->record_samples_msw << 32) + info.record.samples) * u->frame_size; - r += pa_bytes_to_usec(u->written_bytes, &PA_SINK(o)->sample_spec); - r -= pa_bytes_to_usec(info.play.samples * u->frame_size, &PA_SINK(o)->sample_spec); + return result; +} - if (u->memchunk.memblock) - r += pa_bytes_to_usec(u->memchunk.length, &PA_SINK(o)->sample_spec); - } +static pa_usec_t source_get_latency(struct userdata *u, pa_sample_spec *ss) { + pa_usec_t r = 0; + audio_info_t info; + + pa_assert(u); + pa_assert(ss); - *((pa_usec_t*) data) = r; + if (u->fd) { + int err = ioctl(u->fd, AUDIO_GETINFO, &info); + pa_assert(err >= 0); - return 0; + r = pa_bytes_to_usec(get_recorded_bytes(u), ss) - pa_bytes_to_usec(u->read_bytes, ss); } + return r; +} - case PA_SINK_MESSAGE_SET_VOLUME: - if (u->fd >= 0) { - AUDIO_INITINFO(&info); +static void build_pollfd(struct userdata *u) { + struct pollfd *pollfd; - info.play.gain = pa_cvolume_avg((pa_cvolume*)data) * AUDIO_MAX_GAIN / PA_VOLUME_NORM; - assert(info.play.gain <= AUDIO_MAX_GAIN); + pa_assert(u); + pa_assert(!u->rtpoll_item); + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); - if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { - if (errno == EINVAL) - pa_log("AUDIO_SETINFO: Unsupported volume."); - else - pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); - } else { - return 0; - } - } - break; + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + pollfd->fd = u->fd; + pollfd->events = 0; + pollfd->revents = 0; +} - case PA_SINK_MESSAGE_GET_VOLUME: - if (u->fd >= 0) { - err = ioctl(u->fd, AUDIO_GETINFO, &info); - assert(err >= 0); +static int set_buffer(int fd, int buffer_size) { + audio_info_t info; - pa_cvolume_set((pa_cvolume*) data, ((pa_cvolume*) data)->channels, - info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN); + pa_assert(fd >= 0); - return 0; - } - break; + AUDIO_INITINFO(&info); + info.play.buffer_size = buffer_size; + info.record.buffer_size = buffer_size; - case PA_SINK_MESSAGE_SET_MUTE: - if (u->fd >= 0) { - AUDIO_INITINFO(&info); + if (ioctl(fd, AUDIO_SETINFO, &info) < 0) { + if (errno == EINVAL) + pa_log("AUDIO_SETINFO: Unsupported buffer size."); + else + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + return -1; + } - info.output_muted = !!PA_PTR_TO_UINT(data); + return 0; +} - if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) - pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); - else - return 0; +static int auto_format(int fd, int mode, pa_sample_spec *ss) { + audio_info_t info; + + pa_assert(fd >= 0); + pa_assert(ss); + + AUDIO_INITINFO(&info); + + if (mode != O_RDONLY) { + info.play.sample_rate = ss->rate; + info.play.channels = ss->channels; + switch (ss->format) { + case PA_SAMPLE_U8: + info.play.precision = 8; + info.play.encoding = AUDIO_ENCODING_LINEAR; + break; + case PA_SAMPLE_ALAW: + info.play.precision = 8; + info.play.encoding = AUDIO_ENCODING_ALAW; + break; + case PA_SAMPLE_ULAW: + info.play.precision = 8; + info.play.encoding = AUDIO_ENCODING_ULAW; + break; + case PA_SAMPLE_S16NE: + info.play.precision = 16; + info.play.encoding = AUDIO_ENCODING_LINEAR; + break; + default: + pa_log("AUDIO_SETINFO: Unsupported sample format."); + return -1; } - break; + } - case PA_SINK_MESSAGE_GET_MUTE: - if (u->fd >= 0) { - err = ioctl(u->fd, AUDIO_GETINFO, &info); - pa_assert(err >= 0); + if (mode != O_WRONLY) { + info.record.sample_rate = ss->rate; + info.record.channels = ss->channels; + switch (ss->format) { + case PA_SAMPLE_U8: + info.record.precision = 8; + info.record.encoding = AUDIO_ENCODING_LINEAR; + break; + case PA_SAMPLE_ALAW: + info.record.precision = 8; + info.record.encoding = AUDIO_ENCODING_ALAW; + break; + case PA_SAMPLE_ULAW: + info.record.precision = 8; + info.record.encoding = AUDIO_ENCODING_ULAW; + break; + case PA_SAMPLE_S16NE: + info.record.precision = 16; + info.record.encoding = AUDIO_ENCODING_LINEAR; + break; + default: + pa_log("AUDIO_SETINFO: Unsupported sample format."); + return -1; + } + } + + if (ioctl(fd, AUDIO_SETINFO, &info) < 0) { + if (errno == EINVAL) + pa_log("AUDIO_SETINFO: Failed to set sample format."); + else + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + return -1; + } + + return 0; +} + +static int open_audio_device(struct userdata *u, pa_sample_spec *ss) { + pa_assert(u); + pa_assert(ss); + + if ((u->fd = open(u->device_name, u->mode | O_NONBLOCK)) < 0) { + pa_log_warn("open %s failed (%s)", u->device_name, pa_cstrerror(errno)); + return -1; + } + + pa_log_info("device opened in %s mode.", u->mode == O_WRONLY ? "O_WRONLY" : (u->mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); + + if (auto_format(u->fd, u->mode, ss) < 0) + return -1; + + if (set_buffer(u->fd, u->buffer_size) < 0) + return -1; + + u->written_bytes = u->read_bytes = 0; + u->play_samples_msw = u->record_samples_msw = 0; + u->prev_playback_samples = u->prev_record_samples = 0; + + return u->fd; +} + +static int suspend(struct userdata *u) { + pa_assert(u); + pa_assert(u->fd >= 0); + + pa_log_info("Suspending..."); + + ioctl(u->fd, AUDIO_DRAIN, NULL); + pa_close(u->fd); + u->fd = -1; + + if (u->rtpoll_item) { + pa_rtpoll_item_free(u->rtpoll_item); + u->rtpoll_item = NULL; + } + + pa_log_info("Device suspended."); + + return 0; +} + +static int unsuspend(struct userdata *u) { + pa_assert(u); + pa_assert(u->fd < 0); - *(int*)data = !!info.output_muted; + pa_log_info("Resuming..."); + if (open_audio_device(u, u->sink ? &u->sink->sample_spec : &u->source->sample_spec) < 0) + return -1; + + build_pollfd(u); + + pa_log_info("Device resumed."); + + return 0; +} + +static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u = PA_SINK(o)->userdata; + + switch (code) { + + case PA_SINK_MESSAGE_GET_LATENCY: + *((pa_usec_t*) data) = sink_get_latency(u, &PA_SINK(o)->sample_spec); return 0; - } - break; + + case PA_SINK_MESSAGE_SET_STATE: + + switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) { + + case PA_SINK_SUSPENDED: + + pa_assert(PA_SINK_IS_OPENED(u->sink->thread_info.state)); + + if (!u->source || u->source_suspended) { + if (suspend(u) < 0) + return -1; + } + u->sink_suspended = TRUE; + break; + + case PA_SINK_IDLE: + case PA_SINK_RUNNING: + + if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { + if (!u->source || u->source_suspended) { + if (unsuspend(u) < 0) + return -1; + u->sink->get_volume(u->sink); + u->sink->get_mute(u->sink); + } + u->sink_suspended = FALSE; + } + break; + + case PA_SINK_INVALID_STATE: + case PA_SINK_UNLINKED: + case PA_SINK_INIT: + ; + } + + break; } return pa_sink_process_msg(o, code, data, offset, chunk); @@ -202,95 +430,168 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SOURCE(o)->userdata; - int err; - audio_info_t info; switch (code) { - case PA_SOURCE_MESSAGE_GET_LATENCY: { - pa_usec_t r = 0; - if (u->fd) { - err = ioctl(u->fd, AUDIO_GETINFO, &info); - pa_assert(err >= 0); + case PA_SOURCE_MESSAGE_GET_LATENCY: + *((pa_usec_t*) data) = source_get_latency(u, &PA_SOURCE(o)->sample_spec); + return 0; - r += pa_bytes_to_usec(info.record.samples * u->frame_size, &PA_SOURCE(o)->sample_spec); - r -= pa_bytes_to_usec(u->read_bytes, &PA_SOURCE(o)->sample_spec); - } + case PA_SOURCE_MESSAGE_SET_STATE: - *((pa_usec_t*) data) = r; + switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) { - return 0; - } + case PA_SOURCE_SUSPENDED: - case PA_SOURCE_MESSAGE_SET_VOLUME: - if (u->fd >= 0) { - AUDIO_INITINFO(&info); + pa_assert(PA_SOURCE_IS_OPENED(u->source->thread_info.state)); - info.record.gain = pa_cvolume_avg((pa_cvolume*) data) * AUDIO_MAX_GAIN / PA_VOLUME_NORM; - assert(info.record.gain <= AUDIO_MAX_GAIN); + if (!u->sink || u->sink_suspended) { + if (suspend(u) < 0) + return -1; + } + u->source_suspended = TRUE; + break; + + case PA_SOURCE_IDLE: + case PA_SOURCE_RUNNING: + + if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) { + if (!u->sink || u->sink_suspended) { + if (unsuspend(u) < 0) + return -1; + u->source->get_volume(u->source); + } + u->source_suspended = FALSE; + } + break; + + case PA_SOURCE_UNLINKED: + case PA_SOURCE_INIT: + case PA_SOURCE_INVALID_STATE: + ; - if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { - if (errno == EINVAL) - pa_log("AUDIO_SETINFO: Unsupported volume."); - else - pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); - } else { - return 0; - } } break; - case PA_SOURCE_MESSAGE_GET_VOLUME: - if (u->fd >= 0) { - err = ioctl(u->fd, AUDIO_GETINFO, &info); - pa_assert(err >= 0); + } - pa_cvolume_set((pa_cvolume*) data, ((pa_cvolume*) data)->channels, - info.record.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN); + return pa_source_process_msg(o, code, data, offset, chunk); +} - return 0; - } - break; +static void sink_set_volume(pa_sink *s) { + struct userdata *u; + audio_info_t info; + + pa_assert_se(u = s->userdata); + + if (u->fd >= 0) { + AUDIO_INITINFO(&info); + + info.play.gain = pa_cvolume_avg(&s->virtual_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM; + assert(info.play.gain <= AUDIO_MAX_GAIN); + + if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { + if (errno == EINVAL) + pa_log("AUDIO_SETINFO: Unsupported volume."); + else + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + } } +} - return pa_source_process_msg(o, code, data, offset, chunk); +static void sink_get_volume(pa_sink *s) { + struct userdata *u; + audio_info_t info; + + pa_assert_se(u = s->userdata); + + if (u->fd >= 0) { + if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0) + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + else + pa_cvolume_set(&s->virtual_volume, s->sample_spec.channels, + info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN); + } } -static void clear_underflow(struct userdata *u) -{ +static void source_set_volume(pa_source *s) { + struct userdata *u; audio_info_t info; - AUDIO_INITINFO(&info); + pa_assert_se(u = s->userdata); + + if (u->fd >= 0) { + AUDIO_INITINFO(&info); - info.play.error = 0; + info.play.gain = pa_cvolume_avg(&s->virtual_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM; + assert(info.play.gain <= AUDIO_MAX_GAIN); - if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) - pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { + if (errno == EINVAL) + pa_log("AUDIO_SETINFO: Unsupported volume."); + else + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + } + } } -static void clear_overflow(struct userdata *u) -{ +static void source_get_volume(pa_source *s) { + struct userdata *u; audio_info_t info; - AUDIO_INITINFO(&info); + pa_assert_se(u = s->userdata); - info.record.error = 0; + if (u->fd >= 0) { + if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0) + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + else + pa_cvolume_set(&s->virtual_volume, s->sample_spec.channels, + info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN); + } +} + +static void sink_set_mute(pa_sink *s) { + struct userdata *u = s->userdata; + audio_info_t info; - if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) - pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + pa_assert(u); + + if (u->fd >= 0) { + AUDIO_INITINFO(&info); + + info.output_muted = !!s->muted; + + if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + } +} + +static void sink_get_mute(pa_sink *s) { + struct userdata *u = s->userdata; + audio_info_t info; + + pa_assert(u); + + if (u->fd >= 0) { + if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0) + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + else + s->muted = !!info.output_muted; + } } static void thread_func(void *userdata) { struct userdata *u = userdata; unsigned short revents = 0; - int ret; + int ret, err; + audio_info_t info; pa_assert(u); pa_log_debug("Thread starting up"); - if (u->core->high_priority) - pa_make_realtime(); + if (u->core->realtime_scheduling) + pa_make_realtime(u->core->realtime_priority); pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); @@ -298,139 +599,158 @@ static void thread_func(void *userdata) { for (;;) { /* Render some data and write it to the dsp */ - if (u->sink && PA_SINK_OPENED(u->sink->thread_info.state)) { - audio_info_t info; - int err; - size_t len; + if (u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) { + pa_usec_t xtime0; + uint64_t buffered_bytes; + + if (u->sink->thread_info.rewind_requested) + pa_sink_process_rewind(u->sink, 0); err = ioctl(u->fd, AUDIO_GETINFO, &info); pa_assert(err >= 0); - /* - * Since we cannot modify the size of the output buffer we fake it - * by not filling it more than u->buffer_size. - */ - len = u->buffer_size; - len -= u->written_bytes - (info.play.samples * u->frame_size); - - /* The sample counter can sometimes go backwards :( */ - if (len > u->buffer_size) - len = 0; - if (info.play.error) { - pa_log_debug("Solaris buffer underflow!"); - clear_underflow(u); - } + pa_log_debug("buffer under-run!"); - len -= len % u->frame_size; + AUDIO_INITINFO(&info); + info.play.error = 0; + if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + } - while (len) { + for (;;) { void *p; - ssize_t r; + ssize_t w; + size_t len; + + /* + * Since we cannot modify the size of the output buffer we fake it + * by not filling it more than u->buffer_size. + */ + xtime0 = pa_rtclock_usec(); + buffered_bytes = get_playback_buffered_bytes(u); + if (buffered_bytes >= (uint64_t)u->buffer_size) + break; - if (!u->memchunk.length) - pa_sink_render(u->sink, len, &u->memchunk); + len = u->buffer_size - buffered_bytes; + len -= len % u->frame_size; - pa_assert(u->memchunk.length); + if (len < u->min_request) + break; + + if (u->memchunk.length < len) + pa_sink_render(u->sink, u->sink->thread_info.max_request, &u->memchunk); p = pa_memblock_acquire(u->memchunk.memblock); - r = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, NULL); + w = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, NULL); pa_memblock_release(u->memchunk.memblock); - if (r < 0) { - if (errno == EINTR) - continue; - else if (errno != EAGAIN) { - pa_log("Failed to read data from DSP: %s", pa_cstrerror(errno)); - goto fail; + if (w <= 0) { + switch (errno) { + case EINTR: + break; + case EAGAIN: + u->buffer_size = u->buffer_size * 18 / 25; + u->buffer_size -= u->buffer_size % u->frame_size; + u->buffer_size = PA_MAX(u->buffer_size, (int32_t)MIN_BUFFER_SIZE); + pa_sink_set_max_request(u->sink, u->buffer_size); + pa_log("EAGAIN. Buffer size is now %u bytes (%llu buffered)", u->buffer_size, buffered_bytes); + break; + default: + pa_log("Failed to write data to DSP: %s", pa_cstrerror(errno)); + goto fail; } } else { - pa_assert(r % u->frame_size == 0); + pa_assert(w % u->frame_size == 0); - u->memchunk.index += r; - u->memchunk.length -= r; + pa_mutex_lock(u->written_bytes_lock); + u->written_bytes += w; + u->memchunk.length -= w; + pa_mutex_unlock(u->written_bytes_lock); + u->memchunk.index += w; if (u->memchunk.length <= 0) { pa_memblock_unref(u->memchunk.memblock); pa_memchunk_reset(&u->memchunk); } - - len -= r; - u->written_bytes += r; } } + + pa_rtpoll_set_timer_absolute(u->rtpoll, xtime0 + pa_bytes_to_usec(buffered_bytes / 2, &u->sink->sample_spec)); + } else { + pa_rtpoll_set_timer_disabled(u->rtpoll); } /* Try to read some data and pass it on to the source driver */ - if (u->source && PA_SOURCE_OPENED(u->source->thread_info.state) && ((revents & POLLIN))) { + if (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state) && (revents & POLLIN)) { pa_memchunk memchunk; - int err; - size_t l; void *p; ssize_t r; - audio_info_t info; + size_t len; err = ioctl(u->fd, AUDIO_GETINFO, &info); pa_assert(err >= 0); if (info.record.error) { - pa_log_debug("Solaris buffer overflow!"); - clear_overflow(u); + pa_log_debug("buffer overflow!"); + + AUDIO_INITINFO(&info); + info.record.error = 0; + if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); } - err = ioctl(u->fd, I_NREAD, &l); + err = ioctl(u->fd, I_NREAD, &len); pa_assert(err >= 0); - if (l > 0) { - /* This is to make sure it fits in the memory pool. Also, a page - should be the most efficient transfer size. */ - if (l > u->page_size) - l = u->page_size; - - memchunk.memblock = pa_memblock_new(u->core->mempool, l); + if (len > 0) { + memchunk.memblock = pa_memblock_new(u->core->mempool, len); pa_assert(memchunk.memblock); p = pa_memblock_acquire(memchunk.memblock); - r = pa_read(u->fd, p, l, NULL); + r = pa_read(u->fd, p, len, NULL); pa_memblock_release(memchunk.memblock); if (r < 0) { pa_memblock_unref(memchunk.memblock); - if (errno != EAGAIN) { + if (errno == EAGAIN) + break; + else { pa_log("Failed to read data from DSP: %s", pa_cstrerror(errno)); goto fail; } } else { + u->read_bytes += r; + memchunk.index = 0; memchunk.length = r; pa_source_post(u->source, &memchunk); pa_memblock_unref(memchunk.memblock); - u->read_bytes += r; - revents &= ~POLLIN; } } } - if (u->fd >= 0) { + if (u->rtpoll_item) { struct pollfd *pollfd; + pa_assert(u->fd >= 0); + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); - pollfd->events = - ((u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) ? POLLIN : 0); + pollfd->events = (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) ? POLLIN : 0; } /* Hmm, nothing to do. Let's sleep */ - if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) + if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) goto fail; if (ret == 0) goto finish; - if (u->fd >= 0) { + if (u->rtpoll_item) { struct pollfd *pollfd; pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); @@ -460,112 +780,29 @@ static void sig_callback(pa_mainloop_api *api, pa_signal_event*e, int sig, void assert(u); + pa_log_debug("caught signal"); + if (u->sink) { - pa_sink_get_volume(u->sink); - pa_sink_get_mute(u->sink); + pa_sink_get_volume(u->sink, TRUE); + pa_sink_get_mute(u->sink, TRUE); } if (u->source) - pa_source_get_volume(u->source); -} - -static int pa_solaris_auto_format(int fd, int mode, pa_sample_spec *ss) { - audio_info_t info; - - AUDIO_INITINFO(&info); - - if (mode != O_RDONLY) { - info.play.sample_rate = ss->rate; - info.play.channels = ss->channels; - switch (ss->format) { - case PA_SAMPLE_U8: - info.play.precision = 8; - info.play.encoding = AUDIO_ENCODING_LINEAR; - break; - case PA_SAMPLE_ALAW: - info.play.precision = 8; - info.play.encoding = AUDIO_ENCODING_ALAW; - break; - case PA_SAMPLE_ULAW: - info.play.precision = 8; - info.play.encoding = AUDIO_ENCODING_ULAW; - break; - case PA_SAMPLE_S16NE: - info.play.precision = 16; - info.play.encoding = AUDIO_ENCODING_LINEAR; - break; - default: - return -1; - } - } - - if (mode != O_WRONLY) { - info.record.sample_rate = ss->rate; - info.record.channels = ss->channels; - switch (ss->format) { - case PA_SAMPLE_U8: - info.record.precision = 8; - info.record.encoding = AUDIO_ENCODING_LINEAR; - break; - case PA_SAMPLE_ALAW: - info.record.precision = 8; - info.record.encoding = AUDIO_ENCODING_ALAW; - break; - case PA_SAMPLE_ULAW: - info.record.precision = 8; - info.record.encoding = AUDIO_ENCODING_ULAW; - break; - case PA_SAMPLE_S16NE: - info.record.precision = 16; - info.record.encoding = AUDIO_ENCODING_LINEAR; - break; - default: - return -1; - } - } - - if (ioctl(fd, AUDIO_SETINFO, &info) < 0) { - if (errno == EINVAL) - pa_log("AUDIO_SETINFO: Unsupported sample format."); - else - pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); - return -1; - } - - return 0; -} - -static int pa_solaris_set_buffer(int fd, int buffer_size) { - audio_info_t info; - - AUDIO_INITINFO(&info); - - info.play.buffer_size = buffer_size; - info.record.buffer_size = buffer_size; - - if (ioctl(fd, AUDIO_SETINFO, &info) < 0) { - if (errno == EINVAL) - pa_log("AUDIO_SETINFO: Unsupported buffer size."); - else - pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); - return -1; - } - - return 0; + pa_source_get_volume(u->source, TRUE); } int pa__init(pa_module *m) { struct userdata *u = NULL; - const char *p; - int fd = -1; - int buffer_size; - int mode; - int record = 1, playback = 1; + pa_bool_t record = TRUE, playback = TRUE; pa_sample_spec ss; pa_channel_map map; pa_modargs *ma = NULL; - char *t; - struct pollfd *pollfd; + int fd; + pa_sink_new_data sink_new_data; + pa_source_new_data source_new_data; + char const *name; + char *name_buf; + pa_bool_t namereg_fail; pa_assert(m); @@ -575,7 +812,7 @@ int pa__init(pa_module *m) { } if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) { - pa_log("record= and playback= expect numeric argument."); + pa_log("record= and playback= expect a boolean argument."); goto fail; } @@ -584,97 +821,133 @@ int pa__init(pa_module *m) { goto fail; } - mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); + u = pa_xnew0(struct userdata, 1); + u->sample_counter_lock = pa_mutex_new(FALSE, FALSE); + u->written_bytes_lock = pa_mutex_new(FALSE, FALSE); - buffer_size = 16384; - if (pa_modargs_get_value_s32(ma, "buffer_size", &buffer_size) < 0) { - pa_log("failed to parse buffer size argument"); - goto fail; - } + /* + * For a process (or several processes) to use the same audio device for both + * record and playback at the same time, the device's mixer must be enabled. + * See mixerctl(1). It may be turned off for playback only or record only. + */ + u->mode = (playback && record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); ss = m->core->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { pa_log("failed to parse sample specification"); goto fail; } + u->frame_size = pa_frame_size(&ss); - if ((fd = open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), mode | O_NONBLOCK)) < 0) + u->buffer_size = 16384; + if (pa_modargs_get_value_s32(ma, "buffer_size", &u->buffer_size) < 0) { + pa_log("failed to parse buffer size argument"); goto fail; - - pa_log_info("device opened in %s mode.", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); - - if (pa_solaris_auto_format(fd, mode, &ss) < 0) + } + u->buffer_size -= u->buffer_size % u->frame_size; + if (u->buffer_size < (int32_t)MIN_BUFFER_SIZE) { + pa_log("supplied buffer size argument is too small"); goto fail; + } + + u->device_name = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE)); - if (pa_solaris_set_buffer(fd, buffer_size) < 0) + if ((fd = open_audio_device(u, &ss)) < 0) goto fail; - u = pa_xmalloc(sizeof(struct userdata)); u->core = m->core; - - u->fd = fd; - - pa_memchunk_reset(&u->memchunk); - - /* We use this to get a reasonable chunk size */ - u->page_size = PA_PAGE_SIZE; - - u->frame_size = pa_frame_size(&ss); - u->buffer_size = buffer_size; - - u->written_bytes = 0; - u->read_bytes = 0; - u->module = m; m->userdata = u; - pa_thread_mq_init(&u->thread_mq, m->core->mainloop); + pa_memchunk_reset(&u->memchunk); u->rtpoll = pa_rtpoll_new(); - pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); + pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); - pa_rtpoll_set_timer_periodic(u->rtpoll, pa_bytes_to_usec(u->buffer_size / 10, &ss)); + u->rtpoll_item = NULL; + build_pollfd(u); - u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); - pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); - pollfd->fd = fd; - pollfd->events = 0; - pollfd->revents = 0; + if (u->mode != O_WRONLY) { + name_buf = NULL; + namereg_fail = TRUE; - if (mode != O_WRONLY) { - u->source = pa_source_new(m->core, __FILE__, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss, &map); - pa_assert(u->source); + if (!(name = pa_modargs_get_value(ma, "source_name", NULL))) { + name = name_buf = pa_sprintf_malloc("solaris_input.%s", pa_path_get_filename(u->device_name)); + namereg_fail = FALSE; + } + + pa_source_new_data_init(&source_new_data); + source_new_data.driver = __FILE__; + source_new_data.module = m; + pa_source_new_data_set_name(&source_new_data, name); + source_new_data.namereg_fail = namereg_fail; + pa_source_new_data_set_sample_spec(&source_new_data, &ss); + pa_source_new_data_set_channel_map(&source_new_data, &map); + pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_STRING, u->device_name); + pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_API, "solaris"); + pa_proplist_setf(source_new_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Solaris PCM source"); + pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_ACCESS_MODE, "serial"); + pa_proplist_setf(source_new_data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) u->buffer_size); + + u->source = pa_source_new(m->core, &source_new_data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL); + pa_source_new_data_done(&source_new_data); + pa_xfree(name_buf); + + if (!u->source) { + pa_log("Failed to create source object"); + goto fail; + } u->source->userdata = u; u->source->parent.process_msg = source_process_msg; - pa_source_set_module(u->source, m); - pa_source_set_description(u->source, t = pa_sprintf_malloc("Solaris PCM on '%s'", p)); - pa_xfree(t); pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); pa_source_set_rtpoll(u->source, u->rtpoll); - u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL; - u->source->refresh_volume = 1; + u->source->get_volume = source_get_volume; + u->source->set_volume = source_set_volume; + u->source->refresh_volume = TRUE; } else u->source = NULL; - if (mode != O_RDONLY) { - u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map); - pa_assert(u->sink); + if (u->mode != O_RDONLY) { + name_buf = NULL; + namereg_fail = TRUE; + if (!(name = pa_modargs_get_value(ma, "sink_name", NULL))) { + name = name_buf = pa_sprintf_malloc("solaris_output.%s", pa_path_get_filename(u->device_name)); + namereg_fail = FALSE; + } + + pa_sink_new_data_init(&sink_new_data); + sink_new_data.driver = __FILE__; + sink_new_data.module = m; + pa_sink_new_data_set_name(&sink_new_data, name); + sink_new_data.namereg_fail = namereg_fail; + pa_sink_new_data_set_sample_spec(&sink_new_data, &ss); + pa_sink_new_data_set_channel_map(&sink_new_data, &map); + pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_STRING, u->device_name); + pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_API, "solaris"); + pa_proplist_setf(sink_new_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Solaris PCM sink"); + pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_ACCESS_MODE, "serial"); + + u->sink = pa_sink_new(m->core, &sink_new_data, PA_SINK_HARDWARE|PA_SINK_LATENCY|PA_SINK_HW_VOLUME_CTRL|PA_SINK_HW_MUTE_CTRL); + pa_sink_new_data_done(&sink_new_data); + pa_assert(u->sink); u->sink->userdata = u; u->sink->parent.process_msg = sink_process_msg; - pa_sink_set_module(u->sink, m); - pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Solaris PCM on '%s'", p)); - pa_xfree(t); pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_rtpoll(u->sink, u->rtpoll); - u->sink->flags = PA_SINK_HARDWARE|PA_SINK_LATENCY|PA_SINK_HW_VOLUME_CTRL; - u->sink->refresh_volume = 1; - u->sink->refresh_mute = 1; + u->sink->get_volume = sink_get_volume; + u->sink->set_volume = sink_set_volume; + u->sink->get_mute = sink_get_mute; + u->sink->set_mute = sink_set_mute; + u->sink->refresh_volume = u->sink->refresh_muted = TRUE; + + u->sink->thread_info.max_request = u->buffer_size; + u->min_request = pa_usec_to_bytes(PA_USEC_PER_SEC / MAX_RENDER_HZ, &ss); } else u->sink = NULL; @@ -690,17 +963,28 @@ int pa__init(pa_module *m) { } /* Read mixer settings */ - if (u->source) - pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, 0, NULL); if (u->sink) { - pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL); - pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_MUTE, &u->sink->muted, 0, NULL); - } + if (sink_new_data.volume_is_set) + u->sink->set_volume(u->sink); + else + u->sink->get_volume(u->sink); + + if (sink_new_data.muted_is_set) + u->sink->set_mute(u->sink); + else + u->sink->get_mute(u->sink); - if (u->sink) pa_sink_put(u->sink); - if (u->source) + } + + if (u->source) { + if (source_new_data.volume_is_set) + u->source->set_volume(u->source); + else + u->source->get_volume(u->source); + pa_source_put(u->source); + } pa_modargs_free(ma); @@ -748,7 +1032,7 @@ void pa__done(pa_module *m) { if (u->source) pa_source_unref(u->source); - if (u->memchunk.memblock) + if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); if (u->rtpoll_item) @@ -760,5 +1044,10 @@ void pa__done(pa_module *m) { if (u->fd >= 0) close(u->fd); + pa_mutex_free(u->written_bytes_lock); + pa_mutex_free(u->sample_counter_lock); + + pa_xfree(u->device_name); + pa_xfree(u); } diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index d935caf6..723b5d73 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c index a5a3571c..7e17f8f7 100644 --- a/src/modules/module-suspend-on-idle.c +++ b/src/modules/module-suspend-on-idle.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -149,7 +149,12 @@ static pa_hook_result_t source_output_fixate_hook_cb(pa_core *c, pa_source_outpu pa_assert(data); pa_assert(u); - if ((d = pa_hashmap_get(u->device_infos, data->source))) + if (data->source->monitor_of) + d = pa_hashmap_get(u->device_infos, data->source->monitor_of); + else + d = pa_hashmap_get(u->device_infos, data->source); + + if (d) resume(d); return PA_HOOK_OK; @@ -173,6 +178,8 @@ static pa_hook_result_t sink_input_unlink_hook_cb(pa_core *c, pa_sink_input *s, } static pa_hook_result_t source_output_unlink_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { + struct device_info *d = NULL; + pa_assert(c); pa_source_output_assert_ref(s); pa_assert(u); @@ -180,12 +187,17 @@ static pa_hook_result_t source_output_unlink_hook_cb(pa_core *c, pa_source_outpu if (!s->source) return PA_HOOK_OK; - if (pa_source_check_suspend(s->source) <= 0) { - struct device_info *d; - if ((d = pa_hashmap_get(u->device_infos, s->source))) - restart(d); + if (s->source->monitor_of) { + if (pa_sink_check_suspend(s->source->monitor_of) <= 0) + d = pa_hashmap_get(u->device_infos, s->source->monitor_of); + } else { + if (pa_source_check_suspend(s->source) <= 0) + d = pa_hashmap_get(u->device_infos, s->source); } + if (d) + restart(d); + return PA_HOOK_OK; } @@ -217,15 +229,22 @@ static pa_hook_result_t sink_input_move_finish_hook_cb(pa_core *c, pa_sink_input } static pa_hook_result_t source_output_move_start_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { - struct device_info *d; + struct device_info *d = NULL; pa_assert(c); pa_source_output_assert_ref(s); pa_assert(u); - if (pa_source_check_suspend(s->source) <= 1) - if ((d = pa_hashmap_get(u->device_infos, s->source))) - restart(d); + if (s->source->monitor_of) { + if (pa_sink_check_suspend(s->source->monitor_of) <= 1) + d = pa_hashmap_get(u->device_infos, s->source->monitor_of); + } else { + if (pa_source_check_suspend(s->source) <= 1) + d = pa_hashmap_get(u->device_infos, s->source); + } + + if (d) + restart(d); return PA_HOOK_OK; } @@ -237,7 +256,12 @@ static pa_hook_result_t source_output_move_finish_hook_cb(pa_core *c, pa_source_ pa_source_output_assert_ref(s); pa_assert(u); - if ((d = pa_hashmap_get(u->device_infos, s->source))) + if (s->source->monitor_of) + d = pa_hashmap_get(u->device_infos, s->source->monitor_of); + else + d = pa_hashmap_get(u->device_infos, s->source); + + if (d) resume(d); return PA_HOOK_OK; @@ -259,16 +283,25 @@ static pa_hook_result_t sink_input_state_changed_hook_cb(pa_core *c, pa_sink_inp } static pa_hook_result_t source_output_state_changed_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { - struct device_info *d; pa_source_output_state_t state; + pa_assert(c); pa_source_output_assert_ref(s); pa_assert(u); state = pa_source_output_get_state(s); - if (state == PA_SOURCE_OUTPUT_RUNNING) - if ((d = pa_hashmap_get(u->device_infos, s->source))) + + if (state == PA_SOURCE_OUTPUT_RUNNING) { + struct device_info *d; + + if (s->source->monitor_of) + d = pa_hashmap_get(u->device_infos, s->source->monitor_of); + else + d = pa_hashmap_get(u->device_infos, s->source); + + if (d) resume(d); + } return PA_HOOK_OK; } @@ -285,6 +318,10 @@ static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct user source = pa_source_isinstance(o) ? PA_SOURCE(o) : NULL; sink = pa_sink_isinstance(o) ? PA_SINK(o) : NULL; + /* Never suspend monitors */ + if (source && source->monitor_of) + return PA_HOOK_OK; + pa_assert(source || sink); d = pa_xnew(struct device_info, 1); diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index 63ae740a..c1488841 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-volume-restore.c b/src/modules/module-volume-restore.c index 21c71491..61858afa 100644 --- a/src/modules/module-volume-restore.c +++ b/src/modules/module-volume-restore.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-waveout.c b/src/modules/module-waveout.c index b452c3bf..2d35828d 100644 --- a/src/modules/module-waveout.c +++ b/src/modules/module-waveout.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-x11-bell.c b/src/modules/module-x11-bell.c index bef02536..ac303c3b 100644 --- a/src/modules/module-x11-bell.c +++ b/src/modules/module-x11-bell.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-x11-cork-request.c b/src/modules/module-x11-cork-request.c index 0c9aedf4..c1380c27 100644 --- a/src/modules/module-x11-cork-request.c +++ b/src/modules/module-x11-cork-request.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-x11-publish.c b/src/modules/module-x11-publish.c index fb27eba2..7d71067b 100644 --- a/src/modules/module-x11-publish.c +++ b/src/modules/module-x11-publish.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-x11-xsmp.c b/src/modules/module-x11-xsmp.c index 5fc8047d..28fd373a 100644 --- a/src/modules/module-x11-xsmp.c +++ b/src/modules/module-x11-xsmp.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-zeroconf-discover.c b/src/modules/module-zeroconf-discover.c index 5123ead8..3da946e0 100644 --- a/src/modules/module-zeroconf-discover.c +++ b/src/modules/module-zeroconf-discover.c @@ -5,7 +5,7 @@ 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 + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c index 985564f4..692ffe91 100644 --- a/src/modules/module-zeroconf-publish.c +++ b/src/modules/module-zeroconf-publish.c @@ -5,7 +5,7 @@ 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 + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/oss/module-oss.c b/src/modules/oss/module-oss.c index 54d1679f..7bce8d00 100644 --- a/src/modules/oss/module-oss.c +++ b/src/modules/oss/module-oss.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/oss/oss-util.c b/src/modules/oss/oss-util.c index f04b875d..5a109ae9 100644 --- a/src/modules/oss/oss-util.c +++ b/src/modules/oss/oss-util.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/oss/oss-util.h b/src/modules/oss/oss-util.h index 654f7bba..845b0c8f 100644 --- a/src/modules/oss/oss-util.h +++ b/src/modules/oss/oss-util.h @@ -9,7 +9,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/raop/base64.c b/src/modules/raop/base64.c index 059c7028..e1cbed02 100644 --- a/src/modules/raop/base64.c +++ b/src/modules/raop/base64.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/raop/base64.h b/src/modules/raop/base64.h index dac0e707..7a973b68 100644 --- a/src/modules/raop/base64.h +++ b/src/modules/raop/base64.h @@ -9,7 +9,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c index 4627545e..b3f243c3 100644 --- a/src/modules/raop/raop_client.c +++ b/src/modules/raop/raop_client.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -51,7 +51,12 @@ #include <pulsecore/macro.h> #include <pulsecore/strbuf.h> #include <pulsecore/random.h> + +#ifdef HAVE_POLL_H +#include <poll.h> +#else #include <pulsecore/poll.h> +#endif #include "raop_client.h" #include "rtsp_client.h" @@ -339,9 +344,13 @@ static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* he break; case STATE_TEARDOWN: + pa_log_debug("RAOP: TEARDOWN"); + break; + case STATE_SET_PARAMETER: pa_log_debug("RAOP: SET_PARAMETER"); break; + case STATE_DISCONNECTED: pa_assert(c->closed_callback); pa_assert(c->rtsp); diff --git a/src/modules/raop/raop_client.h b/src/modules/raop/raop_client.h index ec3136a7..5ad3e3fa 100644 --- a/src/modules/raop/raop_client.h +++ b/src/modules/raop/raop_client.h @@ -8,7 +8,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/reserve-wrap.c b/src/modules/reserve-wrap.c index 709cb060..7d339270 100644 --- a/src/modules/reserve-wrap.c +++ b/src/modules/reserve-wrap.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/reserve-wrap.h b/src/modules/reserve-wrap.h index 4625fe68..2b97c91c 100644 --- a/src/modules/reserve-wrap.h +++ b/src/modules/reserve-wrap.h @@ -8,7 +8,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/reserve.h b/src/modules/reserve.h index ceb1ad11..b315a08c 100644 --- a/src/modules/reserve.h +++ b/src/modules/reserve.h @@ -31,10 +31,11 @@ typedef struct rd_device rd_device; /* Prototype for a function that is called whenever someone else wants - * your app to release the device you having locked. A return value <= - * 0 denies the request, a positive return value agrees to it. Before - * returning your application should close the device in question - * completely to make sure the new application may acceess it. */ + * your application to release the device it has locked. A return + * value <= 0 denies the request, a positive return value agrees to + * it. Before returning your application should close the device in + * question completely to make sure the new application may access + * it. */ typedef int (*rd_request_cb_t)( rd_device *d, int forced); /* Non-zero if an application forcibly took the lock away without asking. If this is the case then the return value of this call is ignored. */ @@ -48,20 +49,20 @@ int rd_acquire( const char *device_name, /* The device to lock, e.g. "Audio0" */ const char *application_name, /* A human readable name of the application, e.g. "PulseAudio Sound Server" */ int32_t priority, /* The priority for this application. If unsure use 0 */ - rd_request_cb_t request_cb, /* Will be called whenever someone asks that this device shall be released. May be NULL if priority is INT32_MAX */ + rd_request_cb_t request_cb, /* Will be called whenever someone requests that this device shall be released. May be NULL if priority is INT32_MAX */ DBusError *error); /* If we fail due to a D-Bus related issue the error will be filled in here. May be NULL. */ -/* Unlock (if needed) and destroy a rd_device object again */ +/* Unlock (if needed) and destroy an rd_device object again */ void rd_release(rd_device *d); -/* Set the application device name for a rd_device object Returns 0 on - * success, a negative errno style return value on error. */ +/* Set the application device name for an rd_device object. Returns 0 + * on success, a negative errno style return value on error. */ int rd_set_application_device_name(rd_device *d, const char *name); -/* Attach a userdata pointer to a rd_device */ +/* Attach a userdata pointer to an rd_device */ void rd_set_userdata(rd_device *d, void *userdata); -/* Query the userdata pointer from a rd_device. Returns NULL if no +/* Query the userdata pointer from an rd_device. Returns NULL if no * userdata was set. */ void* rd_get_userdata(rd_device *d); diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c index 0d86459e..33e23af2 100644 --- a/src/modules/rtp/module-rtp-recv.c +++ b/src/modules/rtp/module-rtp-recv.c @@ -6,7 +6,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c index fef745a1..722d12bd 100644 --- a/src/modules/rtp/module-rtp-send.c +++ b/src/modules/rtp/module-rtp-send.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp.c index c09c321f..7537c1f5 100644 --- a/src/modules/rtp/rtp.c +++ b/src/modules/rtp/rtp.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/rtp/rtp.h b/src/modules/rtp/rtp.h index a2728f05..eff5e75b 100644 --- a/src/modules/rtp/rtp.h +++ b/src/modules/rtp/rtp.h @@ -8,7 +8,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/rtp/rtsp_client.c b/src/modules/rtp/rtsp_client.c index 9eb3d964..98db05dd 100644 --- a/src/modules/rtp/rtsp_client.c +++ b/src/modules/rtp/rtsp_client.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -43,9 +43,14 @@ #include <pulsecore/log.h> #include <pulsecore/macro.h> #include <pulsecore/strbuf.h> -#include <pulsecore/poll.h> #include <pulsecore/ioline.h> +#ifdef HAVE_POLL_H +#include <poll.h> +#else +#include <pulsecore/poll.h> +#endif + #include "rtsp_client.h" struct pa_rtsp_client { @@ -101,26 +106,27 @@ pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char* hostna void pa_rtsp_client_free(pa_rtsp_client* c) { - if (c) { - if (c->sc) - pa_socket_client_unref(c->sc); - if (c->ioline) - pa_ioline_close(c->ioline); - else if (c->io) - pa_iochannel_free(c->io); - - pa_xfree(c->hostname); - pa_xfree(c->url); - pa_xfree(c->localip); - pa_xfree(c->session); - pa_xfree(c->transport); - pa_xfree(c->last_header); - if (c->header_buffer) - pa_strbuf_free(c->header_buffer); - if (c->response_headers) - pa_headerlist_free(c->response_headers); - pa_headerlist_free(c->headers); - } + pa_assert(c); + + if (c->sc) + pa_socket_client_unref(c->sc); + if (c->ioline) + pa_ioline_close(c->ioline); + else if (c->io) + pa_iochannel_free(c->io); + + pa_xfree(c->hostname); + pa_xfree(c->url); + pa_xfree(c->localip); + pa_xfree(c->session); + pa_xfree(c->transport); + pa_xfree(c->last_header); + if (c->header_buffer) + pa_strbuf_free(c->header_buffer); + if (c->response_headers) + pa_headerlist_free(c->response_headers); + pa_headerlist_free(c->headers); + pa_xfree(c); } @@ -141,8 +147,6 @@ static void headers_read(pa_rtsp_client *c) { c->transport = pa_xstrdup(pa_headerlist_gets(c->response_headers, "Transport")); if (!c->session || !c->transport) { - pa_headerlist_free(c->response_headers); - c->response_headers = NULL; pa_log("Invalid SETUP response."); return; } @@ -160,8 +164,6 @@ static void headers_read(pa_rtsp_client *c) { } if (0 == c->rtp_port) { /* Error no server_port in response */ - pa_headerlist_free(c->response_headers); - c->response_headers = NULL; pa_log("Invalid SETUP response (no port number)."); return; } @@ -169,9 +171,6 @@ static void headers_read(pa_rtsp_client *c) { /* Call our callback */ c->callback(c, c->state, c->response_headers, c->userdata); - - pa_headerlist_free(c->response_headers); - c->response_headers = NULL; } @@ -201,7 +200,8 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) { } if (c->waiting && 0 == strcmp("RTSP/1.0 200 OK", s2)) { c->waiting = 0; - pa_assert(!c->response_headers); + if (c->response_headers) + pa_headerlist_free(c->response_headers); c->response_headers = pa_headerlist_new(); goto exit; } @@ -353,9 +353,12 @@ void pa_rtsp_set_callback(pa_rtsp_client *c, pa_rtsp_cb_t callback, void *userda void pa_rtsp_disconnect(pa_rtsp_client *c) { pa_assert(c); - if (c->io) + if (c->ioline) + pa_ioline_close(c->ioline); + else if (c->io) pa_iochannel_free(c->io); c->io = NULL; + c->ioline = NULL; } diff --git a/src/modules/rtp/rtsp_client.h b/src/modules/rtp/rtsp_client.h index 88fb3839..b229f261 100644 --- a/src/modules/rtp/rtsp_client.h +++ b/src/modules/rtp/rtsp_client.h @@ -8,7 +8,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/rtp/sap.c b/src/modules/rtp/sap.c index b5d9df62..adde16df 100644 --- a/src/modules/rtp/sap.c +++ b/src/modules/rtp/sap.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/rtp/sap.h b/src/modules/rtp/sap.h index 69c757cb..ae4ad426 100644 --- a/src/modules/rtp/sap.h +++ b/src/modules/rtp/sap.h @@ -8,7 +8,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/rtp/sdp.c b/src/modules/rtp/sdp.c index 7c547430..7fc7e38c 100644 --- a/src/modules/rtp/sdp.c +++ b/src/modules/rtp/sdp.c @@ -5,7 +5,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/rtp/sdp.h b/src/modules/rtp/sdp.h index 933a602b..4cb3b203 100644 --- a/src/modules/rtp/sdp.h +++ b/src/modules/rtp/sdp.h @@ -8,7 +8,7 @@ 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, + by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/udev-util.c b/src/modules/udev-util.c index a72bc8f8..8ffb76a8 100644 --- a/src/modules/udev-util.c +++ b/src/modules/udev-util.c @@ -5,7 +5,7 @@ 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 + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but diff --git a/src/modules/udev-util.h b/src/modules/udev-util.h index 86fbba7f..5120abdd 100644 --- a/src/modules/udev-util.h +++ b/src/modules/udev-util.h @@ -8,7 +8,7 @@ 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 + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but |