/* Called from main context */
int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
- pa_resampler *new_resampler;
-
pa_sink_input_assert_ref(i);
pa_assert_ctl_context();
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
dest->sample_spec.rate);
}
- if (i->thread_info.resampler &&
- pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
- pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
-
- /* Try to reuse the old resampler if possible */
- new_resampler = i->thread_info.resampler;
-
- else if (!pa_sink_input_is_passthrough(i) &&
- ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
- !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) ||
- !pa_channel_map_equal(&i->channel_map, &dest->channel_map))) {
-
- /* Okay, we need a new resampler for the new sink */
-
- if (!(new_resampler = pa_resampler_new(
- i->core->mempool,
- &i->sample_spec, &i->channel_map,
- &dest->sample_spec, &dest->channel_map,
- i->requested_resample_method,
- ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
- ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
- (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
- pa_log_warn("Unsupported resampling operation.");
- return -PA_ERR_NOTSUPPORTED;
- }
- } else
- new_resampler = NULL;
-
if (i->moving)
i->moving(i, dest);
if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
i->sink->n_corked++;
- /* Replace resampler and render queue */
- if (new_resampler != i->thread_info.resampler) {
- char *memblockq_name;
-
- if (i->thread_info.resampler)
- pa_resampler_free(i->thread_info.resampler);
- i->thread_info.resampler = new_resampler;
-
- pa_memblockq_free(i->thread_info.render_memblockq);
-
- memblockq_name = pa_sprintf_malloc("sink input render_memblockq [%u]", i->index);
- i->thread_info.render_memblockq = pa_memblockq_new(
- memblockq_name,
- 0,
- MEMBLOCKQ_MAXLENGTH,
- 0,
- &i->sink->sample_spec,
- 0,
- 1,
- 0,
- &i->sink->silence);
- pa_xfree(memblockq_name);
- i->actual_resample_method = new_resampler ? pa_resampler_get_method(new_resampler) : PA_RESAMPLER_INVALID;
- }
+ pa_sink_input_update_rate(i);
pa_sink_update_status(dest);
if (pl)
pa_proplist_free(pl);
}
+
+/* Called from main context */
+/* Updates the sink input's resampler with whatever the current sink requires
+ * -- useful when the underlying sink's rate might have changed */
+int pa_sink_input_update_rate(pa_sink_input *i) {
+ pa_resampler *new_resampler;
+ char *memblockq_name;
+
+ pa_sink_input_assert_ref(i);
+ pa_assert_ctl_context();
+
+ if (i->thread_info.resampler &&
+ pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &i->sink->sample_spec) &&
+ pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &i->sink->channel_map))
+
+ new_resampler = i->thread_info.resampler;
+
+ else if (!pa_sink_input_is_passthrough(i) &&
+ ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
+ !pa_sample_spec_equal(&i->sample_spec, &i->sink->sample_spec) ||
+ !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map))) {
+
+ new_resampler = pa_resampler_new(i->core->mempool,
+ &i->sample_spec, &i->channel_map,
+ &i->sink->sample_spec, &i->sink->channel_map,
+ i->requested_resample_method,
+ ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
+ ((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
+ (i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0));
+
+ if (!new_resampler) {
+ pa_log_warn("Unsupported resampling operation.");
+ return -PA_ERR_NOTSUPPORTED;
+ }
+ } else
+ new_resampler = NULL;
+
+ if (new_resampler == i->thread_info.resampler)
+ return 0;
+
+ if (i->thread_info.resampler)
+ pa_resampler_free(i->thread_info.resampler);
+
+ i->thread_info.resampler = new_resampler;
+
+ pa_memblockq_free(i->thread_info.render_memblockq);
+
+ memblockq_name = pa_sprintf_malloc("sink input render_memblockq [%u]", i->index);
+ i->thread_info.render_memblockq = pa_memblockq_new(
+ memblockq_name,
+ 0,
+ MEMBLOCKQ_MAXLENGTH,
+ 0,
+ &i->sink->sample_spec,
+ 0,
+ 1,
+ 0,
+ &i->sink->silence);
+ pa_xfree(memblockq_name);
+
+ i->actual_resample_method = new_resampler ? pa_resampler_get_method(new_resampler) : PA_RESAMPLER_INVALID;
+
+ pa_log_debug("Updated resmpler for sink input %d", i->index);
+
+ return 0;
+}
void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b);
int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate);
+int pa_sink_input_update_rate(pa_sink_input *i);
/* This returns the sink's fields converted into out sample type */
size_t pa_sink_input_get_max_rewind(pa_sink_input *i);
/* Called from main context */
int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, pa_bool_t save) {
- pa_resampler *new_resampler;
-
pa_source_output_assert_ref(o);
pa_assert_ctl_context();
pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state));
dest->sample_spec.rate);
}
- if (o->thread_info.resampler &&
- pa_sample_spec_equal(pa_resampler_input_sample_spec(o->thread_info.resampler), &dest->sample_spec) &&
- pa_channel_map_equal(pa_resampler_input_channel_map(o->thread_info.resampler), &dest->channel_map))
-
- /* Try to reuse the old resampler if possible */
- new_resampler = o->thread_info.resampler;
-
- else if (!pa_source_output_is_passthrough(o) &&
- ((o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ||
- !pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec) ||
- !pa_channel_map_equal(&o->channel_map, &dest->channel_map))) {
-
- /* Okay, we need a new resampler for the new source */
-
- if (!(new_resampler = pa_resampler_new(
- o->core->mempool,
- &dest->sample_spec, &dest->channel_map,
- &o->sample_spec, &o->channel_map,
- o->requested_resample_method,
- ((o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
- ((o->flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
- (o->core->disable_remixing || (o->flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
- pa_log_warn("Unsupported resampling operation.");
- return -PA_ERR_NOTSUPPORTED;
- }
- } else
- new_resampler = NULL;
-
if (o->moving)
o->moving(o, dest);
if (pa_source_output_get_state(o) == PA_SOURCE_OUTPUT_CORKED)
o->source->n_corked++;
- /* Replace resampler */
- if (new_resampler != o->thread_info.resampler) {
-
- if (o->thread_info.resampler)
- pa_resampler_free(o->thread_info.resampler);
- o->thread_info.resampler = new_resampler;
-
- pa_memblockq_free(o->thread_info.delay_memblockq);
-
- o->thread_info.delay_memblockq = pa_memblockq_new(
- "source output delay_memblockq",
- 0,
- MEMBLOCKQ_MAXLENGTH,
- 0,
- &o->source->sample_spec,
- 0,
- 1,
- 0,
- &o->source->silence);
- o->actual_resample_method = new_resampler ? pa_resampler_get_method(new_resampler) : PA_RESAMPLER_INVALID;
- }
+ pa_source_output_update_rate(o);
pa_source_update_status(dest);
if (pl)
pa_proplist_free(pl);
}
+
+/* Called from main context */
+/* Updates the source output's resampler with whatever the current source
+ * requires -- useful when the underlying source's rate might have changed */
+int pa_source_output_update_rate(pa_source_output *o) {
+ pa_resampler *new_resampler;
+ char *memblockq_name;
+
+ pa_source_output_assert_ref(o);
+ pa_assert_ctl_context();
+
+ if (o->thread_info.resampler &&
+ pa_sample_spec_equal(pa_resampler_input_sample_spec(o->thread_info.resampler), &o->source->sample_spec) &&
+ pa_channel_map_equal(pa_resampler_input_channel_map(o->thread_info.resampler), &o->source->channel_map))
+
+ new_resampler = o->thread_info.resampler;
+
+ else if (!pa_source_output_is_passthrough(o) &&
+ ((o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ||
+ !pa_sample_spec_equal(&o->sample_spec, &o->source->sample_spec) ||
+ !pa_channel_map_equal(&o->channel_map, &o->source->channel_map))) {
+
+ new_resampler = pa_resampler_new(o->core->mempool,
+ &o->source->sample_spec, &o->source->channel_map,
+ &o->sample_spec, &o->channel_map,
+ o->requested_resample_method,
+ ((o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
+ ((o->flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
+ (o->core->disable_remixing || (o->flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0));
+
+ if (!new_resampler) {
+ pa_log_warn("Unsupported resampling operation.");
+ return -PA_ERR_NOTSUPPORTED;
+ }
+ } else
+ new_resampler = NULL;
+
+ if (new_resampler == o->thread_info.resampler)
+ return 0;
+
+ if (o->thread_info.resampler)
+ pa_resampler_free(o->thread_info.resampler);
+
+ o->thread_info.resampler = new_resampler;
+
+ pa_memblockq_free(o->thread_info.delay_memblockq);
+
+ memblockq_name = pa_sprintf_malloc("source output delay_memblockq [%u]", o->index);
+ o->thread_info.delay_memblockq = pa_memblockq_new(
+ memblockq_name,
+ 0,
+ MEMBLOCKQ_MAXLENGTH,
+ 0,
+ &o->source->sample_spec,
+ 0,
+ 1,
+ 0,
+ &o->source->silence);
+ pa_xfree(memblockq_name);
+
+ o->actual_resample_method = new_resampler ? pa_resampler_get_method(new_resampler) : PA_RESAMPLER_INVALID;
+
+ pa_log_debug("Updated resmpler for source output %d", o->index);
+
+ return 0;
+}
void pa_source_output_cork(pa_source_output *o, pa_bool_t b);
int pa_source_output_set_rate(pa_source_output *o, uint32_t rate);
+int pa_source_output_update_rate(pa_source_output *o);
size_t pa_source_output_get_max_rewind(pa_source_output *o);