summaryrefslogtreecommitdiffstats
path: root/src/modules/module-stream-restore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/module-stream-restore.c')
-rw-r--r--src/modules/module-stream-restore.c59
1 files changed, 40 insertions, 19 deletions
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index ec4e7c79..55897004 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -134,7 +134,7 @@ static char *get_name(pa_proplist *p, const char *prefix) {
else if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_NAME)))
return pa_sprintf_malloc("%s-by-media-name:%s", prefix, r);
- return NULL;
+ return pa_sprintf_malloc("%s-fallback:%s", prefix, r);
}
static struct entry* read_entry(struct userdata *u, char *name) {
@@ -145,7 +145,7 @@ static struct entry* read_entry(struct userdata *u, char *name) {
pa_assert(name);
key.dptr = name;
- key.dsize = strlen(name);
+ key.dsize = (int) strlen(name);
data = gdbm_fetch(u->gdbm_file, key);
@@ -277,7 +277,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
}
key.dptr = name;
- key.dsize = strlen(name);
+ key.dsize = (int) strlen(name);
data.dptr = (void*) &entry;
data.dsize = sizeof(entry);
@@ -306,8 +306,11 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
if (u->restore_device &&
(s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK, TRUE))) {
- pa_log_info("Restoring device for stream %s.", name);
- new_data->sink = s;
+ 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);
}
pa_xfree(e);
@@ -330,13 +333,20 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
if ((e = read_entry(u, name))) {
if (u->restore_volume) {
- pa_log_info("Restoring volume for sink input %s.", name);
- pa_sink_input_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
+
+ if (!new_data->volume_is_set) {
+ pa_log_info("Restoring volume for sink input %s.", name);
+ pa_sink_input_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
+ } else
+ pa_log_debug("Not restoring volume for sink input %s, because already set.", name);
}
if (u->restore_muted) {
- pa_log_info("Restoring mute state for sink input %s.", name);
- pa_sink_input_new_data_set_muted(new_data, e->muted);
+ 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);
+ } else
+ pa_log_debug("Not restoring mute state for sink input %s, because already set.", name);
}
pa_xfree(e);
@@ -360,10 +370,14 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
pa_source *s;
if (u->restore_device &&
+ !new_data->direct_on_input &&
(s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE, TRUE))) {
- pa_log_info("Restoring device for stream %s.", name);
- new_data->source = s;
+ 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);
}
pa_xfree(e);
@@ -408,7 +422,7 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
char *n;
pa_sink *s;
- if (!(n = get_name(si->proplist, "sink_input")))
+ if (!(n = get_name(si->proplist, "sink-input")))
continue;
if (strcmp(name, n)) {
@@ -417,8 +431,9 @@ 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(&e->volume, &e->channel_map, &si->channel_map));
+ pa_sink_input_set_volume(si, pa_cvolume_remap(&v, &e->channel_map, &si->channel_map));
}
if (u->restore_muted) {
@@ -490,7 +505,7 @@ static void dump_database(struct userdata *u) {
static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
struct userdata *u;
uint32_t command;
- pa_tagstruct *reply;
+ pa_tagstruct *reply = NULL;
pa_assert(p);
pa_assert(m);
@@ -529,7 +544,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
next_key = gdbm_nextkey(u->gdbm_file, key);
- name = pa_xstrndup(key.dptr, key.dsize);
+ name = pa_xstrndup(key.dptr, (size_t) key.dsize);
pa_xfree(key.dptr);
if ((e = read_entry(u, name))) {
@@ -552,7 +567,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
case SUBCOMMAND_WRITE: {
uint32_t mode;
- pa_bool_t apply_immediately;
+ pa_bool_t apply_immediately = FALSE;
if (pa_tagstruct_getu32(t, &mode) < 0 ||
pa_tagstruct_get_boolean(t, &apply_immediately) < 0)
@@ -571,6 +586,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
pa_bool_t muted;
struct entry entry;
datum key, data;
+ int k;
memset(&entry, 0, sizeof(entry));
@@ -588,12 +604,12 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
pa_strlcpy(entry.device, device, sizeof(entry.device));
key.dptr = (void*) name;
- key.dsize = strlen(name);
+ key.dsize = (int) strlen(name);
data.dptr = (void*) &entry;
data.dsize = sizeof(entry);
- if (gdbm_store(u->gdbm_file, key, data, mode == PA_UPDATE_REPLACE ? GDBM_REPLACE : GDBM_INSERT) == 1)
+ if ((k = gdbm_store(u->gdbm_file, key, data, mode == PA_UPDATE_REPLACE ? GDBM_REPLACE : GDBM_INSERT)) == 0)
if (apply_immediately)
apply_entry(u, name, &entry);
}
@@ -613,7 +629,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
goto fail;
key.dptr = (void*) name;
- key.dsize = strlen(name);
+ key.dsize = (int) strlen(name);
gdbm_delete(u->gdbm_file, key);
}
@@ -670,6 +686,7 @@ int pa__init(pa_module*m) {
pa_source_output *so;
uint32_t idx;
pa_bool_t restore_device = TRUE, restore_volume = TRUE, restore_muted = TRUE;
+ int gdbm_cache_size;
pa_assert(m);
@@ -730,6 +747,10 @@ int pa__init(pa_module*m) {
goto fail;
}
+ /* By default the cache of gdbm is rather large, let's reduce it a bit to save memory */
+ gdbm_cache_size = 10;
+ gdbm_setopt(u->gdbm_file, GDBM_CACHESIZE, &gdbm_cache_size, sizeof(gdbm_cache_size));
+
pa_log_info("Sucessfully opened database file '%s'.", fname);
pa_xfree(fname);