sink, source: Add support for nodes

This commit is contained in:
Tanu Kaskinen 2013-07-03 14:09:08 +03:00
parent b7bf725f50
commit 66f5a68732
4 changed files with 74 additions and 0 deletions

View file

@ -83,6 +83,9 @@ pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data) {
pa_zero(*data);
data->proplist = pa_proplist_new();
data->ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_device_port_unref);
pa_node_new_data_init(&data->node_data);
pa_node_new_data_set_type(&data->node_data, PA_NODE_TYPE_SINK);
pa_node_new_data_set_direction(&data->node_data, PA_DIRECTION_OUTPUT);
return data;
}
@ -136,9 +139,16 @@ void pa_sink_new_data_set_port(pa_sink_new_data *data, const char *port) {
data->active_port = pa_xstrdup(port);
}
void pa_sink_new_data_set_create_node(pa_sink_new_data *data, bool create) {
pa_assert(data);
data->create_node = create;
}
void pa_sink_new_data_done(pa_sink_new_data *data) {
pa_assert(data);
pa_node_new_data_done(&data->node_data);
pa_proplist_free(data->proplist);
if (data->ports)
@ -368,6 +378,18 @@ pa_sink* pa_sink_new(
pa_source_set_fixed_latency(s->monitor_source, s->thread_info.fixed_latency);
pa_source_set_max_rewind(s->monitor_source, s->thread_info.max_rewind);
if (data->create_node) {
if (!data->node_data.description)
pa_node_new_data_set_description(&data->node_data, pa_sink_get_description(s));
if (!(s->node = pa_node_new(s->core, &data->node_data))) {
pa_log("Failed to create a node for sink %s.", s->name);
goto fail;
}
s->node->owner = s;
}
pt = pa_proplist_to_string_sep(s->proplist, "\n ");
pa_log_info("Created sink %u \"%s\" with sample spec %s and channel map %s\n %s",
s->index,
@ -648,6 +670,9 @@ void pa_sink_put(pa_sink* s) {
pa_source_put(s->monitor_source);
if (s->node)
pa_node_put(s->node);
pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index);
pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PUT], s);
}
@ -673,6 +698,9 @@ void pa_sink_unlink(pa_sink* s) {
if (linked)
pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s);
if (s->node)
pa_node_unlink(s->node);
if (s->state != PA_SINK_UNLINKED && s->name)
pa_namereg_unregister(s->core, s->name);
@ -717,6 +745,9 @@ static void sink_free(pa_object *o) {
if (s->state != PA_SINK_INIT)
pa_log_info("Freeing sink %u \"%s\"", s->index, s->name);
if (s->node)
pa_node_free(s->node);
if (s->monitor_source) {
pa_source_unref(s->monitor_source);
s->monitor_source = NULL;

View file

@ -37,6 +37,7 @@ typedef struct pa_sink_volume_change pa_sink_volume_change;
#include <pulsecore/core.h>
#include <pulsecore/idxset.h>
#include <pulsecore/memchunk.h>
#include <pulsecore/node.h>
#include <pulsecore/source.h>
#include <pulsecore/module.h>
#include <pulsecore/asyncmsgq.h>
@ -84,6 +85,7 @@ struct pa_sink {
unsigned n_corked;
pa_source *monitor_source;
pa_sink_input *input_to_master; /* non-NULL only for filter sinks */
pa_node *node;
pa_volume_t base_volume; /* shall be constant */
unsigned n_volume_steps; /* shall be constant */
@ -357,6 +359,9 @@ typedef struct pa_sink_new_data {
bool save_port:1;
bool save_volume:1;
bool save_muted:1;
bool create_node;
pa_node_new_data node_data;
} pa_sink_new_data;
pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data);
@ -367,6 +372,7 @@ void pa_sink_new_data_set_alternate_sample_rate(pa_sink_new_data *data, const ui
void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume);
void pa_sink_new_data_set_muted(pa_sink_new_data *data, bool mute);
void pa_sink_new_data_set_port(pa_sink_new_data *data, const char *port);
void pa_sink_new_data_set_create_node(pa_sink_new_data *data, bool create);
void pa_sink_new_data_done(pa_sink_new_data *data);
/*** To be called exclusively by the sink driver, from main context */

View file

@ -74,6 +74,9 @@ pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data) {
pa_zero(*data);
data->proplist = pa_proplist_new();
data->ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_device_port_unref);
pa_node_new_data_init(&data->node_data);
pa_node_new_data_set_type(&data->node_data, PA_NODE_TYPE_SOURCE);
pa_node_new_data_set_direction(&data->node_data, PA_DIRECTION_INPUT);
return data;
}
@ -127,9 +130,16 @@ void pa_source_new_data_set_port(pa_source_new_data *data, const char *port) {
data->active_port = pa_xstrdup(port);
}
void pa_source_new_data_set_create_node(pa_source_new_data *data, bool create) {
pa_assert(data);
data->create_node = create;
}
void pa_source_new_data_done(pa_source_new_data *data) {
pa_assert(data);
pa_node_new_data_done(&data->node_data);
pa_proplist_free(data->proplist);
if (data->ports)
@ -323,6 +333,18 @@ pa_source* pa_source_new(
if (s->card)
pa_assert_se(pa_idxset_put(s->card->sources, s, NULL) >= 0);
if (data->create_node) {
if (!data->node_data.description)
pa_node_new_data_set_description(&data->node_data, pa_source_get_description(s));
if (!(s->node = pa_node_new(s->core, &data->node_data))) {
pa_log("Failed to create a node for source %s.", s->name);
goto fail;
}
s->node->owner = s;
}
pt = pa_proplist_to_string_sep(s->proplist, "\n ");
pa_log_info("Created source %u \"%s\" with sample spec %s and channel map %s\n %s",
s->index,
@ -592,6 +614,9 @@ void pa_source_put(pa_source *s) {
else
pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0);
if (s->node)
pa_node_put(s->node);
pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index);
pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PUT], s);
}
@ -612,6 +637,9 @@ void pa_source_unlink(pa_source *s) {
if (linked)
pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], s);
if (s->node)
pa_node_unlink(s->node);
if (s->state != PA_SOURCE_UNLINKED && s->name)
pa_namereg_unregister(s->core, s->name);
@ -653,6 +681,9 @@ static void source_free(pa_object *o) {
if (s->state != PA_SOURCE_INIT)
pa_log_info("Freeing source %u \"%s\"", s->index, s->name);
if (s->node)
pa_node_free(s->node);
if (s->outputs)
pa_idxset_free(s->outputs, NULL);

View file

@ -37,6 +37,7 @@ typedef struct pa_source_volume_change pa_source_volume_change;
#include <pulsecore/core.h>
#include <pulsecore/idxset.h>
#include <pulsecore/memchunk.h>
#include <pulsecore/node.h>
#include <pulsecore/sink.h>
#include <pulsecore/module.h>
#include <pulsecore/asyncmsgq.h>
@ -84,6 +85,7 @@ struct pa_source {
unsigned n_corked;
pa_sink *monitor_of; /* may be NULL */
pa_source_output *output_from_master; /* non-NULL only for filter sources */
pa_node *node;
pa_volume_t base_volume; /* shall be constant */
unsigned n_volume_steps; /* shall be constant */
@ -294,6 +296,9 @@ typedef struct pa_source_new_data {
bool save_port:1;
bool save_volume:1;
bool save_muted:1;
bool create_node;
pa_node_new_data node_data;
} pa_source_new_data;
pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data);
@ -304,6 +309,7 @@ void pa_source_new_data_set_alternate_sample_rate(pa_source_new_data *data, cons
void pa_source_new_data_set_volume(pa_source_new_data *data, const pa_cvolume *volume);
void pa_source_new_data_set_muted(pa_source_new_data *data, bool mute);
void pa_source_new_data_set_port(pa_source_new_data *data, const char *port);
void pa_source_new_data_set_create_node(pa_source_new_data *data, bool create);
void pa_source_new_data_done(pa_source_new_data *data);
/*** To be called exclusively by the source driver, from main context */