[pulseaudio-discuss] [PATCH v3 1/2] loopback: Enable routing on loopback streams
Tanu Kaskinen
tanuk at iki.fi
Tue May 29 04:24:31 PDT 2012
On Tue, 2012-04-03 at 17:18 +0200, Frédéric Dalleau wrote:
> At module-loopback load, if no sink is given, the default sink is used. If the
> stream has a media.role property, the property cannot be used because a the
> source or sink is forced to default. Both module-intended-roles and
> module-device-manager are affected. The same apply to sources.
>
> With this patch, if sink or source is missing, routing modules can be used.
> ---
> src/modules/module-loopback.c | 39 +++++++++++++++++++++++++++------------
> 1 files changed, 27 insertions(+), 12 deletions(-)
>
> diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
> index 0d65682..1fdf273 100644
> --- a/src/modules/module-loopback.c
> +++ b/src/modules/module-loopback.c
> @@ -645,10 +645,10 @@ static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
> int pa__init(pa_module *m) {
> pa_modargs *ma = NULL;
> struct userdata *u;
> - pa_sink *sink;
> + pa_sink *sink = NULL;
> pa_sink_input_new_data sink_input_data;
> pa_bool_t sink_dont_move;
> - pa_source *source;
> + pa_source *source = NULL;
> pa_source_output_new_data source_output_data;
> pa_bool_t source_dont_move;
> uint32_t latency_msec;
> @@ -666,12 +666,14 @@ int pa__init(pa_module *m) {
> goto fail;
> }
>
> - if (!(source = pa_namereg_get(m->core, pa_modargs_get_value(ma, "source", NULL), PA_NAMEREG_SOURCE))) {
> + n = pa_modargs_get_value(ma, "source", NULL);
> + if (n && !(source = pa_namereg_get(m->core, n, PA_NAMEREG_SOURCE))) {
> pa_log("No such source.");
> goto fail;
> }
>
> - if (!(sink = pa_namereg_get(m->core, pa_modargs_get_value(ma, "sink", NULL), PA_NAMEREG_SINK))) {
> + n = pa_modargs_get_value(ma, "sink", NULL);
> + if (n && !(sink = pa_namereg_get(m->core, n, PA_NAMEREG_SINK))) {
> pa_log("No such sink.");
> goto fail;
> }
> @@ -681,8 +683,18 @@ int pa__init(pa_module *m) {
> goto fail;
> }
>
> - ss = sink->sample_spec;
> - map = sink->channel_map;
> + if (!sink && !source)
> + sink = pa_namereg_get_default_sink(m->core);
This still overrides the routing modules, right?
I guess this is done, because otherwise you don't know how to initialize
ss and map? I think a better solution would be to specify the
PA_SINK_INPUT_FIX_FORMAT flag and its friends when calling
pa_sink_input_new() when neither sink or source has been given. After
the pa_sink_input_new() call, ss and map can be copied from the sink
input, which has got them from the sink to which it was routed.
> +
> + if (sink) {
> + ss = sink->sample_spec;
> + map = sink->channel_map;
> + } else if (source) {
> + ss = source->sample_spec;
> + map = source->channel_map;
> + } else
> + goto fail;
> +
> if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
> pa_log("Invalid sample format specification or channel map");
> goto fail;
> @@ -713,7 +725,9 @@ int pa__init(pa_module *m) {
> 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, FALSE);
> +
> + if(sink)
Cosmetic: Missing space after "if".
> + pa_sink_input_new_data_set_sink(&sink_input_data, sink, FALSE);
>
> 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.");
> @@ -723,12 +737,12 @@ int pa__init(pa_module *m) {
>
> if (!pa_proplist_contains(sink_input_data.proplist, PA_PROP_MEDIA_NAME))
> pa_proplist_setf(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Loopback from %s",
> - pa_strnull(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION)));
> + source ? pa_strnull(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION)) : "unspecified source");
>
> if (!pa_proplist_contains(sink_input_data.proplist, PA_PROP_MEDIA_ROLE))
> pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
>
> - if (!pa_proplist_contains(sink_input_data.proplist, PA_PROP_MEDIA_ICON_NAME)
> + if (source && !pa_proplist_contains(sink_input_data.proplist, PA_PROP_MEDIA_ICON_NAME)
> && (n = pa_proplist_gets(source->proplist, PA_PROP_DEVICE_ICON_NAME)))
> pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ICON_NAME, n);
Now if sink or source is not set, the device description and icon name
properties are left at a suboptimal state. Instead of checking for the
sink and source pointers, maybe this proplist handling could be moved
after pa_sink_input_new() and pa_source_output_new() have been called?
At that time the sink and source would be available.
--
Tanu
More information about the pulseaudio-discuss
mailing list