core: Add extended stream API to support compressed formats

This is the beginning of work to support compressed formats natively in
PulseAudio. This adds a pa_stream_new_extended() that takes a format
structure, sends it to the server (=> protocol extension) and has the
server negotiate with the appropropriate sink to figure out what format
it should use.

This is work in progress, and works only with PCM streams. Actual
compressed format support in some sink needs to be implemented, and
extensive testing is required.

More details on how this is supposed to work is available at:
http://pulseaudio.org/wiki/PassthroughSupport
This commit is contained in:
Arun Raghavan 2011-02-28 13:23:23 +05:30
parent 47e0f91aa2
commit 0ac2cfce6d
25 changed files with 347 additions and 82 deletions

View file

@ -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");

View file

@ -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");

View file

@ -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");
}
}
}

View file

@ -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");

View file

@ -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;

View file

@ -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");

View file

@ -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);

View file

@ -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");

View file

@ -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);

View file

@ -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);
}

View file

@ -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");

View file

@ -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,