[pulseaudio-commits] [Git][pulseaudio/pulseaudio][master] 2 commits: sink, source: Call sink input suspend callback also on suspend cause change
Arun Raghavan
gitlab at gitlab.freedesktop.org
Mon Mar 25 05:28:36 UTC 2019
Arun Raghavan pushed to branch master at PulseAudio / pulseaudio
Commits:
acb02d9e by Georg Chini at 2019-03-25T05:16:15Z
sink, source: Call sink input suspend callback also on suspend cause change
Currently, virtual sinks and sources are not suspended when the master sink
or source is suspended. To implement this, the slave must be able to track
the suspend cause of the master.
With this patch, the sink input suspend callback will not only be called
when the sink or source is changing state, but also when the suspend cause
changes. Similar to the set_state_in_*_thread_cb() functions, the suspend
callback receives a state and a suspend cause as additional arguments.
Because the new state and suspend cause of the sink or source have already
been set, the old values are passed to the callback.
- - - - -
d537e1a8 by Georg Chini at 2019-03-25T05:16:15Z
ladspa-sink: Suspend virtual sink when master is suspended
Currently, the ladspa-sink is not suspended when the master sink is suspended.
With this patch, the ladspa-sink will be suspended with suspend cause
PA_SUSPEND_UNAVAILABLE when the master sink is suspended for other reasons
than PA_SUSPEND_IDLE. This fixes issue #15.
- - - - -
7 changed files:
- src/modules/module-ladspa-sink.c
- src/modules/module-loopback.c
- src/pulsecore/protocol-native.c
- src/pulsecore/sink-input.h
- src/pulsecore/sink.c
- src/pulsecore/source-output.h
- src/pulsecore/source.c
Changes:
=====================================
src/modules/module-ladspa-sink.c
=====================================
@@ -707,6 +707,19 @@ static void sink_input_mute_changed_cb(pa_sink_input *i) {
pa_sink_mute_changed(u->sink, i->muted);
}
+/* Called from main context */
+static void sink_input_suspend_cb(pa_sink_input *i, pa_sink_state_t old_state, pa_suspend_cause_t old_suspend_cause) {
+ struct userdata *u;
+
+ pa_sink_input_assert_ref(i);
+ pa_assert_se(u = i->userdata);
+
+ if (i->sink->state != PA_SINK_SUSPENDED || i->sink->suspend_cause == PA_SUSPEND_IDLE)
+ pa_sink_suspend(u->sink, false, PA_SUSPEND_UNAVAILABLE);
+ else
+ pa_sink_suspend(u->sink, true, PA_SUSPEND_UNAVAILABLE);
+}
+
static int parse_control_parameters(struct userdata *u, const char *cdata, double *read_values, bool *use_default) {
unsigned long p = 0;
const char *state = NULL;
@@ -1346,6 +1359,7 @@ int pa__init(pa_module*m) {
u->sink_input->may_move_to = sink_input_may_move_to_cb;
u->sink_input->moving = sink_input_moving_cb;
u->sink_input->mute_changed = sink_input_mute_changed_cb;
+ u->sink_input->suspend = sink_input_suspend_cb;
u->sink_input->userdata = u;
u->sink->input_to_master = u->sink_input;
=====================================
src/modules/module-loopback.c
=====================================
@@ -761,13 +761,20 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
}
/* Called from main thread */
-static void source_output_suspend_cb(pa_source_output *o, bool suspended) {
+static void source_output_suspend_cb(pa_source_output *o, pa_source_state_t old_state, pa_suspend_cause_t old_suspend_cause) {
struct userdata *u;
+ bool suspended;
pa_source_output_assert_ref(o);
pa_assert_ctl_context();
pa_assert_se(u = o->userdata);
+ /* State has not changed, nothing to do */
+ if (old_state == o->source->state)
+ return;
+
+ suspended = (o->source->state == PA_SOURCE_SUSPENDED);
+
/* If the source has been suspended, we need to handle this like
* a source change when the source is resumed */
if (suspended) {
@@ -1160,13 +1167,20 @@ static bool sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
}
/* Called from main thread */
-static void sink_input_suspend_cb(pa_sink_input *i, bool suspended) {
+static void sink_input_suspend_cb(pa_sink_input *i, pa_sink_state_t old_state, pa_suspend_cause_t old_suspend_cause) {
struct userdata *u;
+ bool suspended;
pa_sink_input_assert_ref(i);
pa_assert_ctl_context();
pa_assert_se(u = i->userdata);
+ /* State has not changed, nothing to do */
+ if (old_state == i->sink->state)
+ return;
+
+ suspended = (i->sink->state == PA_SINK_SUSPENDED);
+
/* If the sink has been suspended, we need to handle this like
* a sink change when the sink is resumed. Because the sink
* is suspended, we can set the variables directly. */
=====================================
src/pulsecore/protocol-native.c
=====================================
@@ -241,7 +241,7 @@ enum {
static bool sink_input_process_underrun_cb(pa_sink_input *i);
static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk);
static void sink_input_kill_cb(pa_sink_input *i);
-static void sink_input_suspend_cb(pa_sink_input *i, bool suspend);
+static void sink_input_suspend_cb(pa_sink_input *i, pa_sink_state_t old_state, pa_suspend_cause_t old_suspend_cause);
static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest);
static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes);
static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes);
@@ -253,7 +253,7 @@ static void playback_stream_request_bytes(struct playback_stream*s);
static void source_output_kill_cb(pa_source_output *o);
static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk);
-static void source_output_suspend_cb(pa_source_output *o, bool suspend);
+static void source_output_suspend_cb(pa_source_output *o, pa_source_state_t old_state, pa_suspend_cause_t old_suspend_cause);
static void source_output_moving_cb(pa_source_output *o, pa_source *dest);
static pa_usec_t source_output_get_latency_cb(pa_source_output *o);
static void source_output_send_event_cb(pa_source_output *o, const char *event, pa_proplist *pl);
@@ -1618,11 +1618,19 @@ static void sink_input_send_event_cb(pa_sink_input *i, const char *event, pa_pro
}
/* Called from main context */
-static void sink_input_suspend_cb(pa_sink_input *i, bool suspend) {
+static void sink_input_suspend_cb(pa_sink_input *i, pa_sink_state_t old_state, pa_suspend_cause_t old_suspend_cause) {
playback_stream *s;
pa_tagstruct *t;
+ bool suspend;
pa_sink_input_assert_ref(i);
+
+ /* State has not changed, nothing to do */
+ if (old_state == i->sink->state)
+ return;
+
+ suspend = (i->sink->state == PA_SINK_SUSPENDED);
+
s = PLAYBACK_STREAM(i->userdata);
playback_stream_assert_ref(s);
@@ -1756,11 +1764,19 @@ static void source_output_send_event_cb(pa_source_output *o, const char *event,
}
/* Called from main context */
-static void source_output_suspend_cb(pa_source_output *o, bool suspend) {
+static void source_output_suspend_cb(pa_source_output *o, pa_source_state_t old_state, pa_suspend_cause_t old_suspend_cause) {
record_stream *s;
pa_tagstruct *t;
+ bool suspend;
pa_source_output_assert_ref(o);
+
+ /* State has not changed, nothing to do */
+ if (old_state == o->source->state)
+ return;
+
+ suspend = (o->source->state == PA_SOURCE_SUSPENDED);
+
s = RECORD_STREAM(o->userdata);
record_stream_assert_ref(s);
=====================================
src/pulsecore/sink-input.h
=====================================
@@ -179,8 +179,9 @@ struct pa_sink_input {
void (*detach) (pa_sink_input *i); /* may be NULL */
/* If non-NULL called whenever the sink this input is attached
- * to suspends or resumes. Called from main context */
- void (*suspend) (pa_sink_input *i, bool b); /* may be NULL */
+ * to suspends or resumes or if the suspend cause changes.
+ * Called from main context */
+ void (*suspend) (pa_sink_input *i, pa_sink_state_t old_state, pa_suspend_cause_t old_suspend_cause); /* may be NULL */
/* If non-NULL called whenever the sink this input is attached
* to suspends or resumes. Called from IO context */
=====================================
src/pulsecore/sink.c
=====================================
@@ -400,6 +400,8 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t
bool suspend_cause_changed;
bool suspending;
bool resuming;
+ pa_sink_state_t old_state;
+ pa_suspend_cause_t old_suspend_cause;
pa_assert(s);
pa_assert_ctl_context();
@@ -469,6 +471,7 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t
}
}
+ old_suspend_cause = s->suspend_cause;
if (suspend_cause_changed) {
char old_cause_buf[PA_SUSPEND_CAUSE_TO_STRING_BUF_SIZE];
char new_cause_buf[PA_SUSPEND_CAUSE_TO_STRING_BUF_SIZE];
@@ -478,6 +481,7 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t
s->suspend_cause = suspend_cause;
}
+ old_state = s->state;
if (state_changed) {
pa_log_debug("%s: state: %s -> %s", s->name, pa_sink_state_to_string(s->state), pa_sink_state_to_string(state));
s->state = state;
@@ -490,7 +494,7 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t
}
}
- if (suspending || resuming) {
+ if (suspending || resuming || suspend_cause_changed) {
pa_sink_input *i;
uint32_t idx;
@@ -501,7 +505,7 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t
(i->flags & PA_SINK_INPUT_KILL_ON_SUSPEND))
pa_sink_input_kill(i);
else if (i->suspend)
- i->suspend(i, state == PA_SINK_SUSPENDED);
+ i->suspend(i, old_state, old_suspend_cause);
}
if ((suspending || resuming || suspend_cause_changed) && s->monitor_source && state != PA_SINK_UNLINKED)
=====================================
src/pulsecore/source-output.h
=====================================
@@ -150,8 +150,9 @@ struct pa_source_output {
void (*detach) (pa_source_output *o); /* may be NULL */
/* If non-NULL called whenever the source this output is attached
- * to suspends or resumes. Called from main context */
- void (*suspend) (pa_source_output *o, bool b); /* may be NULL */
+ * to suspends or resumes or if the suspend cause changes.
+ * Called from main context */
+ void (*suspend) (pa_source_output *o, pa_source_state_t old_state, pa_suspend_cause_t old_suspend_cause); /* may be NULL */
/* If non-NULL called whenever the source this output is attached
* to suspends or resumes. Called from IO context */
=====================================
src/pulsecore/source.c
=====================================
@@ -354,6 +354,8 @@ static int source_set_state(pa_source *s, pa_source_state_t state, pa_suspend_ca
bool suspend_cause_changed;
bool suspending;
bool resuming;
+ pa_source_state_t old_state;
+ pa_suspend_cause_t old_suspend_cause;
pa_assert(s);
pa_assert_ctl_context();
@@ -423,6 +425,7 @@ static int source_set_state(pa_source *s, pa_source_state_t state, pa_suspend_ca
}
}
+ old_suspend_cause = s->suspend_cause;
if (suspend_cause_changed) {
char old_cause_buf[PA_SUSPEND_CAUSE_TO_STRING_BUF_SIZE];
char new_cause_buf[PA_SUSPEND_CAUSE_TO_STRING_BUF_SIZE];
@@ -432,6 +435,7 @@ static int source_set_state(pa_source *s, pa_source_state_t state, pa_suspend_ca
s->suspend_cause = suspend_cause;
}
+ old_state = s->state;
if (state_changed) {
pa_log_debug("%s: state: %s -> %s", s->name, pa_source_state_to_string(s->state), pa_source_state_to_string(state));
s->state = state;
@@ -444,7 +448,7 @@ static int source_set_state(pa_source *s, pa_source_state_t state, pa_suspend_ca
}
}
- if (suspending || resuming) {
+ if (suspending || resuming || suspend_cause_changed) {
pa_source_output *o;
uint32_t idx;
@@ -455,7 +459,7 @@ static int source_set_state(pa_source *s, pa_source_state_t state, pa_suspend_ca
(o->flags & PA_SOURCE_OUTPUT_KILL_ON_SUSPEND))
pa_source_output_kill(o);
else if (o->suspend)
- o->suspend(o, state == PA_SOURCE_SUSPENDED);
+ o->suspend(o, old_state, old_suspend_cause);
}
return ret;
View it on GitLab: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/compare/f7b3537bbf9a6916ee3fd72a82025519b4c346f5...d537e1a8ee452c813fb64d491b1a7db4dc061a19
--
View it on GitLab: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/compare/f7b3537bbf9a6916ee3fd72a82025519b4c346f5...d537e1a8ee452c813fb64d491b1a7db4dc061a19
You're receiving this email because of your account on gitlab.freedesktop.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/pulseaudio-commits/attachments/20190325/e34f81c7/attachment-0001.html>
More information about the pulseaudio-commits
mailing list