Currently the loopback module uses sample spec and channel map of the sink by default. It leads to double resample if source and sink sample specs are different and no rate/format specified in arguments. This patch causes the source sample spec and channel map to be used by default. --- src/modules/module-loopback.c | 140 +++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c index aecac0a..a72f395 100644 --- a/src/modules/module-loopback.c +++ b/src/modules/module-loopback.c @@ -1286,15 +1286,15 @@ int pa__init(pa_module *m) { goto fail; } - if (sink) { - ss = sink->sample_spec; - map = sink->channel_map; + if (source) { + ss = source->sample_spec; + map = source->channel_map; format_set = true; rate_set = true; channels_set = true; - } else if (source) { - ss = source->sample_spec; - map = source->channel_map; + } else if (sink) { + ss = sink->sample_spec; + map = sink->channel_map; format_set = true; rate_set = true; channels_set = true; @@ -1363,6 +1363,70 @@ int pa__init(pa_module *m) { u->real_adjust_time = u->adjust_time; + pa_source_output_new_data_init(&source_output_data); + source_output_data.driver = __FILE__; + source_output_data.module = m; + if (source) + 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_source_output_new_data_done(&source_output_data); + goto fail; + } + + if (!pa_proplist_contains(source_output_data.proplist, PA_PROP_MEDIA_ROLE)) + pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "abstract"); + + pa_source_output_new_data_set_sample_spec(&source_output_data, &ss); + pa_source_output_new_data_set_channel_map(&source_output_data, &map); + source_output_data.flags = PA_SOURCE_OUTPUT_START_CORKED; + + if (!remix) + source_output_data.flags |= PA_SOURCE_OUTPUT_NO_REMIX; + + if (!format_set) + source_output_data.flags |= PA_SOURCE_OUTPUT_FIX_FORMAT; + + if (!rate_set) + source_output_data.flags |= PA_SOURCE_OUTPUT_FIX_RATE; + + if (!channels_set) + source_output_data.flags |= PA_SOURCE_OUTPUT_FIX_CHANNELS; + + source_dont_move = false; + if (pa_modargs_get_value_boolean(ma, "source_dont_move", &source_dont_move) < 0) { + pa_log("source_dont_move= expects a boolean argument."); + goto fail; + } + + if (source_dont_move) + source_output_data.flags |= PA_SOURCE_OUTPUT_DONT_MOVE; + + pa_source_output_new(&u->source_output, m->core, &source_output_data); + pa_source_output_new_data_done(&source_output_data); + + if (!u->source_output) + goto fail; + + u->source_output->parent.process_msg = source_output_process_msg_cb; + u->source_output->push = source_output_push_cb; + u->source_output->process_rewind = source_output_process_rewind_cb; + u->source_output->kill = source_output_kill_cb; + u->source_output->attach = source_output_attach_cb; + u->source_output->detach = source_output_detach_cb; + u->source_output->may_move_to = source_output_may_move_to_cb; + u->source_output->moving = source_output_moving_cb; + u->source_output->suspend = source_output_suspend_cb; + u->source_output->update_source_latency_range = update_source_latency_range_cb; + u->source_output->update_source_fixed_latency = update_source_latency_range_cb; + u->source_output->userdata = u; + + /* If format, rate or channels were originally unset, they are set now + * after the pa_source_output_new() call. */ + ss = u->source_output->sample_spec; + map = u->source_output->channel_map; + pa_sink_input_new_data_init(&sink_input_data); sink_input_data.driver = __FILE__; sink_input_data.module = m; @@ -1386,15 +1450,6 @@ int pa__init(pa_module *m) { if (!remix) sink_input_data.flags |= PA_SINK_INPUT_NO_REMIX; - if (!format_set) - sink_input_data.flags |= PA_SINK_INPUT_FIX_FORMAT; - - if (!rate_set) - sink_input_data.flags |= PA_SINK_INPUT_FIX_RATE; - - if (!channels_set) - sink_input_data.flags |= PA_SINK_INPUT_FIX_CHANNELS; - sink_dont_move = false; if (pa_modargs_get_value_boolean(ma, "sink_dont_move", &sink_dont_move) < 0) { pa_log("sink_dont_move= expects a boolean argument."); @@ -1410,11 +1465,6 @@ int pa__init(pa_module *m) { if (!u->sink_input) goto fail; - /* If format, rate or channels were originally unset, they are set now - * after the pa_sink_input_new() call. */ - ss = u->sink_input->sample_spec; - map = u->sink_input->channel_map; - u->sink_input->parent.process_msg = sink_input_process_msg_cb; u->sink_input->pop = sink_input_pop_cb; u->sink_input->process_rewind = sink_input_process_rewind_cb; @@ -1431,56 +1481,6 @@ int pa__init(pa_module *m) { u->sink_input->update_sink_fixed_latency = update_sink_latency_range_cb; u->sink_input->userdata = u; - pa_source_output_new_data_init(&source_output_data); - source_output_data.driver = __FILE__; - source_output_data.module = m; - if (source) - 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_source_output_new_data_done(&source_output_data); - goto fail; - } - - if (!pa_proplist_contains(source_output_data.proplist, PA_PROP_MEDIA_ROLE)) - pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "abstract"); - - pa_source_output_new_data_set_sample_spec(&source_output_data, &ss); - pa_source_output_new_data_set_channel_map(&source_output_data, &map); - source_output_data.flags = PA_SOURCE_OUTPUT_START_CORKED; - - if (!remix) - source_output_data.flags |= PA_SOURCE_OUTPUT_NO_REMIX; - - source_dont_move = false; - if (pa_modargs_get_value_boolean(ma, "source_dont_move", &source_dont_move) < 0) { - pa_log("source_dont_move= expects a boolean argument."); - goto fail; - } - - if (source_dont_move) - source_output_data.flags |= PA_SOURCE_OUTPUT_DONT_MOVE; - - pa_source_output_new(&u->source_output, m->core, &source_output_data); - pa_source_output_new_data_done(&source_output_data); - - if (!u->source_output) - goto fail; - - u->source_output->parent.process_msg = source_output_process_msg_cb; - u->source_output->push = source_output_push_cb; - u->source_output->process_rewind = source_output_process_rewind_cb; - u->source_output->kill = source_output_kill_cb; - u->source_output->attach = source_output_attach_cb; - u->source_output->detach = source_output_detach_cb; - u->source_output->may_move_to = source_output_may_move_to_cb; - u->source_output->moving = source_output_moving_cb; - u->source_output->suspend = source_output_suspend_cb; - u->source_output->update_source_latency_range = update_source_latency_range_cb; - u->source_output->update_source_fixed_latency = update_source_latency_range_cb; - u->source_output->userdata = u; - update_latency_boundaries(u, u->source_output->source, u->sink_input->sink); set_sink_input_latency(u, u->sink_input->sink); set_source_output_latency(u, u->source_output->source); -- 1.8.3.1