mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-03 09:01:50 -05:00
core: Factor out passthrough checks into their own functions
Since we currently have two mechanisms to signal a passthrough connection (non-PCM format or PA_SINK_INPUT_PASSTHROUGH flag), we move all the related checks into functions and use those everywhere. This makes things more consistent, and should we decide to get rid of the flag, we only need to change pa_sink_input_*_is_passthrough() accordingly.
This commit is contained in:
parent
9a39a3df10
commit
4fb68b91ac
4 changed files with 41 additions and 17 deletions
|
|
@ -1058,7 +1058,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
|
||||||
pa_sink_input *i = PA_SINK_INPUT(data);
|
pa_sink_input *i = PA_SINK_INPUT(data);
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
if (PA_LIKELY(pa_format_info_is_pcm(i->format)))
|
if (PA_LIKELY(!pa_sink_input_is_passthrough(i)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
u->old_rate = u->sink->sample_spec.rate;
|
u->old_rate = u->sink->sample_spec.rate;
|
||||||
|
|
@ -1084,7 +1084,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
|
||||||
pa_sink_input *i = PA_SINK_INPUT(data);
|
pa_sink_input *i = PA_SINK_INPUT(data);
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
if (PA_LIKELY(pa_format_info_is_pcm(i->format)))
|
if (PA_LIKELY(!pa_sink_input_is_passthrough(i)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Passthrough format, see if we need to reset sink sample rate */
|
/* Passthrough format, see if we need to reset sink sample rate */
|
||||||
|
|
|
||||||
|
|
@ -50,15 +50,14 @@ PA_DEFINE_PUBLIC_CLASS(pa_sink_input, pa_msgobject);
|
||||||
static void sink_input_free(pa_object *o);
|
static void sink_input_free(pa_object *o);
|
||||||
static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v);
|
static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v);
|
||||||
|
|
||||||
static int check_passthrough_connection(pa_format_info *format, pa_sink *dest) {
|
static int check_passthrough_connection(pa_bool_t passthrough, pa_sink *dest) {
|
||||||
|
|
||||||
if (pa_sink_is_passthrough(dest)) {
|
if (pa_sink_is_passthrough(dest)) {
|
||||||
pa_log_warn("Sink is already connected to PASSTHROUGH input");
|
pa_log_warn("Sink is already connected to PASSTHROUGH input");
|
||||||
return -PA_ERR_BUSY;
|
return -PA_ERR_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If current input(s) exist, check new input is not PASSTHROUGH */
|
/* If current input(s) exist, check new input is not PASSTHROUGH */
|
||||||
if (pa_idxset_size(dest->inputs) > 0 && !pa_format_info_is_pcm(format)) {
|
if (pa_idxset_size(dest->inputs) > 0 && passthrough) {
|
||||||
pa_log_warn("Sink is already connected, cannot accept new PASSTHROUGH INPUT");
|
pa_log_warn("Sink is already connected, cannot accept new PASSTHROUGH INPUT");
|
||||||
return -PA_ERR_BUSY;
|
return -PA_ERR_BUSY;
|
||||||
}
|
}
|
||||||
|
|
@ -91,6 +90,18 @@ void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const
|
||||||
data->channel_map = *map;
|
data->channel_map = *map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pa_bool_t pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data *data) {
|
||||||
|
pa_assert(data);
|
||||||
|
|
||||||
|
if (PA_LIKELY(data->format) && PA_UNLIKELY(!pa_format_info_is_pcm(data->format)))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (PA_UNLIKELY(data->flags & PA_SINK_INPUT_PASSTHROUGH))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
|
void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
|
||||||
pa_assert(data);
|
pa_assert(data);
|
||||||
pa_assert(data->volume_writable);
|
pa_assert(data->volume_writable);
|
||||||
|
|
@ -284,15 +295,13 @@ int pa_sink_input_new(
|
||||||
} else {
|
} else {
|
||||||
pa_return_val_if_fail(pa_format_info_to_sample_spec_fake(data->format, &ss), -PA_ERR_INVALID);
|
pa_return_val_if_fail(pa_format_info_to_sample_spec_fake(data->format, &ss), -PA_ERR_INVALID);
|
||||||
pa_sink_input_new_data_set_sample_spec(data, &ss);
|
pa_sink_input_new_data_set_sample_spec(data, &ss);
|
||||||
/* XXX: this is redundant - we can just check the encoding */
|
|
||||||
data->flags |= PA_SINK_INPUT_PASSTHROUGH;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_return_val_if_fail(data->sink, -PA_ERR_NOENTITY);
|
pa_return_val_if_fail(data->sink, -PA_ERR_NOENTITY);
|
||||||
pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data->sink)), -PA_ERR_BADSTATE);
|
pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data->sink)), -PA_ERR_BADSTATE);
|
||||||
pa_return_val_if_fail(!data->sync_base || (data->sync_base->sink == data->sink && pa_sink_input_get_state(data->sync_base) == PA_SINK_INPUT_CORKED), -PA_ERR_INVALID);
|
pa_return_val_if_fail(!data->sync_base || (data->sync_base->sink == data->sink && pa_sink_input_get_state(data->sync_base) == PA_SINK_INPUT_CORKED), -PA_ERR_INVALID);
|
||||||
|
|
||||||
r = check_passthrough_connection(data->format, data->sink);
|
r = check_passthrough_connection(pa_sink_input_new_data_is_passthrough(data), data->sink);
|
||||||
pa_return_val_if_fail(r == PA_OK, r);
|
pa_return_val_if_fail(r == PA_OK, r);
|
||||||
|
|
||||||
if (!data->sample_spec_is_set)
|
if (!data->sample_spec_is_set)
|
||||||
|
|
@ -373,7 +382,7 @@ int pa_sink_input_new(
|
||||||
!pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
|
!pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
|
||||||
|
|
||||||
/* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
|
/* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
|
||||||
if (!(data->flags & PA_SINK_INPUT_PASSTHROUGH)) /* no resampler for passthrough content */
|
if (!pa_sink_input_new_data_is_passthrough(data)) /* no resampler for passthrough content */
|
||||||
if (!(resampler = pa_resampler_new(
|
if (!(resampler = pa_resampler_new(
|
||||||
core->mempool,
|
core->mempool,
|
||||||
&data->sample_spec, &data->channel_map,
|
&data->sample_spec, &data->channel_map,
|
||||||
|
|
@ -601,7 +610,7 @@ void pa_sink_input_unlink(pa_sink_input *i) {
|
||||||
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL) == 0);
|
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL) == 0);
|
||||||
|
|
||||||
/* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
|
/* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
|
||||||
if (!pa_format_info_is_pcm(i->format) && i->sink->monitor_source)
|
if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
|
||||||
pa_source_suspend(i->sink->monitor_source, FALSE, PA_SUSPEND_PASSTHROUGH);
|
pa_source_suspend(i->sink->monitor_source, FALSE, PA_SUSPEND_PASSTHROUGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -694,7 +703,7 @@ void pa_sink_input_put(pa_sink_input *i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're entering passthrough mode, disable the monitor */
|
/* If we're entering passthrough mode, disable the monitor */
|
||||||
if (!pa_format_info_is_pcm(i->format) && i->sink->monitor_source)
|
if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
|
||||||
pa_source_suspend(i->sink->monitor_source, TRUE, PA_SUSPEND_PASSTHROUGH);
|
pa_source_suspend(i->sink->monitor_source, TRUE, PA_SUSPEND_PASSTHROUGH);
|
||||||
|
|
||||||
i->thread_info.soft_volume = i->soft_volume;
|
i->thread_info.soft_volume = i->soft_volume;
|
||||||
|
|
@ -1178,12 +1187,25 @@ static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
|
||||||
/* We don't copy the data to the thread_info data. That's left for someone else to do */
|
/* We don't copy the data to the thread_info data. That's left for someone else to do */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Called from main or I/O context */
|
||||||
|
pa_bool_t pa_sink_input_is_passthrough(pa_sink_input *i) {
|
||||||
|
pa_sink_input_assert_ref(i);
|
||||||
|
|
||||||
|
if (PA_UNLIKELY(!pa_format_info_is_pcm(i->format)))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (PA_UNLIKELY(i->flags & PA_SINK_INPUT_PASSTHROUGH))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Called from main context */
|
/* Called from main context */
|
||||||
pa_bool_t pa_sink_input_is_volume_readable(pa_sink_input *i) {
|
pa_bool_t pa_sink_input_is_volume_readable(pa_sink_input *i) {
|
||||||
pa_sink_input_assert_ref(i);
|
pa_sink_input_assert_ref(i);
|
||||||
pa_assert_ctl_context();
|
pa_assert_ctl_context();
|
||||||
|
|
||||||
return !(i->flags & PA_SINK_INPUT_PASSTHROUGH);
|
return !pa_sink_input_is_passthrough(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from main context */
|
/* Called from main context */
|
||||||
|
|
@ -1342,7 +1364,7 @@ pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_passthrough_connection(i->format, dest) < 0)
|
if (check_passthrough_connection(pa_sink_input_is_passthrough(i), dest) < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (i->may_move_to)
|
if (i->may_move_to)
|
||||||
|
|
@ -1389,7 +1411,7 @@ int pa_sink_input_start_move(pa_sink_input *i) {
|
||||||
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
|
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
|
||||||
|
|
||||||
/* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
|
/* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
|
||||||
if (!pa_format_info_is_pcm(i->format) && i->sink->monitor_source)
|
if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
|
||||||
pa_source_suspend(i->sink->monitor_source, FALSE, PA_SUSPEND_PASSTHROUGH);
|
pa_source_suspend(i->sink->monitor_source, FALSE, PA_SUSPEND_PASSTHROUGH);
|
||||||
|
|
||||||
pa_sink_update_status(i->sink);
|
pa_sink_update_status(i->sink);
|
||||||
|
|
@ -1564,7 +1586,7 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
|
||||||
if (!pa_sink_input_may_move_to(i, dest))
|
if (!pa_sink_input_may_move_to(i, dest))
|
||||||
return -PA_ERR_NOTSUPPORTED;
|
return -PA_ERR_NOTSUPPORTED;
|
||||||
|
|
||||||
if (!pa_format_info_is_pcm(i->format) && !pa_sink_check_format(dest, i->format)) {
|
if (pa_sink_input_is_passthrough(i) && !pa_sink_check_format(dest, i->format)) {
|
||||||
/* FIXME: Fire a message here so the client can renegotiate */
|
/* FIXME: Fire a message here so the client can renegotiate */
|
||||||
return -PA_ERR_NOTSUPPORTED;
|
return -PA_ERR_NOTSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
@ -1634,7 +1656,7 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
|
||||||
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
|
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
|
||||||
|
|
||||||
/* If we're entering passthrough mode, disable the monitor */
|
/* If we're entering passthrough mode, disable the monitor */
|
||||||
if (!pa_format_info_is_pcm(i->format) && i->sink->monitor_source)
|
if (pa_sink_input_is_passthrough(i) && i->sink->monitor_source)
|
||||||
pa_source_suspend(i->sink->monitor_source, TRUE, PA_SUSPEND_PASSTHROUGH);
|
pa_source_suspend(i->sink->monitor_source, TRUE, PA_SUSPEND_PASSTHROUGH);
|
||||||
|
|
||||||
pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
|
pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,7 @@ typedef struct pa_sink_input_new_data {
|
||||||
pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data);
|
pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data);
|
||||||
void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec);
|
void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec);
|
||||||
void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map);
|
void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map);
|
||||||
|
pa_bool_t pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data *data);
|
||||||
void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume);
|
void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume);
|
||||||
void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor);
|
void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor);
|
||||||
void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor);
|
void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor);
|
||||||
|
|
@ -350,6 +351,7 @@ void pa_sink_input_kill(pa_sink_input*i);
|
||||||
|
|
||||||
pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency);
|
pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency);
|
||||||
|
|
||||||
|
pa_bool_t pa_sink_input_is_passthrough(pa_sink_input *i);
|
||||||
pa_bool_t pa_sink_input_is_volume_readable(pa_sink_input *i);
|
pa_bool_t pa_sink_input_is_volume_readable(pa_sink_input *i);
|
||||||
void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute);
|
void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute);
|
||||||
pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute);
|
pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute);
|
||||||
|
|
|
||||||
|
|
@ -1252,7 +1252,7 @@ pa_bool_t pa_sink_is_passthrough(pa_sink *s) {
|
||||||
if (pa_idxset_size(s->inputs) == 1) {
|
if (pa_idxset_size(s->inputs) == 1) {
|
||||||
alt_i = pa_idxset_first(s->inputs, &idx);
|
alt_i = pa_idxset_first(s->inputs, &idx);
|
||||||
|
|
||||||
if (!pa_format_info_is_pcm(alt_i->format))
|
if (pa_sink_input_is_passthrough(alt_i))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue