pa_source_output_new_data_init(&source_output_data);
source_output_data.driver = __FILE__;
source_output_data.module = m;
- pa_source_output_new_data_set_source(&source_output_data, source_master, false);
+ pa_source_output_new_data_set_source(&source_output_data, source_master, false, true);
source_output_data.destination_source = u->source;
pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Source Stream");
pa_sink_input_new_data_init(&sink_input_data);
sink_input_data.driver = __FILE__;
sink_input_data.module = m;
- pa_sink_input_new_data_set_sink(&sink_input_data, sink_master, false);
+ pa_sink_input_new_data_set_sink(&sink_input_data, sink_master, false, true);
sink_input_data.origin_sink = u->sink;
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Sink Stream");
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
if (!new_data->sink) {
pa_sink *sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
pa_return_val_if_fail(sink, -PA_ERR_NOENTITY);
- pa_sink_input_new_data_set_sink(new_data, sink, false);
+ pa_sink_input_new_data_set_sink(new_data, sink, false, false);
}
if (!new_data->format && new_data->nego_formats && !pa_idxset_isempty(new_data->nego_formats))
if (null_sink) {
pa_log_info("Already playing a passthrough stream; re-routing new stream to the null sink");
- pa_sink_input_new_data_set_sink(new_data, null_sink, false);
+ pa_sink_input_new_data_set_sink(new_data, null_sink, false, false);
}
return PA_HOOK_OK;
u = o->userdata;
pa_sink_input_new_data_init(&data);
- pa_sink_input_new_data_set_sink(&data, o->sink, false);
+ pa_sink_input_new_data_set_sink(&data, o->sink, false, true);
data.driver = __FILE__;
pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME, "Simultaneous output on %s", pa_strnull(pa_proplist_gets(o->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "filter");
pa_sink *sink;
if ((sink = pa_idxset_get_by_index(u->core->sinks, device_index))) {
- if (!pa_sink_input_new_data_set_sink(new_data, sink, false))
+ if (!pa_sink_input_new_data_set_sink(new_data, sink, false, false))
pa_log_debug("Not restoring device for stream because no supported format was found");
}
}
pa_source *source;
if ((source = pa_idxset_get_by_index(u->core->sources, device_index)))
- if (!pa_source_output_new_data_set_source(new_data, source, false))
+ if (!pa_source_output_new_data_set_source(new_data, source, false, false))
pa_log_debug("Not restoring device for stream because no supported format was found");
}
}
pa_sink_input_new_data_init(&sink_input_data);
sink_input_data.driver = __FILE__;
sink_input_data.module = m;
- pa_sink_input_new_data_set_sink(&sink_input_data, master, false);
+ pa_sink_input_new_data_set_sink(&sink_input_data, master, false, true);
sink_input_data.origin_sink = u->sink;
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Equalized Stream");
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
/* Prefer the default sink over any other sink, just in case... */
if (c->default_sink)
- if (role_match(c->default_sink->proplist, role) && pa_sink_input_new_data_set_sink(new_data, c->default_sink, false))
+ if (role_match(c->default_sink->proplist, role) && pa_sink_input_new_data_set_sink(new_data, c->default_sink, false, false))
return PA_HOOK_OK;
/* @todo: favour the highest priority device, not the first one we find? */
if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)))
continue;
- if (role_match(s->proplist, role) && pa_sink_input_new_data_set_sink(new_data, s, false))
+ if (role_match(s->proplist, role) && pa_sink_input_new_data_set_sink(new_data, s, false, false))
return PA_HOOK_OK;
}
/* Prefer the default source over any other source, just in case... */
if (c->default_source)
if (role_match(c->default_source->proplist, role)) {
- pa_source_output_new_data_set_source(new_data, c->default_source, false);
+ pa_source_output_new_data_set_source(new_data, c->default_source, false, false);
return PA_HOOK_OK;
}
/* @todo: favour the highest priority device, not the first one we find? */
if (role_match(s->proplist, role)) {
- pa_source_output_new_data_set_source(new_data, s, false);
+ pa_source_output_new_data_set_source(new_data, s, false, false);
return PA_HOOK_OK;
}
}
pa_sink_input_new_data_init(&sink_input_data);
sink_input_data.driver = __FILE__;
sink_input_data.module = m;
- pa_sink_input_new_data_set_sink(&sink_input_data, master, false);
+ pa_sink_input_new_data_set_sink(&sink_input_data, master, false, true);
sink_input_data.origin_sink = u->sink;
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "LADSPA Stream");
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
sink_input_data.module = m;
if (sink)
- pa_sink_input_new_data_set_sink(&sink_input_data, sink, false);
+ pa_sink_input_new_data_set_sink(&sink_input_data, sink, false, true);
if (pa_modargs_get_proplist(ma, "sink_input_properties", sink_input_data.proplist, PA_UPDATE_REPLACE) < 0) {
pa_log("Failed to parse the sink_input_properties value.");
source_output_data.driver = __FILE__;
source_output_data.module = m;
if (source)
- pa_source_output_new_data_set_source(&source_output_data, source, false);
+ pa_source_output_new_data_set_source(&source_output_data, source, false, true);
if (pa_modargs_get_proplist(ma, "source_output_properties", source_output_data.proplist, PA_UPDATE_REPLACE) < 0) {
pa_log("Failed to parse the source_output_properties value.");
pa_sink_input_new_data_init(&sink_input_data);
sink_input_data.driver = __FILE__;
sink_input_data.module = m;
- pa_sink_input_new_data_set_sink(&sink_input_data, master, false);
+ pa_sink_input_new_data_set_sink(&sink_input_data, master, false, true);
sink_input_data.origin_sink = u->sink;
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Remapped Stream");
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
pa_source_output_new_data_init(&source_output_data);
source_output_data.driver = __FILE__;
source_output_data.module = m;
- pa_source_output_new_data_set_source(&source_output_data, master, false);
+ pa_source_output_new_data_set_source(&source_output_data, master, false, true);
source_output_data.destination_source = u->source;
pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Remapped Stream");
pa_sink_input_new_data_init(&data);
data.driver = __FILE__;
data.module = m;
- pa_sink_input_new_data_set_sink(&data, sink, false);
+ pa_sink_input_new_data_set_sink(&data, sink, false, true);
pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME, "%u Hz Sine", frequency);
pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
pa_proplist_setf(data.proplist, "sine.hz", "%u", frequency);
same time, in which case we want to make sure we don't
interfere with that */
if (s && PA_SINK_IS_LINKED(pa_sink_get_state(s)))
- if (pa_sink_input_new_data_set_sink(new_data, s, true))
+ if (pa_sink_input_new_data_set_sink(new_data, s, true, false))
pa_log_info("Restoring device for stream %s.", name);
entry_free(e);
interfere with that */
if (s && PA_SOURCE_IS_LINKED(pa_source_get_state(s))) {
pa_log_info("Restoring device for stream %s.", name);
- pa_source_output_new_data_set_source(new_data, s, true);
+ pa_source_output_new_data_set_source(new_data, s, true, false);
}
entry_free(e);
pa_sink_input_new_data_init(&sink_input_data);
sink_input_data.driver = __FILE__;
sink_input_data.module = m;
- pa_sink_input_new_data_set_sink(&sink_input_data, master, false);
+ pa_sink_input_new_data_set_sink(&sink_input_data, master, false, true);
sink_input_data.origin_sink = u->sink;
pa_proplist_setf(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Sink Stream from %s", pa_proplist_gets(u->sink->proplist, PA_PROP_DEVICE_DESCRIPTION));
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
pa_source_output_new_data_init(&source_output_data);
source_output_data.driver = __FILE__;
source_output_data.module = m;
- pa_source_output_new_data_set_source(&source_output_data, master, false);
+ pa_source_output_new_data_set_source(&source_output_data, master, false, true);
source_output_data.destination_source = u->source;
pa_proplist_setf(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Source Stream of %s", pa_proplist_gets(u->source->proplist, PA_PROP_DEVICE_DESCRIPTION));
pa_sink_input_new_data_init(&sink_input_data);
sink_input_data.driver = __FILE__;
sink_input_data.module = m;
- pa_sink_input_new_data_set_sink(&sink_input_data, master, false);
+ pa_sink_input_new_data_set_sink(&sink_input_data, master, false, true);
sink_input_data.origin_sink = u->sink;
pa_proplist_setf(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Surround Sink Stream from %s", pa_proplist_gets(u->sink->proplist, PA_PROP_DEVICE_DESCRIPTION));
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
goto fail;
pa_sink_input_new_data_init(&data);
- pa_sink_input_new_data_set_sink(&data, sink, false);
+ pa_sink_input_new_data_set_sink(&data, sink, false, true);
data.driver = __FILE__;
pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "stream");
pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME,
pa_proplist_setf(data.proplist, "rtp.ttl", "%lu", (unsigned long) ttl);
data.driver = __FILE__;
data.module = m;
- pa_source_output_new_data_set_source(&data, s, false);
+ pa_source_output_new_data_set_source(&data, s, false, true);
pa_source_output_new_data_set_sample_spec(&data, &ss);
pa_source_output_new_data_set_channel_map(&data, &cm);
data.flags |= get_dont_inhibit_auto_suspend_flag(s, inhibit_auto_suspend);
u->memblockq = NULL;
pa_sink_input_new_data_init(&data);
- pa_sink_input_new_data_set_sink(&data, sink, false);
+ pa_sink_input_new_data_set_sink(&data, sink, false, true);
data.driver = __FILE__;
pa_sink_input_new_data_set_sample_spec(&data, ss);
pa_sink_input_new_data_set_channel_map(&data, map);
sdata.module = c->options->module;
sdata.client = c->client;
if (sink)
- pa_sink_input_new_data_set_sink(&sdata, sink, false);
+ pa_sink_input_new_data_set_sink(&sdata, sink, false, true);
pa_sink_input_new_data_set_sample_spec(&sdata, &ss);
pa_sink_input_new(&c->sink_input, c->protocol->core, &sdata);
sdata.module = c->options->module;
sdata.client = c->client;
if (source)
- pa_source_output_new_data_set_source(&sdata, source, false);
+ pa_source_output_new_data_set_source(&sdata, source, false, true);
pa_source_output_new_data_set_sample_spec(&sdata, &ss);
pa_source_output_new(&c->source_output, c->protocol->core, &sdata);
data.driver = __FILE__;
data.module = c->module;
data.client = c->client;
- pa_source_output_new_data_set_source(&data, source, false);
+ pa_source_output_new_data_set_source(&data, source, false, true);
pa_proplist_update(data.proplist, PA_UPDATE_MERGE, c->client->proplist);
pa_source_output_new_data_set_sample_spec(&data, &ss);
pa_source_output_new_data_set_channel_map(&data, &cm);
data.module = c->options->module;
data.client = c->client;
if (source)
- pa_source_output_new_data_set_source(&data, source, false);
+ pa_source_output_new_data_set_source(&data, source, false, true);
if (pa_sample_spec_valid(ss))
pa_source_output_new_data_set_sample_spec(&data, ss);
if (pa_channel_map_valid(map))
data.module = c->options->module;
data.client = c->client;
if (sink)
- pa_sink_input_new_data_set_sink(&data, sink, false);
+ pa_sink_input_new_data_set_sink(&data, sink, false, true);
if (pa_sample_spec_valid(ss))
pa_sink_input_new_data_set_sample_spec(&data, ss);
if (pa_channel_map_valid(map))
data.driver = __FILE__;
data.module = o->module;
data.client = c->client;
- pa_sink_input_new_data_set_sink(&data, sink, false);
+ pa_sink_input_new_data_set_sink(&data, sink, false, true);
pa_proplist_update(data.proplist, PA_UPDATE_MERGE, c->client->proplist);
pa_sink_input_new_data_set_sample_spec(&data, &o->sample_spec);
data.driver = __FILE__;
data.module = o->module;
data.client = c->client;
- pa_source_output_new_data_set_source(&data, source, false);
+ pa_source_output_new_data_set_source(&data, source, false, true);
pa_proplist_update(data.proplist, PA_UPDATE_MERGE, c->client->proplist);
pa_source_output_new_data_set_sample_spec(&data, &o->sample_spec);
data->muted = mute;
}
-bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, bool save) {
+bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, bool save, bool requested_by_application) {
bool ret = true;
pa_idxset *formats = NULL;
/* We're not working with the extended API */
data->sink = s;
data->save_sink = save;
+ data->sink_requested_by_application = requested_by_application;
} else {
/* Extended API: let's see if this sink supports the formats the client can provide */
formats = pa_sink_check_formats(s, data->req_formats);
/* Sink supports at least one of the requested formats */
data->sink = s;
data->save_sink = save;
+ 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);
data->nego_formats = formats;
if (data->sink) {
/* Trigger format negotiation */
- return pa_sink_input_new_data_set_sink(data, data->sink, data->save_sink);
+ return pa_sink_input_new_data_set_sink(data, data->sink, data->save_sink, data->sink_requested_by_application);
}
return true;
if (!data->sink) {
pa_sink *sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
pa_return_val_if_fail(sink, -PA_ERR_NOENTITY);
- pa_sink_input_new_data_set_sink(data, sink, false);
+ pa_sink_input_new_data_set_sink(data, sink, false, false);
}
/* If something didn't pick a format for us, pick the top-most format since
i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
i->module = data->module;
i->sink = data->sink;
+ i->sink_requested_by_application = data->sink_requested_by_application;
i->origin_sink = data->origin_sink;
i->client = data->client;
pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
i->sink = NULL;
+ i->sink_requested_by_application = false;
pa_sink_input_unref(i);
pa_client *client; /* may be NULL */
pa_sink *sink; /* NULL while we are being moved */
+
+ /* This is set to true when creating the sink input if the sink was
+ * requested by the application that created the sink input. This is
+ * sometimes useful for determining whether the sink input should be
+ * moved by some automatic policy. If the sink input is moved away from the
+ * sink that the application requested, this flag is reset to false. */
+ bool sink_requested_by_application;
+
pa_sink *origin_sink; /* only set by filter sinks */
/* A sink input may be connected to multiple source outputs
pa_client *client;
pa_sink *sink;
+ bool sink_requested_by_application;
pa_sink *origin_sink;
pa_resample_method_t resample_method;
void pa_sink_input_new_data_add_volume_factor(pa_sink_input_new_data *data, const char *key, const pa_cvolume *volume_factor);
void pa_sink_input_new_data_add_volume_factor_sink(pa_sink_input_new_data *data, const char *key, const pa_cvolume *volume_factor);
void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, bool mute);
-bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, bool save);
+bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, bool save, bool requested_by_application);
bool pa_sink_input_new_data_set_formats(pa_sink_input_new_data *data, pa_idxset *formats);
void pa_sink_input_new_data_done(pa_sink_input_new_data *data);
u->readf_function = pa_sndfile_readf_function(&ss);
pa_sink_input_new_data_init(&data);
- pa_sink_input_new_data_set_sink(&data, sink, false);
+ pa_sink_input_new_data_set_sink(&data, sink, false, true);
data.driver = __FILE__;
pa_sink_input_new_data_set_sample_spec(&data, &ss);
pa_sink_input_new_data_set_channel_map(&data, &cm);
data->muted = mute;
}
-bool pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_source *s, bool save) {
+bool pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_source *s, bool save,
+ bool requested_by_application) {
bool ret = true;
pa_idxset *formats = NULL;
/* We're not working with the extended API */
data->source = s;
data->save_source = save;
+ data->source_requested_by_application = requested_by_application;
} else {
/* Extended API: let's see if this source supports the formats the client would like */
formats = pa_source_check_formats(s, data->req_formats);
/* Source supports at least one of the requested formats */
data->source = s;
data->save_source = save;
+ data->source_requested_by_application = requested_by_application;
if (data->nego_formats)
pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
data->nego_formats = formats;
if (data->source) {
/* Trigger format negotiation */
- return pa_source_output_new_data_set_source(data, data->source, data->save_source);
+ return pa_source_output_new_data_set_source(data, data->source, data->save_source,
+ data->source_requested_by_application);
}
return true;
pa_return_val_if_fail(source, -PA_ERR_NOENTITY);
}
- pa_source_output_new_data_set_source(data, source, false);
+ pa_source_output_new_data_set_source(data, source, false, false);
}
/* If something didn't pick a format for us, pick the top-most format since
o->driver = pa_xstrdup(pa_path_get_filename(data->driver));
o->module = data->module;
o->source = data->source;
+ o->source_requested_by_application = data->source_requested_by_application;
o->destination_source = data->destination_source;
o->client = data->client;
pa_cvolume_remap(&o->volume_factor_source, &o->source->channel_map, &o->channel_map);
o->source = NULL;
+ o->source_requested_by_application = false;
pa_source_output_unref(o);
pa_client *client; /* may be NULL */
pa_source *source; /* NULL while being moved */
+
+ /* This is set to true when creating the source output if the source was
+ * requested by the application that created the source output. This is
+ * sometimes useful for determining whether the source output should be
+ * moved by some automatic policy. If the source output is moved away from
+ * the source that the application requested, this flag is reset to
+ * false. */
+ bool source_requested_by_application;
+
pa_source *destination_source; /* only set by filter sources */
/* A source output can monitor just a single input of a sink, in which case we find it here */
pa_client *client;
pa_source *source;
+ bool source_requested_by_application;
pa_source *destination_source;
pa_resample_method_t resample_method;
void pa_source_output_new_data_apply_volume_factor(pa_source_output_new_data *data, const pa_cvolume *volume_factor);
void pa_source_output_new_data_apply_volume_factor_source(pa_source_output_new_data *data, const pa_cvolume *volume_factor);
void pa_source_output_new_data_set_muted(pa_source_output_new_data *data, bool mute);
-bool pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_source *s, bool save);
+bool pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_source *s, bool save,
+ bool requested_by_application);
bool pa_source_output_new_data_set_formats(pa_source_output_new_data *data, pa_idxset *formats);
void pa_source_output_new_data_done(pa_source_output_new_data *data);