[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master, updated. v0.9.13-405-gd1b754d

Lennart Poettering gitmailer-noreply at 0pointer.de
Tue Jan 27 14:40:43 PST 2009


This is an automated email from the git hooks/post-receive script. It was
generated because of a push to the "PulseAudio Sound Server" repository.

The master branch has been updated
      from  0ca16caff7658ec0624a17ad43ce48645696534a (commit)

- Log -----------------------------------------------------------------
d1b754d... only store volume/device information that has been flagged for saving, and store both relative and absolute volumes
64b0543... when changing volume, store whether it is worth remembering or no
ee17772... add missing 'const'
-----------------------------------------------------------------------

Summary of changes:
 src/modules/alsa/module-alsa-card.c |    4 +-
 src/modules/module-match.c          |    2 +-
 src/modules/module-rescue-streams.c |    4 +-
 src/modules/module-stream-restore.c |  211 ++++++++++++++++++++++++++--------
 src/pulse/volume.c                  |    2 +-
 src/pulse/volume.h                  |    2 +-
 src/pulsecore/cli-command.c         |    8 +-
 src/pulsecore/protocol-esound.c     |    2 +-
 src/pulsecore/protocol-native.c     |    8 +-
 src/pulsecore/sink-input.c          |   22 +++-
 src/pulsecore/sink-input.h          |   18 ++-
 src/pulsecore/sink.c                |    4 +-
 src/pulsecore/sink.h                |    2 +-
 src/pulsecore/source-output.c       |   14 ++-
 src/pulsecore/source-output.h       |   11 ++-
 src/pulsecore/source.c              |    4 +-
 src/pulsecore/source.h              |    2 +-
 17 files changed, 230 insertions(+), 90 deletions(-)

-----------------------------------------------------------------------

commit ee17772cea3471b0e44fd1598f7ababa4100db0c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 27 22:49:02 2009 +0100

    add missing 'const'

diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index 822fe39..3434cb1 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -341,7 +341,7 @@ static pa_bool_t on_lfe(pa_channel_position_t p) {
         p == PA_CHANNEL_POSITION_LFE;
 }
 
-pa_cvolume *pa_cvolume_remap(pa_cvolume *v, pa_channel_map *from, pa_channel_map *to) {
+pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa_channel_map *to) {
     int a, b;
     pa_cvolume result;
 
diff --git a/src/pulse/volume.h b/src/pulse/volume.h
index c1967b3..9a883ca 100644
--- a/src/pulse/volume.h
+++ b/src/pulse/volume.h
@@ -228,7 +228,7 @@ double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST;
 #endif
 
 /** Remap a volume from one channel mapping to a different channel mapping. \since 0.9.12 */
-pa_cvolume *pa_cvolume_remap(pa_cvolume *v, pa_channel_map *from, pa_channel_map *to);
+pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa_channel_map *to);
 
 /** Return non-zero if the specified volume is compatible with
  * the specified sample spec. \since 0.9.13 */

commit 64b05435889678dcb154c460063395855659485e
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 27 23:35:55 2009 +0100

    when changing volume, store whether it is worth remembering or no

diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 8f192c2..e63414e 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -177,7 +177,7 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
 
             if (inputs) {
                 if (u->sink)
-                    pa_sink_move_all_finish(u->sink, inputs);
+                    pa_sink_move_all_finish(u->sink, inputs, FALSE);
                 else
                     pa_sink_move_all_fail(inputs);
             }
@@ -200,7 +200,7 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
 
             if (outputs) {
                 if (u->source)
-                    pa_source_move_all_finish(u->source, outputs);
+                    pa_source_move_all_finish(u->source, outputs, FALSE);
                 else
                     pa_source_move_all_fail(outputs);
             }
diff --git a/src/modules/module-match.c b/src/modules/module-match.c
index 8c825c4..cbf6268 100644
--- a/src/modules/module-match.c
+++ b/src/modules/module-match.c
@@ -216,7 +216,7 @@ static void callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, v
                 pa_cvolume cv;
                 pa_log_debug("changing volume of sink input '%s' to 0x%03x", n, r->volume);
                 pa_cvolume_set(&cv, si->sample_spec.channels, r->volume);
-                pa_sink_input_set_volume(si, &cv);
+                pa_sink_input_set_volume(si, &cv, TRUE);
             }
         }
     }
diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c
index 07a0237..e52e39c 100644
--- a/src/modules/module-rescue-streams.c
+++ b/src/modules/module-rescue-streams.c
@@ -77,7 +77,7 @@ static pa_hook_result_t sink_hook_callback(pa_core *c, pa_sink *sink, void* user
     }
 
     while ((i = pa_idxset_first(sink->inputs, NULL))) {
-        if (pa_sink_input_move_to(i, target) < 0) {
+        if (pa_sink_input_move_to(i, target, FALSE) < 0) {
             pa_log_warn("Failed to move sink input %u \"%s\" to %s.", i->index, pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME), target->name);
             return PA_HOOK_OK;
         }
@@ -121,7 +121,7 @@ static pa_hook_result_t source_hook_callback(pa_core *c, pa_source *source, void
     pa_assert(target != source);
 
     while ((o = pa_idxset_first(source->outputs, NULL))) {
-        if (pa_source_output_move_to(o, target) < 0) {
+        if (pa_source_output_move_to(o, target, FALSE) < 0) {
             pa_log_warn("Failed to move source output %u \"%s\" to %s.", o->index, pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME), target->name);
             return PA_HOOK_OK;
         }
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 464ff2d..f298231 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -438,14 +438,14 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
 
         if (u->restore_muted) {
             pa_log_info("Restoring mute state for sink input %s.", name);
-            pa_sink_input_set_mute(si, e->muted);
+            pa_sink_input_set_mute(si, e->muted, TRUE);
         }
 
         if (u->restore_device &&
             (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
 
             pa_log_info("Restoring device for stream %s.", name);
-            pa_sink_input_move_to(si, s);
+            pa_sink_input_move_to(si, s, TRUE);
         }
     }
 
@@ -465,7 +465,7 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
             (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
 
             pa_log_info("Restoring device for stream %s.", name);
-            pa_source_output_move_to(so, s);
+            pa_source_output_move_to(so, s, TRUE);
         }
     }
 }
diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c
index b93f24f..be5a394 100644
--- a/src/pulsecore/cli-command.c
+++ b/src/pulsecore/cli-command.c
@@ -560,7 +560,7 @@ static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strb
     }
 
     pa_cvolume_set(&cvolume, si->sample_spec.channels, volume);
-    pa_sink_input_set_volume(si, &cvolume);
+    pa_sink_input_set_volume(si, &cvolume, TRUE);
     return 0;
 }
 
@@ -852,7 +852,7 @@ static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf
         return -1;
     }
 
-    pa_sink_input_set_mute(si, mute);
+    pa_sink_input_set_mute(si, mute, TRUE);
     return 0;
 }
 
@@ -1169,7 +1169,7 @@ static int pa_cli_command_move_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf
         return -1;
     }
 
-    if (pa_sink_input_move_to(si, sink) < 0) {
+    if (pa_sink_input_move_to(si, sink, TRUE) < 0) {
         pa_strbuf_puts(buf, "Moved failed.\n");
         return -1;
     }
@@ -1212,7 +1212,7 @@ static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_str
         return -1;
     }
 
-    if (pa_source_output_move_to(so, source) < 0) {
+    if (pa_source_output_move_to(so, source, TRUE) < 0) {
         pa_strbuf_puts(buf, "Moved failed.\n");
         return -1;
     }
diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c
index b1d3909..1311e67 100644
--- a/src/pulsecore/protocol-esound.c
+++ b/src/pulsecore/protocol-esound.c
@@ -760,7 +760,7 @@ static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *
         volume.values[0] = (lvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
         volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE;
         volume.channels = 2;
-        pa_sink_input_set_volume(conn->sink_input, &volume);
+        pa_sink_input_set_volume(conn->sink_input, &volume, TRUE);
         ok = 1;
     } else
         ok = 0;
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 80edb20..c33d15e 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -3170,7 +3170,7 @@ static void command_set_volume(
     else if (source)
         pa_source_set_volume(source, &volume);
     else if (si)
-        pa_sink_input_set_volume(si, &volume);
+        pa_sink_input_set_volume(si, &volume, TRUE);
 
     pa_pstream_send_simple_ack(c->pstream, tag);
 }
@@ -3242,7 +3242,7 @@ static void command_set_mute(
     else if (source)
         pa_source_set_mute(source, mute);
     else if (si)
-        pa_sink_input_set_mute(si, mute);
+        pa_sink_input_set_mute(si, mute, TRUE);
 
     pa_pstream_send_simple_ack(c->pstream, tag);
 }
@@ -3852,7 +3852,7 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag
 
         CHECK_VALIDITY(c->pstream, si && sink, tag, PA_ERR_NOENTITY);
 
-        if (pa_sink_input_move_to(si, sink) < 0) {
+        if (pa_sink_input_move_to(si, sink, TRUE) < 0) {
             pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
             return;
         }
@@ -3871,7 +3871,7 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag
 
         CHECK_VALIDITY(c->pstream, so && source, tag, PA_ERR_NOENTITY);
 
-        if (pa_source_output_move_to(so, source) < 0) {
+        if (pa_source_output_move_to(so, source, TRUE) < 0) {
             pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
             return;
         }
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 8b76df0..d4d1119 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -138,8 +138,10 @@ pa_sink_input* pa_sink_input_new(
 
     pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
 
-    if (!data->sink)
+    if (!data->sink) {
         data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
+        data->save_sink = FALSE;
+    }
 
     pa_return_null_if_fail(data->sink);
     pa_return_null_if_fail(pa_sink_get_state(data->sink) != PA_SINK_UNLINKED);
@@ -168,6 +170,8 @@ pa_sink_input* pa_sink_input_new(
         } else
             pa_cvolume_reset(&data->virtual_volume, data->sample_spec.channels);
 
+        data->save_volume = FALSE;
+
     } else if (!data->virtual_volume_is_absolute) {
 
         /* When the 'absolute' bool is set then we'll treat the volume
@@ -265,6 +269,9 @@ pa_sink_input* pa_sink_input_new(
 
     i->virtual_volume = data->virtual_volume;
     i->soft_volume = data->soft_volume;
+    i->save_volume = data->save_volume;
+    i->save_sink = data->save_sink;
+    i->save_muted = data->save_muted;
 
     i->muted = data->muted;
 
@@ -855,7 +862,7 @@ pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
 }
 
 /* Called from main context */
-void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) {
+void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save) {
     pa_sink_input_assert_ref(i);
     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
     pa_assert(volume);
@@ -866,6 +873,7 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) {
         return;
 
     i->virtual_volume = *volume;
+    i->save_volume = save;
 
     if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
         pa_cvolume new_volume;
@@ -902,7 +910,7 @@ const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i) {
 }
 
 /* Called from main context */
-void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute) {
+void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
     pa_assert(i);
     pa_sink_input_assert_ref(i);
     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
@@ -911,6 +919,7 @@ void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute) {
         return;
 
     i->muted = mute;
+    i->save_muted = save;
 
     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
     pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
@@ -1081,7 +1090,7 @@ int pa_sink_input_start_move(pa_sink_input *i) {
 }
 
 /* Called from main context */
-int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest) {
+int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
     pa_resampler *new_resampler;
 
     pa_sink_input_assert_ref(i);
@@ -1093,6 +1102,7 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest) {
         return -1;
 
     i->sink = dest;
+    i->save_sink = save;
     pa_idxset_put(dest->inputs, i, NULL);
 
     if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
@@ -1169,7 +1179,7 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest) {
 }
 
 /* Called from main context */
-int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest) {
+int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
     pa_sink_input_assert_ref(i);
     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
     pa_assert(i->sink);
@@ -1184,7 +1194,7 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest) {
     if (pa_sink_input_start_move(i) < 0)
         return -1;
 
-    if (pa_sink_input_finish_move(i, dest) < 0)
+    if (pa_sink_input_finish_move(i, dest, save) < 0)
         return -1;
 
     return 0;
diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
index 5bf38de..893d869 100644
--- a/src/pulsecore/sink-input.h
+++ b/src/pulsecore/sink-input.h
@@ -91,7 +91,13 @@ struct pa_sink_input {
     pa_sink_input *sync_prev, *sync_next;
 
     pa_cvolume virtual_volume, soft_volume;
-    pa_bool_t muted;
+    pa_bool_t muted:1;
+
+    /* if TRUE then the source we are connected to and/or the volume
+     * set is worth remembering, i.e. was explicitly chosen by the
+     * user and not automatically. module-stream-restore looks for
+     * this.*/
+    pa_bool_t save_sink:1, save_volume:1, save_muted:1;
 
     pa_resample_method_t requested_resample_method, actual_resample_method;
 
@@ -236,6 +242,8 @@ typedef struct pa_sink_input_new_data {
     pa_bool_t muted_is_set:1;
 
     pa_bool_t virtual_volume_is_absolute:1;
+
+    pa_bool_t save_sink:1, save_volume:1, save_muted:1;
 } pa_sink_input_new_data;
 
 pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data);
@@ -280,15 +288,15 @@ void pa_sink_input_kill(pa_sink_input*i);
 
 pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency);
 
-void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume);
+void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save);
 const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i);
-void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute);
+void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save);
 pa_bool_t pa_sink_input_get_mute(pa_sink_input *i);
 pa_bool_t pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p);
 
 pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i);
 
-int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest);
+int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save);
 pa_bool_t pa_sink_input_may_move(pa_sink_input *i); /* may this sink input move at all? */
 pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest); /* may this sink input move to this sink? */
 
@@ -296,7 +304,7 @@ pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest); /* may thi
  * first the detaching from the old sink, then the attaching to the
  * new sink */
 int pa_sink_input_start_move(pa_sink_input *i);
-int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest);
+int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save);
 
 pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i);
 
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 7735d3a..3afeadb 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -503,7 +503,7 @@ pa_queue *pa_sink_move_all_start(pa_sink *s) {
 }
 
 /* Called from main context */
-void pa_sink_move_all_finish(pa_sink *s, pa_queue *q) {
+void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, pa_bool_t save) {
     pa_sink_input *i;
 
     pa_sink_assert_ref(s);
@@ -511,7 +511,7 @@ void pa_sink_move_all_finish(pa_sink *s, pa_queue *q) {
     pa_assert(q);
 
     while ((i = PA_SINK_INPUT(pa_queue_pop(q)))) {
-        if (pa_sink_input_finish_move(i, s) < 0)
+        if (pa_sink_input_finish_move(i, s, save) < 0)
             pa_sink_input_unlink(i);
 
         pa_sink_input_unref(i);
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index b26ca77..124b4e1 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -256,7 +256,7 @@ unsigned pa_sink_check_suspend(pa_sink *s); /* Returns how many streams are acti
 
 /* Moves all inputs away, and stores them in pa_queue */
 pa_queue *pa_sink_move_all_start(pa_sink *s);
-void pa_sink_move_all_finish(pa_sink *s, pa_queue *q);
+void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, pa_bool_t save);
 void pa_sink_move_all_fail(pa_queue *q);
 
 /*** To be called exclusively by the sink driver, from IO context */
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index 204e06c..1e1ac4e 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -112,8 +112,10 @@ pa_source_output* pa_source_output_new(
 
     pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver));
 
-    if (!data->source)
+    if (!data->source) {
         data->source = pa_namereg_get(core, NULL, PA_NAMEREG_SOURCE);
+        data->save_source = FALSE;
+    }
 
     pa_return_null_if_fail(data->source);
     pa_return_null_if_fail(pa_source_get_state(data->source) != PA_SOURCE_UNLINKED);
@@ -196,7 +198,6 @@ pa_source_output* pa_source_output_new(
     o->source = data->source;
     o->client = data->client;
 
-
     o->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
     o->requested_resample_method = data->resample_method;
     o->sample_spec = data->sample_spec;
@@ -204,6 +205,8 @@ pa_source_output* pa_source_output_new(
 
     o->direct_on_input = data->direct_on_input;
 
+    o->save_source = data->save_source;
+
     reset_callbacks(o);
     o->userdata = NULL;
 
@@ -699,7 +702,7 @@ int pa_source_output_start_move(pa_source_output *o) {
 }
 
 /* Called from main context */
-int pa_source_output_finish_move(pa_source_output *o, pa_source *dest) {
+int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, pa_bool_t save) {
     pa_resampler *new_resampler;
 
     pa_source_output_assert_ref(o);
@@ -711,6 +714,7 @@ int pa_source_output_finish_move(pa_source_output *o, pa_source *dest) {
         return -1;
 
     o->source = dest;
+    o->save_source = save;
     pa_idxset_put(o->source->outputs, o, NULL);
 
     if (pa_source_output_get_state(o) == PA_SOURCE_OUTPUT_CORKED)
@@ -778,7 +782,7 @@ int pa_source_output_finish_move(pa_source_output *o, pa_source *dest) {
 }
 
 /* Called from main context */
-int pa_source_output_move_to(pa_source_output *o, pa_source *dest) {
+int pa_source_output_move_to(pa_source_output *o, pa_source *dest, pa_bool_t save) {
 
     pa_source_output_assert_ref(o);
     pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state));
@@ -794,7 +798,7 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) {
     if (pa_source_output_start_move(o) < 0)
         return -1;
 
-    if (pa_source_output_finish_move(o, dest) < 0)
+    if (pa_source_output_finish_move(o, dest, save) < 0)
         return -1;
 
     return 0;
diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h
index d60e425..671894e 100644
--- a/src/pulsecore/source-output.h
+++ b/src/pulsecore/source-output.h
@@ -79,6 +79,11 @@ struct pa_source_output {
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
 
+    /* if TRUE then the source we are connected to is worth
+     * remembering, i.e. was explicitly chosen by the user and not
+     * automatically. module-stream-restore looks for this.*/
+    pa_bool_t save_source:1;
+
     pa_resample_method_t requested_resample_method, actual_resample_method;
 
     /* Pushes a new memchunk into the output. Called from IO thread
@@ -187,6 +192,8 @@ typedef struct pa_source_output_new_data {
 
     pa_bool_t sample_spec_is_set:1;
     pa_bool_t channel_map_is_set:1;
+
+    pa_bool_t save_source:1;
 } pa_source_output_new_data;
 
 pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data);
@@ -225,13 +232,13 @@ pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o);
 
 pa_bool_t pa_source_output_may_move(pa_source_output *o);
 pa_bool_t pa_source_output_may_move_to(pa_source_output *o, pa_source *dest);
-int pa_source_output_move_to(pa_source_output *o, pa_source *dest);
+int pa_source_output_move_to(pa_source_output *o, pa_source *dest, pa_bool_t save);
 
 /* The same as pa_source_output_move_to() but in two seperate steps,
  * first the detaching from the old source, then the attaching to the
  * new source */
 int pa_source_output_start_move(pa_source_output *o);
-int pa_source_output_finish_move(pa_source_output *o, pa_source *dest);
+int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, pa_bool_t save);
 
 #define pa_source_output_get_state(o) ((o)->state)
 
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index cd6ebc3..0152b08 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -439,7 +439,7 @@ pa_queue *pa_source_move_all_start(pa_source *s) {
 }
 
 /* Called from main context */
-void pa_source_move_all_finish(pa_source *s, pa_queue *q) {
+void pa_source_move_all_finish(pa_source *s, pa_queue *q, pa_bool_t save) {
     pa_source_output *o;
 
     pa_source_assert_ref(s);
@@ -447,7 +447,7 @@ void pa_source_move_all_finish(pa_source *s, pa_queue *q) {
     pa_assert(q);
 
     while ((o = PA_SOURCE_OUTPUT(pa_queue_pop(q)))) {
-        if (pa_source_output_finish_move(o, s) < 0)
+        if (pa_source_output_finish_move(o, s, save) < 0)
             pa_source_output_unlink(o);
 
         pa_source_output_unref(o);
diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
index de23977..8a91016 100644
--- a/src/pulsecore/source.h
+++ b/src/pulsecore/source.h
@@ -239,7 +239,7 @@ unsigned pa_source_check_suspend(pa_source *s); /* Returns how many streams are
 
 /* Moves all inputs away, and stores them in pa_queue */
 pa_queue *pa_source_move_all_start(pa_source *s);
-void pa_source_move_all_finish(pa_source *s, pa_queue *q);
+void pa_source_move_all_finish(pa_source *s, pa_queue *q, pa_bool_t save);
 void pa_source_move_all_fail(pa_queue *q);
 
 /*** To be called exclusively by the source driver, from IO context */

commit d1b754d99867e68dea71d4d6726949d0ce8ba0fa
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jan 27 23:39:39 2009 +0100

    only store volume/device information that has been flagged for saving, and store both relative and absolute volumes

diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index f298231..fe30e29 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -87,10 +87,12 @@ struct userdata {
 };
 
 struct entry {
-    char device[PA_NAME_MAX];
     pa_channel_map channel_map;
-    pa_cvolume volume;
+    char device[PA_NAME_MAX];
+    pa_cvolume relative_volume;
+    pa_cvolume absolute_volume;
     pa_bool_t muted:1;
+    pa_bool_t device_valid:1, relative_volume_valid:1, absolute_volume_valid:1, muted_valid:1;
 };
 
 
@@ -153,7 +155,9 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
         goto fail;
 
     if (data.dsize != sizeof(struct entry)) {
-        pa_log_warn("Database contains entry for stream %s of wrong size %lu != %lu", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry));
+        /* This is probably just a database upgrade, hence let's not
+         * consider this more than a debug message */
+        pa_log_debug("Database contains entry for stream %s of wrong size %lu != %lu", name, (unsigned long) data.dsize, (unsigned long) sizeof(struct entry));
         goto fail;
     }
 
@@ -164,18 +168,19 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
         goto fail;
     }
 
-    if (!(pa_cvolume_valid(&e->volume))) {
-        pa_log_warn("Invalid volume stored in database for stream %s", name);
+    if (!(pa_channel_map_valid(&e->channel_map))) {
+        pa_log_warn("Invalid channel map stored in database for stream %s", name);
         goto fail;
     }
 
-    if (!(pa_channel_map_valid(&e->channel_map))) {
-        pa_log_warn("Invalid channel map stored in database for stream %s", name);
+    if (e->device_valid && !pa_namereg_is_valid_name(e->device)) {
+        pa_log_warn("Invalid device name stored in database for stream %s", name);
         goto fail;
     }
 
-    if (e->volume.channels != e->channel_map.channels) {
-        pa_log_warn("Volume and channel map don't match in database entry for stream %s", name);
+    if ((e->relative_volume_valid && (!pa_cvolume_valid(&e->relative_volume) || e->relative_volume.channels != e->channel_map.channels)) ||
+        (e->absolute_volume_valid && (!pa_cvolume_valid(&e->absolute_volume) || e->absolute_volume.channels != e->channel_map.channels))) {
+        pa_log_warn("Invalid volume stored in database for stream %s", name);
         goto fail;
     }
 
@@ -213,6 +218,33 @@ static void trigger_save(struct userdata *u) {
     u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u);
 }
 
+static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
+    pa_cvolume t;
+
+    pa_assert(a);
+    pa_assert(b);
+
+    if (a->device_valid != b->device_valid ||
+        (a->device_valid && strncmp(a->device, b->device, sizeof(a->device))))
+        return FALSE;
+
+    if (a->muted_valid != b->muted_valid ||
+        (a->muted && (a->muted != b->muted)))
+        return FALSE;
+
+    t = b->relative_volume;
+    if (a->relative_volume_valid != b->relative_volume_valid ||
+        (a->relative_volume_valid && !pa_cvolume_equal(pa_cvolume_remap(&t, &b->channel_map, &a->channel_map), &a->relative_volume)))
+        return FALSE;
+
+    t = b->absolute_volume;
+    if (a->absolute_volume_valid != b->absolute_volume_valid ||
+        (a->absolute_volume_valid && !pa_cvolume_equal(pa_cvolume_remap(&t, &b->channel_map, &a->channel_map), &a->absolute_volume)))
+        return FALSE;
+
+    return TRUE;
+}
+
 static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
     struct userdata *u = userdata;
     struct entry entry, *old;
@@ -240,9 +272,23 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
             return;
 
         entry.channel_map = sink_input->channel_map;
-        entry.volume = *pa_sink_input_get_volume(sink_input);
+
+        if (sink_input->sink->flags & PA_SINK_FLAT_VOLUME) {
+            entry.absolute_volume = *pa_sink_input_get_volume(sink_input);
+            entry.absolute_volume_valid = sink_input->save_volume;
+
+            pa_sw_cvolume_divide(&entry.relative_volume, &entry.absolute_volume, pa_sink_get_volume(sink_input->sink, FALSE));
+            entry.relative_volume_valid = sink_input->save_volume;
+        } else {
+            entry.relative_volume = *pa_sink_input_get_volume(sink_input);
+            entry.relative_volume_valid = sink_input->save_volume;
+        }
+
         entry.muted = pa_sink_input_get_mute(sink_input);
+        entry.muted_valid = sink_input->save_muted;
+
         pa_strlcpy(entry.device, sink_input->sink->name, sizeof(entry.device));
+        entry.device_valid = sink_input->save_sink;
 
     } else {
         pa_source_output *source_output;
@@ -255,19 +301,15 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
         if (!(name = get_name(source_output->proplist, "source-output")))
             return;
 
-        /* The following fields are filled in to make the entry valid
-         * according to read_entry(). They are otherwise useless */
         entry.channel_map = source_output->channel_map;
-        pa_cvolume_reset(&entry.volume, entry.channel_map.channels);
+
         pa_strlcpy(entry.device, source_output->source->name, sizeof(entry.device));
+        entry.device_valid = source_output->save_source;
     }
 
     if ((old = read_entry(u, name))) {
 
-        if (pa_cvolume_equal(pa_cvolume_remap(&old->volume, &old->channel_map, &entry.channel_map), &entry.volume) &&
-            !old->muted == !entry.muted &&
-            strncmp(old->device, entry.device, sizeof(entry.device)) == 0) {
-
+        if (entries_equal(old, &entry)) {
             pa_xfree(old);
             pa_xfree(name);
             return;
@@ -297,20 +339,25 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
 
     pa_assert(new_data);
 
+    if (!u->restore_device)
+        return PA_HOOK_OK;
+
     if (!(name = get_name(new_data->proplist, "sink-input")))
         return PA_HOOK_OK;
 
     if ((e = read_entry(u, name))) {
         pa_sink *s;
 
-        if (u->restore_device &&
-            (s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK))) {
+        if (e->device_valid) {
 
-            if (!new_data->sink) {
-                pa_log_info("Restoring device for stream %s.", name);
-                new_data->sink = s;
-            } else
-                pa_log_info("Not restore device for stream %s, because already set.", name);
+            if ((s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK))) {
+                if (!new_data->sink) {
+                    pa_log_info("Restoring device for stream %s.", name);
+                    new_data->sink = s;
+                    new_data->save_sink = TRUE;
+                } else
+                    pa_log_info("Not restore device for stream %s, because already set.", name);
+            }
         }
 
         pa_xfree(e);
@@ -327,6 +374,9 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
 
     pa_assert(new_data);
 
+    if (!u->restore_volume && !u->restore_muted)
+        return PA_HOOK_OK;
+
     if (!(name = get_name(new_data->proplist, "sink-input")))
         return PA_HOOK_OK;
 
@@ -335,16 +385,37 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
         if (u->restore_volume) {
 
             if (!new_data->virtual_volume_is_set) {
-                pa_log_info("Restoring volume for sink input %s.", name);
-                pa_sink_input_new_data_set_virtual_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
+                pa_cvolume v;
+                pa_cvolume_init(&v);
+
+                if (new_data->sink->flags & PA_SINK_FLAT_VOLUME) {
+
+                    if (e->absolute_volume_valid &&
+                        e->device_valid &&
+                        pa_streq(new_data->sink->name, e->device))
+                        v = e->absolute_volume;
+                    else if (e->relative_volume_valid) {
+                        pa_cvolume t = new_data->sink->virtual_volume;
+                        pa_sw_cvolume_multiply(&v, &e->relative_volume, pa_cvolume_remap(&t, &new_data->sink->channel_map, &e->channel_map));
+                    }
+
+                } else if (e->relative_volume_valid)
+                    v = e->relative_volume;
+
+                if (v.channels > 0) {
+                    pa_log_info("Restoring volume for sink input %s.", name);
+                    pa_sink_input_new_data_set_virtual_volume(new_data, pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map));
+                    new_data->save_volume = TRUE;
+                }
             } else
                 pa_log_debug("Not restoring volume for sink input %s, because already set.", name);
         }
 
-        if (u->restore_muted) {
+        if (u->restore_muted && e->muted_valid) {
             if (!new_data->muted_is_set) {
                 pa_log_info("Restoring mute state for sink input %s.", name);
                 pa_sink_input_new_data_set_muted(new_data, e->muted);
+                new_data->save_muted = TRUE;
             } else
                 pa_log_debug("Not restoring mute state for sink input %s, because already set.", name);
         }
@@ -363,21 +434,27 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
 
     pa_assert(new_data);
 
+    if (!u->restore_device)
+        return PA_HOOK_OK;
+
+    if (new_data->direct_on_input)
+        return PA_HOOK_OK;
+
     if (!(name = get_name(new_data->proplist, "source-output")))
         return PA_HOOK_OK;
 
     if ((e = read_entry(u, name))) {
         pa_source *s;
 
-        if (u->restore_device &&
-            !new_data->direct_on_input &&
-            (s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE))) {
-
-            if (!new_data->source) {
-                pa_log_info("Restoring device for stream %s.", name);
-                new_data->source = s;
-            } else
-                pa_log_info("Not restoring device for stream %s, because already set", name);
+        if (e->device_valid) {
+            if ((s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE))) {
+                if (!new_data->source) {
+                    pa_log_info("Restoring device for stream %s.", name);
+                    new_data->source = s;
+                    new_data->save_source = TRUE;
+                } else
+                    pa_log_info("Not restoring device for stream %s, because already set", name);
+            }
         }
 
         pa_xfree(e);
@@ -431,18 +508,37 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
         }
 
         if (u->restore_volume) {
-            pa_cvolume v = e->volume;
-            pa_log_info("Restoring volume for sink input %s.", name);
-            pa_sink_input_set_volume(si, pa_cvolume_remap(&v, &e->channel_map, &si->channel_map));
+            pa_cvolume v;
+            pa_cvolume_init(&v);
+
+            if (si->sink->flags & PA_SINK_FLAT_VOLUME) {
+
+                if (e->absolute_volume_valid &&
+                    e->device_valid &&
+                    pa_streq(e->device, si->sink->name))
+                    v = e->absolute_volume;
+                else if (e->relative_volume_valid) {
+                    pa_cvolume t = si->sink->virtual_volume;
+                    pa_sw_cvolume_multiply(&v, &e->relative_volume, pa_cvolume_remap(&t, &si->sink->channel_map, &e->channel_map));
+                }
+            } else if (e->relative_volume_valid)
+                v = e->relative_volume;
+
+            if (v.channels > 0) {
+                pa_log_info("Restoring volume for sink input %s.", name);
+                pa_sink_input_set_volume(si, pa_cvolume_remap(&v, &e->channel_map, &si->channel_map), TRUE);
+            }
         }
 
-        if (u->restore_muted) {
+        if (u->restore_muted &&
+            e->muted_valid) {
             pa_log_info("Restoring mute state for sink input %s.", name);
             pa_sink_input_set_mute(si, e->muted, TRUE);
         }
 
         if (u->restore_device &&
-            (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
+            e->device_valid &&
+            (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SINK))) {
 
             pa_log_info("Restoring device for stream %s.", name);
             pa_sink_input_move_to(si, s, TRUE);
@@ -462,6 +558,7 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
         }
 
         if (u->restore_device &&
+            e->device_valid &&
             (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
 
             pa_log_info("Restoring device for stream %s.", name);
@@ -548,11 +645,13 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                 pa_xfree(key.dptr);
 
                 if ((e = read_entry(u, name))) {
+                    pa_cvolume r;
+
                     pa_tagstruct_puts(reply, name);
                     pa_tagstruct_put_channel_map(reply, &e->channel_map);
-                    pa_tagstruct_put_cvolume(reply, &e->volume);
-                    pa_tagstruct_puts(reply, e->device);
-                    pa_tagstruct_put_boolean(reply, e->muted);
+                    pa_tagstruct_put_cvolume(reply, e->relative_volume_valid ? &e->relative_volume : pa_cvolume_init(&r));
+                    pa_tagstruct_puts(reply, e->device_valid ? e->device : NULL);
+                    pa_tagstruct_put_boolean(reply, e->muted_valid ? e->muted : FALSE);
 
                     pa_xfree(e);
                 }
@@ -592,16 +691,28 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
 
                 if (pa_tagstruct_gets(t, &name) < 0 ||
                     pa_tagstruct_get_channel_map(t, &entry.channel_map) ||
-                    pa_tagstruct_get_cvolume(t, &entry.volume) < 0 ||
+                    pa_tagstruct_get_cvolume(t, &entry.relative_volume) < 0 ||
                     pa_tagstruct_gets(t, &device) < 0 ||
                     pa_tagstruct_get_boolean(t, &muted) < 0)
                     goto fail;
 
-                if (entry.channel_map.channels != entry.volume.channels)
+                entry.absolute_volume_valid = FALSE;
+                entry.relative_volume_valid = entry.relative_volume.channels > 0;
+
+                if (entry.relative_volume_valid &&
+                    entry.channel_map.channels != entry.relative_volume.channels)
                     goto fail;
 
                 entry.muted = muted;
-                pa_strlcpy(entry.device, device, sizeof(entry.device));
+                entry.muted_valid = TRUE;
+
+                if (device)
+                    pa_strlcpy(entry.device, device, sizeof(entry.device));
+                entry.device_valid = !!entry.device[0];
+
+                if (entry.device_valid &&
+                    !pa_namereg_is_valid_name(entry.device))
+                    goto fail;
 
                 key.dptr = (void*) name;
                 key.dsize = (int) strlen(name);

-- 
hooks/post-receive
PulseAudio Sound Server



More information about the pulseaudio-commits mailing list