[pulseaudio-discuss] [PATCH] sink, source: Rework reconfiguration logic to apply to more than rate

Arun Raghavan arun at arunraghavan.net
Sun Sep 3 11:28:50 UTC 2017


This rejigs the update_rate() logic to encompass changes to the sample
spec as a whole, as well as passthrough status. As a result,
sinks/sources provide a reconfigure() method which allows
reconfiguration as required.

The behaviour itself is currently unchanged -- alsa-sink/-source do not
actually implement anything other than rate updates for now (nor are
they ever requested to). This can be modified in the future, to allow,
for example 24-bit output when incoming media supports it, as well as
channel count changes for passthrough sinks.

Another related change is that passthrough status is now part of
sink/source reconfiguration, and we can stop doing a suspend/unsuspend
when entering/leaving passthrough state. So that part is now divided
in two -- pa_sink_reconfigure() sets the sink in passthrough mode if
required, and pa_sink_enter_passthrough() sets up everything else
(this currently means only volumes, but could disable other processing)
for passthrough mode.
---
 src/modules/alsa/alsa-sink.c   | 16 +++++---
 src/modules/alsa/alsa-source.c | 14 ++++---
 src/pulsecore/sink-input.c     |  6 +--
 src/pulsecore/sink.c           | 87 ++++++++++++++++--------------------------
 src/pulsecore/sink.h           |  6 +--
 src/pulsecore/source-output.c  |  6 +--
 src/pulsecore/source.c         | 58 +++++++++++++++-------------
 src/pulsecore/source.h         |  6 +--
 8 files changed, 94 insertions(+), 105 deletions(-)

diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 827a65081..96fd02aec 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -1596,31 +1596,35 @@ static bool sink_set_formats(pa_sink *s, pa_idxset *formats) {
     return true;
 }
 
-static int sink_update_rate_cb(pa_sink *s, uint32_t rate) {
+static int sink_reconfigure_cb(pa_sink *s, pa_sample_spec *spec, bool passthrough) {
     struct userdata *u = s->userdata;
     int i;
     bool supported = false;
 
+    /* FIXME: we only update rate for now */
+
     pa_assert(u);
 
     for (i = 0; u->rates[i]; i++) {
-        if (u->rates[i] == rate) {
+        if (u->rates[i] == spec->rate) {
             supported = true;
             break;
         }
     }
 
     if (!supported) {
-        pa_log_info("Sink does not support sample rate of %d Hz", rate);
+        pa_log_info("Sink does not support sample rate of %d Hz", spec->rate);
         return -1;
     }
 
     if (!PA_SINK_IS_OPENED(s->state)) {
-        pa_log_info("Updating rate for device %s, new rate is %d",u->device_name, rate);
-        u->sink->sample_spec.rate = rate;
+        pa_log_info("Updating rate for device %s, new rate is %d", u->device_name, spec->rate);
+        u->sink->sample_spec.rate = spec->rate;
         return 0;
     }
 
+    /* Passthrough status change is handled during unsuspend */
+
     return -1;
 }
 
@@ -2357,7 +2361,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
     else
         u->sink->set_port = sink_set_port_cb;
     if (u->sink->alternate_sample_rate)
-        u->sink->update_rate = sink_update_rate_cb;
+        u->sink->reconfigure = sink_reconfigure_cb;
     u->sink->userdata = u;
 
     pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index 6bec188ea..3f87a4792 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -1398,28 +1398,30 @@ static void source_update_requested_latency_cb(pa_source *s) {
     update_sw_params(u);
 }
 
-static int source_update_rate_cb(pa_source *s, uint32_t rate) {
+static int source_reconfigure_cb(pa_source *s, pa_sample_spec *spec, bool passthrough) {
     struct userdata *u = s->userdata;
     int i;
     bool supported = false;
 
+    /* FIXME: we only update rate for now */
+
     pa_assert(u);
 
     for (i = 0; u->rates[i]; i++) {
-        if (u->rates[i] == rate) {
+        if (u->rates[i] == spec->rate) {
             supported = true;
             break;
         }
     }
 
     if (!supported) {
-        pa_log_info("Source does not support sample rate of %d Hz", rate);
+        pa_log_info("Source does not support sample rate of %d Hz", spec->rate);
         return -1;
     }
 
     if (!PA_SOURCE_IS_OPENED(s->state)) {
-        pa_log_info("Updating rate for device %s, new rate is %d", u->device_name, rate);
-        u->source->sample_spec.rate = rate;
+        pa_log_info("Updating rate for device %s, new rate is %d", u->device_name, spec->rate);
+        u->source->sample_spec.rate = spec->rate;
         return 0;
     }
 
@@ -2041,7 +2043,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
     else
         u->source->set_port = source_set_port_cb;
     if (u->source->alternate_sample_rate)
-        u->source->update_rate = source_update_rate_cb;
+        u->source->reconfigure = source_reconfigure_cb;
     u->source->userdata = u;
 
     pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 2ceed412d..29e45dade 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -410,7 +410,7 @@ int pa_sink_input_new(
            module-suspend-on-idle can resume a sink */
 
         pa_log_info("Trying to change sample rate");
-        if (pa_sink_update_rate(data->sink, data->sample_spec.rate, pa_sink_input_new_data_is_passthrough(data)) >= 0)
+        if (pa_sink_reconfigure(data->sink, &data->sample_spec, pa_sink_input_new_data_is_passthrough(data)) >= 0)
             pa_log_info("Rate changed to %u Hz", data->sink->sample_spec.rate);
     }
 
@@ -609,7 +609,7 @@ static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state)
             !pa_sample_spec_equal(&i->sample_spec, &i->sink->sample_spec)) {
             /* We were uncorked and the sink was not playing anything -- let's try
              * to update the sample rate to avoid resampling */
-            pa_sink_update_rate(i->sink, i->sample_spec.rate, pa_sink_input_is_passthrough(i));
+            pa_sink_reconfigure(i->sink, &i->sample_spec, pa_sink_input_is_passthrough(i));
         }
 
         pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0);
@@ -1879,7 +1879,7 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, bool save) {
            SINK_INPUT_MOVE_FINISH hook */
 
         pa_log_info("Trying to change sample rate");
-        if (pa_sink_update_rate(dest, i->sample_spec.rate, pa_sink_input_is_passthrough(i)) >= 0)
+        if (pa_sink_reconfigure(dest, &i->sample_spec, pa_sink_input_is_passthrough(i)) >= 0)
             pa_log_info("Rate changed to %u Hz", dest->sample_spec.rate);
     }
 
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index c0b7cb2c5..f1813b6d1 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -161,7 +161,7 @@ static void reset_callbacks(pa_sink *s) {
     s->set_port = NULL;
     s->get_formats = NULL;
     s->set_formats = NULL;
-    s->update_rate = NULL;
+    s->reconfigure = NULL;
 }
 
 /* Called from main context */
@@ -1412,9 +1412,9 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
 }
 
 /* Called from main thread */
-int pa_sink_update_rate(pa_sink *s, uint32_t rate, bool passthrough) {
+int pa_sink_reconfigure(pa_sink *s, pa_sample_spec *spec, bool passthrough) {
     int ret = -1;
-    uint32_t desired_rate;
+    pa_sample_spec desired_spec;
     uint32_t default_rate = s->default_sample_rate;
     uint32_t alternate_rate = s->alternate_sample_rate;
     uint32_t idx;
@@ -1423,10 +1423,12 @@ int pa_sink_update_rate(pa_sink *s, uint32_t rate, bool passthrough) {
     bool alternate_rate_is_usable = false;
     bool avoid_resampling = s->core->avoid_resampling;
 
-    if (rate == s->sample_spec.rate)
+    /* We currently only try to reconfigure the sample rate */
+
+    if (pa_sample_spec_equal(spec, &s->sample_spec))
         return 0;
 
-    if (!s->update_rate)
+    if (!s->reconfigure)
         return -1;
 
     if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough && !avoid_resampling)) {
@@ -1447,52 +1449,57 @@ int pa_sink_update_rate(pa_sink *s, uint32_t rate, bool passthrough) {
         }
     }
 
-    if (PA_UNLIKELY(!pa_sample_rate_valid(rate)))
+    if (PA_UNLIKELY(!pa_sample_spec_valid(spec)))
         return -1;
 
+    desired_spec = s->sample_spec;
+
     if (passthrough) {
         /* We have to try to use the sink input rate */
-        desired_rate = rate;
+        desired_spec.rate = spec->rate;
 
-    } else if (avoid_resampling && (rate >= default_rate || rate >= alternate_rate)) {
+    } else if (avoid_resampling && (spec->rate >= default_rate || spec->rate >= alternate_rate)) {
         /* We just try to set the sink input's sample rate if it's not too low */
-        desired_rate = rate;
+        desired_spec.rate = spec->rate;
 
-    } else if (default_rate == rate || alternate_rate == rate) {
+    } else if (default_rate == spec->rate || alternate_rate == spec->rate) {
         /* We can directly try to use this rate */
-        desired_rate = rate;
+        desired_spec.rate = spec->rate;
 
     } else {
         /* See if we can pick a rate that results in less resampling effort */
-        if (default_rate % 11025 == 0 && rate % 11025 == 0)
+        if (default_rate % 11025 == 0 && spec->rate % 11025 == 0)
             default_rate_is_usable = true;
-        if (default_rate % 4000 == 0 && rate % 4000 == 0)
+        if (default_rate % 4000 == 0 && spec->rate % 4000 == 0)
             default_rate_is_usable = true;
-        if (alternate_rate && alternate_rate % 11025 == 0 && rate % 11025 == 0)
+        if (alternate_rate && alternate_rate % 11025 == 0 && spec->rate % 11025 == 0)
             alternate_rate_is_usable = true;
-        if (alternate_rate && alternate_rate % 4000 == 0 && rate % 4000 == 0)
+        if (alternate_rate && alternate_rate % 4000 == 0 && spec->rate % 4000 == 0)
             alternate_rate_is_usable = true;
 
         if (alternate_rate_is_usable && !default_rate_is_usable)
-            desired_rate = alternate_rate;
+            desired_spec.rate = alternate_rate;
         else
-            desired_rate = default_rate;
+            desired_spec.rate = default_rate;
     }
 
-    if (desired_rate == s->sample_spec.rate)
+    if (pa_sample_spec_equal(&desired_spec, &s->sample_spec) && passthrough == pa_sink_is_passthrough(s))
         return -1;
 
     if (!passthrough && pa_sink_used_by(s) > 0)
         return -1;
 
-    pa_log_debug("Suspending sink %s due to changing the sample rate.", s->name);
+    pa_log_debug("Suspending sink %s due to changing format.", s->name);
     pa_sink_suspend(s, true, PA_SUSPEND_INTERNAL);
 
-    if (s->update_rate(s, desired_rate) >= 0) {
+    /* Flag for the sink now that we want it configured for passthrough */
+    s->is_passthrough_set = passthrough;
+
+    if (s->reconfigure(s, &desired_spec, passthrough) >= 0) {
         /* update monitor source as well */
         if (s->monitor_source && !passthrough)
-            pa_source_update_rate(s->monitor_source, desired_rate, false);
-        pa_log_info("Changed sampling rate successfully");
+            pa_source_reconfigure(s->monitor_source, &desired_spec, false);
+        pa_log_info("Changed format successfully");
 
         PA_IDXSET_FOREACH(i, s->inputs, idx) {
             if (i->state == PA_SINK_INPUT_CORKED)
@@ -1607,30 +1614,18 @@ bool pa_sink_is_filter(pa_sink *s) {
 
 /* Called from main context */
 bool pa_sink_is_passthrough(pa_sink *s) {
-    pa_sink_input *alt_i;
-    uint32_t idx;
-
     pa_sink_assert_ref(s);
 
-    /* one and only one PASSTHROUGH input can possibly be connected */
-    if (pa_idxset_size(s->inputs) == 1) {
-        alt_i = pa_idxset_first(s->inputs, &idx);
-
-        if (pa_sink_input_is_passthrough(alt_i))
-            return true;
-    }
-
-    return false;
+    return s->is_passthrough_set;
 }
 
 /* Called from main context */
 void pa_sink_enter_passthrough(pa_sink *s) {
     pa_cvolume volume;
 
-    if (s->is_passthrough_set) {
-	pa_log_debug("Sink %s is already in passthrough mode, nothing to do", s->name);
-	return;
-    }
+    /* The sink implementation is reconfigured for passthrough in
+     * pa_sink_reconfigure(). This function sets the PA core objects to
+     * passthrough mode. */
 
     /* disable the monitor in passthrough mode */
     if (s->monitor_source) {
@@ -1646,21 +1641,10 @@ void pa_sink_enter_passthrough(pa_sink *s) {
     pa_sink_set_volume(s, &volume, true, false);
 
     pa_log_debug("Suspending/Restarting sink %s to enter passthrough mode", s->name);
-
-    /* force sink to be resumed in passthrough mode */
-    pa_sink_suspend(s, true, PA_SUSPEND_INTERNAL);
-    s->is_passthrough_set = true;
-    pa_sink_suspend(s, false, PA_SUSPEND_INTERNAL);
 }
 
 /* Called from main context */
 void pa_sink_leave_passthrough(pa_sink *s) {
-
-    if (!s->is_passthrough_set) {
-	pa_log_debug("Sink %s is not in passthrough mode, nothing to do", s->name);
-	return;
-    }
-
     /* Unsuspend monitor */
     if (s->monitor_source) {
         pa_log_debug("Resuming monitor source %s, because the sink is leaving the passthrough mode.", s->monitor_source->name);
@@ -1673,11 +1657,6 @@ void pa_sink_leave_passthrough(pa_sink *s) {
     pa_cvolume_init(&s->saved_volume);
     s->saved_save_volume = false;
 
-    /* force sink to be resumed in non-passthrough mode */
-    pa_sink_suspend(s, true, PA_SUSPEND_INTERNAL);
-    s->is_passthrough_set = false;
-    pa_sink_suspend(s, false, PA_SUSPEND_INTERNAL);
-
 }
 
 /* Called from main context. */
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index 7deafdd85..457b0e3a0 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -245,9 +245,9 @@ struct pa_sink {
      * set). Makes a copy of the formats passed in. */
     bool (*set_formats)(pa_sink *s, pa_idxset *formats); /* may be NULL */
 
-    /* Called whenever the sampling frequency shall be changed. Called from
+    /* Called whenever device parameters need to be changed. Called from
      * main thread. */
-    int (*update_rate)(pa_sink *s, uint32_t rate);
+    int (*reconfigure)(pa_sink *s, pa_sample_spec *spec, bool passthrough);
 
     /* Contains copies of the above data so that the real-time worker
      * thread can work without access locking */
@@ -423,7 +423,7 @@ unsigned pa_device_init_priority(pa_proplist *p);
 
 /**** May be called by everyone, from main context */
 
-int pa_sink_update_rate(pa_sink *s, uint32_t rate, bool passthrough);
+int pa_sink_reconfigure(pa_sink *s, pa_sample_spec *spec, bool passthrough);
 void pa_sink_set_port_latency_offset(pa_sink *s, int64_t offset);
 
 /* The returned value is supposed to be in the time domain of the sound card! */
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index fa32a5666..a591ae83c 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -356,7 +356,7 @@ int pa_source_output_new(
            module-suspend-on-idle can resume a source */
 
         pa_log_info("Trying to change sample rate");
-        if (pa_source_update_rate(data->source, data->sample_spec.rate, pa_source_output_new_data_is_passthrough(data)) >= 0)
+        if (pa_source_reconfigure(data->source, &data->sample_spec, pa_source_output_new_data_is_passthrough(data)) >= 0)
             pa_log_info("Rate changed to %u Hz", data->source->sample_spec.rate);
     }
 
@@ -529,7 +529,7 @@ static void source_output_set_state(pa_source_output *o, pa_source_output_state_
             !pa_sample_spec_equal(&o->sample_spec, &o->source->sample_spec)) {
             /* We were uncorked and the source was not playing anything -- let's try
              * to update the sample rate to avoid resampling */
-            pa_source_update_rate(o->source, o->sample_spec.rate, pa_source_output_is_passthrough(o));
+            pa_source_reconfigure(o->source, &o->sample_spec, pa_source_output_is_passthrough(o));
         }
 
         pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0);
@@ -1501,7 +1501,7 @@ int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, bool save
            SOURCE_OUTPUT_MOVE_FINISH hook */
 
         pa_log_info("Trying to change sample rate");
-        if (pa_source_update_rate(dest, o->sample_spec.rate, pa_source_output_is_passthrough(o)) >= 0)
+        if (pa_source_reconfigure(dest, o->sample_spec.rate, pa_source_output_is_passthrough(o)) >= 0)
             pa_log_info("Rate changed to %u Hz", dest->sample_spec.rate);
     }
 
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 865fb1440..8752b2d11 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -150,7 +150,7 @@ static void reset_callbacks(pa_source *s) {
     s->update_requested_latency = NULL;
     s->set_port = NULL;
     s->get_formats = NULL;
-    s->update_rate = NULL;
+    s->reconfigure = NULL;
 }
 
 /* Called from main context */
@@ -982,19 +982,21 @@ void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *
 }
 
 /* Called from main thread */
-int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
+int pa_source_reconfigure(pa_source *s, pa_sample_spec *spec, bool passthrough) {
     int ret;
-    uint32_t desired_rate;
+    pa_sample_spec desired_spec;
     uint32_t default_rate = s->default_sample_rate;
     uint32_t alternate_rate = s->alternate_sample_rate;
     bool default_rate_is_usable = false;
     bool alternate_rate_is_usable = false;
     bool avoid_resampling = s->core->avoid_resampling;
 
-    if (rate == s->sample_spec.rate)
+    /* We currently only try to reconfigure the sample rate */
+
+    if (pa_sample_spec_equal(spec, &s->sample_spec))
         return 0;
 
-    if (!s->update_rate && !s->monitor_of)
+    if (!s->reconfigure && !s->monitor_of)
         return -1;
 
     if (PA_UNLIKELY(default_rate == alternate_rate && !passthrough && !avoid_resampling)) {
@@ -1015,39 +1017,41 @@ int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
         }
     }
 
-    if (PA_UNLIKELY(!pa_sample_rate_valid(rate)))
+    if (PA_UNLIKELY(!pa_sample_spec_valid(spec)))
         return -1;
 
+    desired_spec = s->sample_spec;
+
     if (passthrough) {
         /* We have to try to use the source output rate */
-        desired_rate = rate;
+        desired_spec.rate = spec->rate;
 
-    } else if (avoid_resampling && (rate >= default_rate || rate >= alternate_rate)) {
+    } else if (avoid_resampling && (spec->rate >= default_rate || spec->rate >= alternate_rate)) {
         /* We just try to set the source output's sample rate if it's not too low */
-        desired_rate = rate;
+        desired_spec.rate = spec->rate;
 
-    } else if (default_rate == rate || alternate_rate == rate) {
+    } else if (default_rate == spec->rate || alternate_rate == spec->rate) {
         /* We can directly try to use this rate */
-        desired_rate = rate;
+        desired_spec.rate = spec->rate;
 
     } else {
         /* See if we can pick a rate that results in less resampling effort */
-        if (default_rate % 11025 == 0 && rate % 11025 == 0)
+        if (default_rate % 11025 == 0 && spec->rate % 11025 == 0)
             default_rate_is_usable = true;
-        if (default_rate % 4000 == 0 && rate % 4000 == 0)
+        if (default_rate % 4000 == 0 && spec->rate % 4000 == 0)
             default_rate_is_usable = true;
-        if (alternate_rate && alternate_rate % 11025 == 0 && rate % 11025 == 0)
+        if (alternate_rate && alternate_rate % 11025 == 0 && spec->rate % 11025 == 0)
             alternate_rate_is_usable = true;
-        if (alternate_rate && alternate_rate % 4000 == 0 && rate % 4000 == 0)
+        if (alternate_rate && alternate_rate % 4000 == 0 && spec->rate % 4000 == 0)
             alternate_rate_is_usable = true;
 
         if (alternate_rate_is_usable && !default_rate_is_usable)
-            desired_rate = alternate_rate;
+            desired_spec.rate = alternate_rate;
         else
-            desired_rate = default_rate;
+            desired_spec.rate = default_rate;
     }
 
-    if (desired_rate == s->sample_spec.rate)
+    if (pa_sample_spec_equal(&desired_spec, &s->sample_spec) && passthrough == pa_source_is_passthrough(s))
         return -1;
 
     if (!passthrough && pa_source_used_by(s) > 0)
@@ -1056,8 +1060,8 @@ int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
     pa_log_debug("Suspending source %s due to changing the sample rate.", s->name);
     pa_source_suspend(s, true, PA_SUSPEND_INTERNAL);
 
-    if (s->update_rate)
-        ret = s->update_rate(s, desired_rate);
+    if (s->reconfigure)
+        ret = s->reconfigure(s, &desired_spec, passthrough);
     else {
         /* This is a monitor source. */
 
@@ -1065,23 +1069,23 @@ int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough) {
          * have no idea whether the behaviour with passthrough streams is
          * sensible. */
         if (!passthrough) {
-            uint32_t old_rate = s->sample_spec.rate;
+            pa_sample_spec old_spec = s->sample_spec;
 
-            s->sample_spec.rate = desired_rate;
-            ret = pa_sink_update_rate(s->monitor_of, desired_rate, false);
+            s->sample_spec = desired_spec;
+            ret = pa_sink_reconfigure(s->monitor_of, &desired_spec, false);
 
             if (ret < 0) {
                 /* Changing the sink rate failed, roll back the old rate for
                  * the monitor source. Why did we set the source rate before
-                 * calling pa_sink_update_rate(), you may ask. The reason is
-                 * that pa_sink_update_rate() tries to update the monitor
+                 * calling pa_sink_reconfigure(), you may ask. The reason is
+                 * that pa_sink_reconfigure() tries to update the monitor
                  * source rate, but we are already in the process of updating
                  * the monitor source rate, so there's a risk of entering an
                  * infinite loop. Setting the source rate before calling
-                 * pa_sink_update_rate() makes the rate == s->sample_spec.rate
+                 * pa_sink_reconfigure() makes the rate == s->sample_spec.rate
                  * check in the beginning of this function return early, so we
                  * avoid looping. */
-                s->sample_spec.rate = old_rate;
+                s->sample_spec = old_spec;
             }
         } else
             ret = -1;
diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
index 1e33cde2d..7fb4a79ea 100644
--- a/src/pulsecore/source.h
+++ b/src/pulsecore/source.h
@@ -202,9 +202,9 @@ struct pa_source {
      * in descending order of preference. */
     pa_idxset* (*get_formats)(pa_source *s); /* ditto */
 
-    /* Called whenever the sampling frequency shall be changed. Called from
+    /* Called whenever device parameters need to be changed. Called from
      * main thread. */
-    int (*update_rate)(pa_source *s, uint32_t rate);
+    int (*reconfigure)(pa_source *s, pa_sample_spec *spec, bool passthrough);
 
     /* Contains copies of the above data so that the real-time worker
      * thread can work without access locking */
@@ -396,7 +396,7 @@ bool pa_source_update_proplist(pa_source *s, pa_update_mode_t mode, pa_proplist
 int pa_source_set_port(pa_source *s, const char *name, bool save);
 void pa_source_set_mixer_dirty(pa_source *s, bool is_dirty);
 
-int pa_source_update_rate(pa_source *s, uint32_t rate, bool passthrough);
+int pa_source_reconfigure(pa_source *s, pa_sample_spec *spec, bool passthrough);
 
 unsigned pa_source_linked_by(pa_source *s); /* Number of connected streams */
 unsigned pa_source_used_by(pa_source *s); /* Number of connected streams that are not corked */
-- 
2.13.5



More information about the pulseaudio-discuss mailing list