And don't move the stream in the module-stream-restore anymore, And the preferred_sink is only set when user is calling the move_to() and the module-stream-restore maintains the saving and deleting of preferred_sink. If the target of move_to() is default_sink, preferred_sink will be cleared and the entry->device will be cleared too from database. Signed-off-by: Hui Wang <hui.wang@xxxxxxxxxxxxx> --- src/modules/module-device-manager.c | 2 +- src/modules/module-intended-roles.c | 2 +- src/modules/module-stream-restore.c | 47 +++++++++++++++++--------- src/modules/module-switch-on-connect.c | 2 +- src/pulsecore/sink-input.c | 25 +++++++++++--- src/pulsecore/sink-input.h | 7 ++-- 6 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c index 15fdaaaa2..36e71584e 100644 --- a/src/modules/module-device-manager.c +++ b/src/modules/module-device-manager.c @@ -657,7 +657,7 @@ static void route_sink_input(struct userdata *u, pa_sink_input *si) { pa_assert(u->do_routing); /* Don't override user or application routing requests. */ - if (si->save_sink || si->sink_requested_by_application) + if (si->preferred_sink != NULL || si->sink_requested_by_application) return; /* Skip this if it is already in the process of being moved anyway */ diff --git a/src/modules/module-intended-roles.c b/src/modules/module-intended-roles.c index adee51c20..98e4c241f 100644 --- a/src/modules/module-intended-roles.c +++ b/src/modules/module-intended-roles.c @@ -175,7 +175,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct if (si->sink == sink) continue; - if (si->save_sink) + if (si->preferred_sink != NULL) continue; /* Skip this if it is already in the process of being moved diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index 228e9e447..276957c25 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -1311,19 +1311,29 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted); } - if (sink_input->save_sink) { + if (sink_input->preferred_sink != NULL || !created_new_entry) { pa_xfree(entry->device); - entry->device = pa_xstrdup(sink_input->sink->name); - entry->device_valid = true; - device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device)); - if (sink_input->sink->card) { + if (sink_input->preferred_sink != NULL) { + entry->device = pa_xstrdup(sink_input->preferred_sink); + entry->device_valid = true; + } else { + entry->device = NULL; + entry->device_valid = false; + } + + device_updated = !created_new_entry && (!old->device_valid || !entry->device_valid || !pa_streq(entry->device, old->device)); + + if (entry->device_valid == false) { + pa_xfree(entry->card); + entry->card = NULL; + entry->card_valid = false; + } else if (sink_input->sink->card) { pa_xfree(entry->card); entry->card = pa_xstrdup(sink_input->sink->card->name); entry->card_valid = true; } } - } else { pa_source_output *source_output; @@ -1641,7 +1651,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct if (si->sink == sink) continue; - if (si->save_sink) + if (si->preferred_sink != NULL) continue; /* Skip this if it is already in the process of being moved @@ -1665,7 +1675,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct if ((e = entry_read(u, name))) { if (e->device_valid && pa_streq(e->device, sink->name)) - pa_sink_input_move_to(si, sink, true); + si->preferred_sink = pa_xstrdup(sink->name); entry_free(e); } @@ -1764,8 +1774,10 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str if ((d = pa_namereg_get(c, e->device, PA_NAMEREG_SINK)) && d != sink && - PA_SINK_IS_LINKED(d->state)) - pa_sink_input_move_to(si, d, true); + PA_SINK_IS_LINKED(d->state)) { + pa_xfree(si->preferred_sink); + si->preferred_sink = pa_xstrdup(d->name); + } } entry_free(e); @@ -1942,12 +1954,13 @@ static void entry_apply(struct userdata *u, const char *name, struct entry *e) { if (u->restore_device) { if (!e->device_valid) { - if (si->save_sink) { + if (si->preferred_sink != NULL) { pa_log_info("Ensuring device is not saved for stream %s.", name); /* If the device is not valid we should make sure the save flag is cleared as the user may have specifically removed the sink element from the rule. */ - si->save_sink = false; + pa_xfree(si->preferred_sink); + si->preferred_sink = NULL; /* This is cheating a bit. The sink input itself has not changed but the rules governing its routing have, so we fire this event such that other routing modules (e.g. module-device-manager) @@ -1956,7 +1969,8 @@ static void entry_apply(struct userdata *u, const char *name, struct entry *e) { } } else if ((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); + pa_xfree(si->preferred_sink); + si->preferred_sink = pa_xstrdup(s->name); } } } @@ -2176,9 +2190,10 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio entry->muted = muted; entry->muted_valid = true; - - entry->device = pa_xstrdup(device); - entry->device_valid = device && !!entry->device[0]; + if (device && !pa_streq(device, m->core->default_sink->name) && !pa_streq(device, m->core->default_source->name)) { + entry->device = pa_xstrdup(device); + entry->device_valid = device && !!entry->device[0]; + } if (entry->device_valid && !pa_namereg_is_valid_name(entry->device)) { entry_free(entry); diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c index ebdd6aad0..faa0f289f 100644 --- a/src/modules/module-switch-on-connect.c +++ b/src/modules/module-switch-on-connect.c @@ -112,7 +112,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* } PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) { - if (i->save_sink || !PA_SINK_INPUT_IS_LINKED(i->state)) + if (i->preferred_sink != NULL || !PA_SINK_INPUT_IS_LINKED(i->state)) continue; if (pa_sink_input_move_to(i, sink, false) < 0) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 312ec4a97..1031051a7 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -190,7 +190,8 @@ bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, b if (!data->req_formats) { /* We're not working with the extended API */ data->sink = s; - data->save_sink = save; + if (save) + data->preferred_sink = pa_xstrdup(s->name); data->sink_requested_by_application = requested_by_application; } else { /* Extended API: let's see if this sink supports the formats the client can provide */ @@ -199,7 +200,8 @@ bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, b if (formats && !pa_idxset_isempty(formats)) { /* Sink supports at least one of the requested formats */ data->sink = s; - data->save_sink = save; + if (save) + data->preferred_sink = pa_xstrdup(s->name); data->sink_requested_by_application = requested_by_application; if (data->nego_formats) pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free); @@ -226,7 +228,7 @@ bool pa_sink_input_new_data_set_formats(pa_sink_input_new_data *data, pa_idxset if (data->sink) { /* Trigger format negotiation */ - return pa_sink_input_new_data_set_sink(data, data->sink, data->save_sink, data->sink_requested_by_application); + return pa_sink_input_new_data_set_sink(data, data->sink, false, data->sink_requested_by_application); } return true; @@ -519,7 +521,7 @@ int pa_sink_input_new( pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels); i->volume_writable = data->volume_writable; i->save_volume = data->save_volume; - i->save_sink = data->save_sink; + i->preferred_sink = pa_xstrdup(data->preferred_sink); i->save_muted = data->save_muted; i->muted = data->muted; @@ -777,6 +779,9 @@ static void sink_input_free(pa_object *o) { if (i->volume_factor_sink_items) pa_hashmap_free(i->volume_factor_sink_items); + if (i->preferred_sink) + pa_xfree(i->preferred_sink); + pa_xfree(i->driver); pa_xfree(i); } @@ -1914,7 +1919,17 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, bool save) { i->moving(i, dest); i->sink = dest; - i->save_sink = save; + + /* save == true, means user is calling the move_to() and want to + save the preferred_sinke if the sink is not default_sink */ + if (save) { + pa_xfree(i->preferred_sink); + if (dest == dest->core->default_sink) + i->preferred_sink = NULL; + else + i->preferred_sink = pa_xstrdup(dest->name); + } + pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL); PA_HASHMAP_FOREACH(v, i->volume_factor_sink_items, state) diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 9e90291ca..537cec9a1 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -123,7 +123,8 @@ struct pa_sink_input { * set is worth remembering, i.e. was explicitly chosen by the * user and not automatically. module-stream-restore looks for * this.*/ - bool save_sink:1, save_volume:1, save_muted:1; + char *preferred_sink; + bool save_volume:1, save_muted:1; pa_resample_method_t requested_resample_method, actual_resample_method; @@ -300,6 +301,8 @@ typedef struct pa_sink_input_new_data { pa_idxset *req_formats; pa_idxset *nego_formats; + char *preferred_sink; + pa_cvolume volume; bool muted:1; pa_hashmap *volume_factor_items, *volume_factor_sink_items; @@ -314,7 +317,7 @@ typedef struct pa_sink_input_new_data { bool volume_writable:1; - bool save_sink:1, save_volume:1, save_muted:1; + bool 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); -- 2.17.1 _______________________________________________ pulseaudio-discuss mailing list pulseaudio-discuss@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss