summaryrefslogtreecommitdiffstats
path: root/src/pulsecore/source-output.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pulsecore/source-output.c')
-rw-r--r--src/pulsecore/source-output.c53
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))