mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-08 13:29:59 -05:00
Merge branch 'passthrough'
This commit is contained in:
commit
26b4bd74aa
49 changed files with 1796 additions and 201 deletions
|
|
@ -108,6 +108,8 @@ struct userdata {
|
|||
|
||||
pa_cvolume hardware_volume;
|
||||
|
||||
uint32_t old_rate;
|
||||
|
||||
size_t
|
||||
frame_size,
|
||||
fragment_size,
|
||||
|
|
@ -1051,6 +1053,56 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
|
|||
|
||||
switch (code) {
|
||||
|
||||
case PA_SINK_MESSAGE_FINISH_MOVE:
|
||||
case PA_SINK_MESSAGE_ADD_INPUT: {
|
||||
pa_sink_input *i = PA_SINK_INPUT(data);
|
||||
int r = 0;
|
||||
|
||||
if (PA_LIKELY(!pa_sink_input_is_passthrough(i)))
|
||||
break;
|
||||
|
||||
u->old_rate = u->sink->sample_spec.rate;
|
||||
|
||||
/* Passthrough format, see if we need to reset sink sample rate */
|
||||
if (u->sink->sample_spec.rate == i->thread_info.sample_spec.rate)
|
||||
break;
|
||||
|
||||
/* .. we do */
|
||||
if ((r = suspend(u)) < 0)
|
||||
return r;
|
||||
|
||||
u->sink->sample_spec.rate = i->thread_info.sample_spec.rate;
|
||||
|
||||
if ((r = unsuspend(u)) < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PA_SINK_MESSAGE_START_MOVE:
|
||||
case PA_SINK_MESSAGE_REMOVE_INPUT: {
|
||||
pa_sink_input *i = PA_SINK_INPUT(data);
|
||||
int r = 0;
|
||||
|
||||
if (PA_LIKELY(!pa_sink_input_is_passthrough(i)))
|
||||
break;
|
||||
|
||||
/* Passthrough format, see if we need to reset sink sample rate */
|
||||
if (u->sink->sample_spec.rate == u->old_rate)
|
||||
break;
|
||||
|
||||
/* .. we do */
|
||||
if ((r = suspend(u)) < 0)
|
||||
return r;
|
||||
|
||||
u->sink->sample_spec.rate = u->old_rate;
|
||||
|
||||
if ((r = unsuspend(u)) < 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PA_SINK_MESSAGE_GET_LATENCY: {
|
||||
pa_usec_t r = 0;
|
||||
|
||||
|
|
@ -1707,13 +1759,6 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB, pa_bool_t sync_v
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: need automatic detection rather than hard-coded path */
|
||||
if (!strcmp(u->mixer_path->name, "iec958-passthrough-output")) {
|
||||
u->sink->flags |= PA_SINK_PASSTHROUGH;
|
||||
} else {
|
||||
u->sink->flags &= ~PA_SINK_PASSTHROUGH;
|
||||
}
|
||||
|
||||
if (!u->mixer_path->has_volume)
|
||||
pa_log_info("Driver does not support hardware volume control, falling back to software volume control.");
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
# This file is part of PulseAudio.
|
||||
#
|
||||
# PulseAudio is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# PulseAudio is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with PulseAudio; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
|
||||
|
||||
[Element IEC958]
|
||||
switch = mute
|
||||
|
|
@ -155,13 +155,6 @@ paths-input = iec958-stereo-input
|
|||
paths-output = iec958-stereo-output
|
||||
priority = 5
|
||||
|
||||
[Mapping iec958-passthrough]
|
||||
device-strings = iec958:%f
|
||||
channel-map = left,right
|
||||
direction = output
|
||||
paths-output = iec958-passthrough-output
|
||||
priority = 5
|
||||
|
||||
[Mapping iec958-ac3-surround-40]
|
||||
device-strings = a52:%f
|
||||
channel-map = front-left,front-right,rear-left,rear-right
|
||||
|
|
|
|||
|
|
@ -1549,7 +1549,7 @@ int pa__init(pa_module*m) {
|
|||
pa_sink_input_new_data_init(&sink_input_data);
|
||||
sink_input_data.driver = __FILE__;
|
||||
sink_input_data.module = m;
|
||||
sink_input_data.sink = sink_master;
|
||||
pa_sink_input_new_data_set_sink(&sink_input_data, sink_master, FALSE);
|
||||
sink_input_data.origin_sink = u->sink;
|
||||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Sink Stream");
|
||||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
|
||||
|
|
|
|||
|
|
@ -845,7 +845,7 @@ static int output_create_sink_input(struct output *o) {
|
|||
return 0;
|
||||
|
||||
pa_sink_input_new_data_init(&data);
|
||||
data.sink = o->sink;
|
||||
pa_sink_input_new_data_set_sink(&data, o->sink, FALSE);
|
||||
data.driver = __FILE__;
|
||||
pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME, "Simultaneous output on %s", pa_strnull(pa_proplist_gets(o->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
|
||||
pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "filter");
|
||||
|
|
|
|||
|
|
@ -832,8 +832,8 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
|
|||
pa_sink *sink;
|
||||
|
||||
if ((sink = pa_idxset_get_by_index(u->core->sinks, device_index))) {
|
||||
new_data->sink = sink;
|
||||
new_data->save_sink = FALSE;
|
||||
if (!pa_sink_input_new_data_set_sink(new_data, sink, FALSE))
|
||||
pa_log_debug("Not restoring device for stream because no supported format was found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1212,7 +1212,7 @@ int pa__init(pa_module*m) {
|
|||
pa_sink_input_new_data_init(&sink_input_data);
|
||||
sink_input_data.driver = __FILE__;
|
||||
sink_input_data.module = m;
|
||||
sink_input_data.sink = master;
|
||||
pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE);
|
||||
sink_input_data.origin_sink = u->sink;
|
||||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Equalized Stream");
|
||||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
|
||||
|
|
|
|||
|
|
@ -117,11 +117,8 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
|
|||
|
||||
/* Prefer the default sink over any other sink, just in case... */
|
||||
if ((def = pa_namereg_get_default_sink(c)))
|
||||
if (role_match(def->proplist, role)) {
|
||||
new_data->sink = def;
|
||||
new_data->save_sink = FALSE;
|
||||
if (role_match(def->proplist, role) && pa_sink_input_new_data_set_sink(new_data, def, FALSE))
|
||||
return PA_HOOK_OK;
|
||||
}
|
||||
|
||||
/* @todo: favour the highest priority device, not the first one we find? */
|
||||
PA_IDXSET_FOREACH(s, c->sinks, idx) {
|
||||
|
|
@ -131,11 +128,8 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
|
|||
if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)))
|
||||
continue;
|
||||
|
||||
if (role_match(s->proplist, role)) {
|
||||
new_data->sink = s;
|
||||
new_data->save_sink = FALSE;
|
||||
if (role_match(s->proplist, role) && pa_sink_input_new_data_set_sink(new_data, s, FALSE))
|
||||
return PA_HOOK_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return PA_HOOK_OK;
|
||||
|
|
|
|||
|
|
@ -907,7 +907,7 @@ int pa__init(pa_module*m) {
|
|||
pa_sink_input_new_data_init(&sink_input_data);
|
||||
sink_input_data.driver = __FILE__;
|
||||
sink_input_data.module = m;
|
||||
sink_input_data.sink = master;
|
||||
pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE);
|
||||
sink_input_data.origin_sink = u->sink;
|
||||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "LADSPA Stream");
|
||||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
|
||||
|
|
|
|||
|
|
@ -695,7 +695,7 @@ int pa__init(pa_module *m) {
|
|||
pa_sink_input_new_data_init(&sink_input_data);
|
||||
sink_input_data.driver = __FILE__;
|
||||
sink_input_data.module = m;
|
||||
sink_input_data.sink = sink;
|
||||
pa_sink_input_new_data_set_sink(&sink_input_data, sink, FALSE);
|
||||
|
||||
if ((n = pa_modargs_get_value(ma, "sink_input_name", NULL)))
|
||||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, n);
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ int pa__init(pa_module*m) {
|
|||
pa_sink_input_new_data_init(&sink_input_data);
|
||||
sink_input_data.driver = __FILE__;
|
||||
sink_input_data.module = m;
|
||||
sink_input_data.sink = master;
|
||||
pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE);
|
||||
sink_input_data.origin_sink = u->sink;
|
||||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Remapped Stream");
|
||||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ int pa__init(pa_module*m) {
|
|||
pa_sink_input_new_data_init(&data);
|
||||
data.driver = __FILE__;
|
||||
data.module = m;
|
||||
data.sink = sink;
|
||||
pa_sink_input_new_data_set_sink(&data, sink, FALSE);
|
||||
pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME, "%u Hz Sine", frequency);
|
||||
pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
|
||||
pa_proplist_setf(data.proplist, "sine.hz", "%u", frequency);
|
||||
|
|
|
|||
|
|
@ -1301,11 +1301,9 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
|
|||
/* It might happen that a stream and a sink are set up at the
|
||||
same time, in which case we want to make sure we don't
|
||||
interfere with that */
|
||||
if (s && PA_SINK_IS_LINKED(pa_sink_get_state(s))) {
|
||||
pa_log_info("Restoring device for stream %s.", name);
|
||||
new_data->sink = s;
|
||||
new_data->save_sink = TRUE;
|
||||
}
|
||||
if (s && PA_SINK_IS_LINKED(pa_sink_get_state(s)))
|
||||
if (pa_sink_input_new_data_set_sink(new_data, s, TRUE))
|
||||
pa_log_info("Restoring device for stream %s.", name);
|
||||
|
||||
pa_xfree(e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1095,6 +1095,23 @@ static void sink_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_t
|
|||
}
|
||||
}
|
||||
|
||||
if (u->version >= 21) {
|
||||
uint8_t n_formats;
|
||||
pa_format_info format;
|
||||
|
||||
if (pa_tagstruct_getu8(t, &n_formats) < 0) { /* no. of formats */
|
||||
pa_log("Parse failure");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (uint8_t j = 0; j < n_formats; j++) {
|
||||
if (pa_tagstruct_get_format_info(t, &format)) { /* format info */
|
||||
pa_log("Parse failure");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pa_tagstruct_eof(t)) {
|
||||
pa_log("Packet too long");
|
||||
goto fail;
|
||||
|
|
@ -1128,6 +1145,7 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag
|
|||
pa_channel_map channel_map;
|
||||
pa_cvolume volume;
|
||||
pa_proplist *pl;
|
||||
pa_bool_t b;
|
||||
|
||||
pa_assert(pd);
|
||||
pa_assert(u);
|
||||
|
|
@ -1175,6 +1193,33 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag
|
|||
}
|
||||
}
|
||||
|
||||
if (u->version >= 19) {
|
||||
if (pa_tagstruct_get_boolean(t, &b) < 0) {
|
||||
|
||||
pa_log("Parse failure");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (u->version >= 20) {
|
||||
if (pa_tagstruct_get_boolean(t, &b) < 0 ||
|
||||
pa_tagstruct_get_boolean(t, &b) < 0) {
|
||||
|
||||
pa_log("Parse failure");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (u->version >= 21) {
|
||||
pa_format_info format;
|
||||
|
||||
if (pa_tagstruct_get_format_info(t, &format) < 0) {
|
||||
|
||||
pa_log("Parse failure");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pa_tagstruct_eof(t)) {
|
||||
pa_log("Packet too long");
|
||||
goto fail;
|
||||
|
|
@ -1491,6 +1536,13 @@ static void create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t
|
|||
/* #endif */
|
||||
}
|
||||
|
||||
if (u->version >= 21) {
|
||||
pa_format_info format;
|
||||
|
||||
if (pa_tagstruct_get_format_info(t, &format) < 0)
|
||||
goto parse_error;
|
||||
}
|
||||
|
||||
if (!pa_tagstruct_eof(t))
|
||||
goto parse_error;
|
||||
|
||||
|
|
@ -1693,6 +1745,13 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
|
|||
pa_tagstruct_put_boolean(reply, FALSE); /* passthrough stream */
|
||||
#endif
|
||||
|
||||
#ifdef TUNNEL_SINK
|
||||
if (u->version >= 21) {
|
||||
/* We're not using the extended API, so n_formats = 0 and that's that */
|
||||
pa_tagstruct_putu8(t, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
pa_pstream_send_tagstruct(u->pstream, reply);
|
||||
pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, create_stream_callback, u, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -579,7 +579,7 @@ int pa__init(pa_module*m) {
|
|||
pa_sink_input_new_data_init(&sink_input_data);
|
||||
sink_input_data.driver = __FILE__;
|
||||
sink_input_data.module = m;
|
||||
sink_input_data.sink = master;
|
||||
pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE);
|
||||
sink_input_data.origin_sink = u->sink;
|
||||
pa_proplist_setf(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Sink Stream from %s", pa_proplist_gets(u->sink->proplist, PA_PROP_DEVICE_DESCRIPTION));
|
||||
pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
|
||||
|
|
|
|||
|
|
@ -512,7 +512,7 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in
|
|||
goto fail;
|
||||
|
||||
pa_sink_input_new_data_init(&data);
|
||||
data.sink = sink;
|
||||
pa_sink_input_new_data_set_sink(&data, sink, FALSE);
|
||||
data.driver = __FILE__;
|
||||
pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "stream");
|
||||
pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue