On 19.02.2018 21:49, Raman Shyshniou wrote: > 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); Thanks again. Also pushed to next.