diff options
Diffstat (limited to 'src/pulsecore/source-output.c')
-rw-r--r-- | src/pulsecore/source-output.c | 53 |
1 files changed, 35 insertions, 18 deletions
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index dbf3af94..376402fa 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -90,6 +90,7 @@ static void reset_callbacks(pa_source_output *o) { o->kill = NULL; o->get_latency = NULL; o->state_change = NULL; + o->may_move_to = NULL; } /* Called from main context */ @@ -124,14 +125,14 @@ pa_source_output* pa_source_output_new( pa_return_null_if_fail(pa_sample_spec_valid(&data->sample_spec)); if (!data->channel_map_is_set) { - if (data->source->channel_map.channels == data->sample_spec.channels) + if (pa_channel_map_compatible(&data->source->channel_map, &data->sample_spec)) data->channel_map = data->source->channel_map; else - pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT)); + pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT); } pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map)); - pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels); + pa_return_null_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec)); if (flags & PA_SOURCE_OUTPUT_FIX_FORMAT) data->sample_spec.format = data->source->sample_spec.format; @@ -171,7 +172,8 @@ pa_source_output* pa_source_output_new( data->resample_method, ((flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) | ((flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) | - (core->disable_remixing || (flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) { + (core->disable_remixing || (flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) | + (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) { pa_log_warn("Unsupported resampling operation."); return NULL; } @@ -397,7 +399,7 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { if (pa_memblockq_push(o->thread_info.delay_memblockq, chunk) < 0) { pa_log_debug("Delay queue overflow!"); - pa_memblockq_seek(o->thread_info.delay_memblockq, chunk->length, PA_SEEK_RELATIVE); + pa_memblockq_seek(o->thread_info.delay_memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE); } limit = o->process_rewind ? 0 : o->source->thread_info.max_rewind; @@ -511,14 +513,11 @@ pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t if (PA_SOURCE_OUTPUT_IS_LINKED(o->state)) pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0); - else { + else /* If this source output is not realized yet, we have to touch * the thread info data directly */ - usec = fixup_latency(o->source, usec); o->thread_info.requested_source_latency = usec; - o->source->thread_info.requested_latency_valid = FALSE; - } return usec; } @@ -595,6 +594,32 @@ pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o) { return o->resample_method; } +pa_bool_t pa_source_output_may_move_to(pa_source_output *o, pa_source *dest) { + pa_source_output_assert_ref(o); + pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); + pa_source_assert_ref(dest); + + if (dest == o->source) + return TRUE; + + if (o->flags & PA_SOURCE_OUTPUT_DONT_MOVE) + return FALSE; + + if (o->direct_on_input) + return FALSE; + + if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { + pa_log_warn("Failed to move source output: too many outputs per source."); + return FALSE; + } + + if (o->may_move_to) + if (!o->may_move_to(o, dest)) + return FALSE; + + return TRUE; +} + /* Called from main context */ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { pa_source *origin; @@ -610,17 +635,9 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { if (dest == origin) return 0; - if (o->flags & PA_SOURCE_OUTPUT_DONT_MOVE) + if (!pa_source_output_may_move_to(o, dest)) return -1; - if (o->direct_on_input) - return -1; - - if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { - pa_log_warn("Failed to move source output: too many outputs per source."); - return -1; - } - if (o->thread_info.resampler && pa_sample_spec_equal(&origin->sample_spec, &dest->sample_spec) && pa_channel_map_equal(&origin->channel_map, &dest->channel_map)) |