mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
Make scheduler more generic
Add some callbacks to trigger push and pull in a graph Remove the scheduler, make some implementations of graph push/pull functions. Add some properties to jack clients and nodes Fix the parent of the clients. Notify link format changes
This commit is contained in:
parent
eba2b82c8e
commit
bece3a013b
20 changed files with 248 additions and 158 deletions
|
|
@ -31,39 +31,39 @@ extern "C" {
|
|||
#define SPA_GRAPH_STATE_CHECK_IN 2
|
||||
#define SPA_GRAPH_STATE_CHECK_OUT 3
|
||||
|
||||
struct spa_graph_scheduler {
|
||||
struct spa_graph_data {
|
||||
struct spa_graph *graph;
|
||||
struct spa_list ready;
|
||||
struct spa_graph_node *node;
|
||||
};
|
||||
|
||||
static inline void spa_graph_scheduler_init(struct spa_graph_scheduler *sched,
|
||||
struct spa_graph *graph)
|
||||
static inline void spa_graph_data_init(struct spa_graph_data *data,
|
||||
struct spa_graph *graph)
|
||||
{
|
||||
sched->graph = graph;
|
||||
spa_list_init(&sched->ready);
|
||||
sched->node = NULL;
|
||||
data->graph = graph;
|
||||
spa_list_init(&data->ready);
|
||||
data->node = NULL;
|
||||
}
|
||||
|
||||
static inline int spa_graph_scheduler_input(void *data)
|
||||
static inline int spa_graph_node_impl_input(void *data)
|
||||
{
|
||||
struct spa_node *n = data;
|
||||
return spa_node_process_input(n);
|
||||
}
|
||||
|
||||
static inline int spa_graph_scheduler_output(void *data)
|
||||
static inline int spa_graph_node_impl_output(void *data)
|
||||
{
|
||||
struct spa_node *n = data;
|
||||
return spa_node_process_output(n);
|
||||
}
|
||||
|
||||
static const struct spa_graph_node_callbacks spa_graph_scheduler_default = {
|
||||
static const struct spa_graph_node_callbacks spa_graph_node_impl_default = {
|
||||
SPA_VERSION_GRAPH_NODE_CALLBACKS,
|
||||
spa_graph_scheduler_input,
|
||||
spa_graph_scheduler_output,
|
||||
spa_graph_node_impl_input,
|
||||
spa_graph_node_impl_output,
|
||||
};
|
||||
|
||||
static inline void spa_scheduler_port_check(struct spa_graph_scheduler *sched, struct spa_graph_port *port)
|
||||
static inline void spa_graph_data_port_check(struct spa_graph_data *data, struct spa_graph_port *port)
|
||||
{
|
||||
struct spa_graph_node *node = port->node;
|
||||
|
||||
|
|
@ -75,23 +75,23 @@ static inline void spa_scheduler_port_check(struct spa_graph_scheduler *sched, s
|
|||
if (node->required_in > 0 && node->ready_in == node->required_in) {
|
||||
node->state = SPA_GRAPH_STATE_IN;
|
||||
if (node->ready_link.next == NULL)
|
||||
spa_list_insert(sched->ready.prev, &node->ready_link);
|
||||
spa_list_insert(data->ready.prev, &node->ready_link);
|
||||
} else if (node->ready_link.next) {
|
||||
spa_list_remove(&node->ready_link);
|
||||
node->ready_link.next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool spa_graph_scheduler_iterate(struct spa_graph_scheduler *sched)
|
||||
static inline bool spa_graph_data_iterate(struct spa_graph_data *data)
|
||||
{
|
||||
bool res;
|
||||
int state;
|
||||
struct spa_graph_port *p;
|
||||
struct spa_graph_node *n;
|
||||
|
||||
res = !spa_list_is_empty(&sched->ready);
|
||||
res = !spa_list_is_empty(&data->ready);
|
||||
if (res) {
|
||||
n = spa_list_first(&sched->ready, struct spa_graph_node, ready_link);
|
||||
n = spa_list_first(&data->ready, struct spa_graph_node, ready_link);
|
||||
|
||||
spa_list_remove(&n->ready_link);
|
||||
n->ready_link.next = NULL;
|
||||
|
|
@ -106,9 +106,9 @@ static inline bool spa_graph_scheduler_iterate(struct spa_graph_scheduler *sched
|
|||
else if (state == SPA_RESULT_HAVE_BUFFER)
|
||||
n->state = SPA_GRAPH_STATE_CHECK_OUT;
|
||||
debug("node %p processed input state %d\n", n, n->state);
|
||||
if (n == sched->node)
|
||||
if (n == data->node)
|
||||
break;
|
||||
spa_list_insert(sched->ready.prev, &n->ready_link);
|
||||
spa_list_append(&data->ready, &n->ready_link);
|
||||
break;
|
||||
|
||||
case SPA_GRAPH_STATE_OUT:
|
||||
|
|
@ -118,7 +118,7 @@ static inline bool spa_graph_scheduler_iterate(struct spa_graph_scheduler *sched
|
|||
else if (state == SPA_RESULT_HAVE_BUFFER)
|
||||
n->state = SPA_GRAPH_STATE_CHECK_OUT;
|
||||
debug("node %p processed output state %d\n", n, n->state);
|
||||
spa_list_insert(sched->ready.prev, &n->ready_link);
|
||||
spa_list_append(&data->ready, &n->ready_link);
|
||||
break;
|
||||
|
||||
case SPA_GRAPH_STATE_CHECK_IN:
|
||||
|
|
@ -126,10 +126,10 @@ static inline bool spa_graph_scheduler_iterate(struct spa_graph_scheduler *sched
|
|||
spa_list_for_each(p, &n->ports[SPA_DIRECTION_INPUT], link) {
|
||||
struct spa_graph_node *pn = p->peer->node;
|
||||
if (p->io->status == SPA_RESULT_NEED_BUFFER) {
|
||||
if (pn != sched->node
|
||||
if (pn != data->node
|
||||
|| pn->flags & SPA_GRAPH_NODE_FLAG_ASYNC) {
|
||||
pn->state = SPA_GRAPH_STATE_OUT;
|
||||
spa_list_insert(sched->ready.prev,
|
||||
spa_list_append(&data->ready,
|
||||
&pn->ready_link);
|
||||
}
|
||||
} else if (p->io->status == SPA_RESULT_OK)
|
||||
|
|
@ -137,35 +137,52 @@ static inline bool spa_graph_scheduler_iterate(struct spa_graph_scheduler *sched
|
|||
}
|
||||
case SPA_GRAPH_STATE_CHECK_OUT:
|
||||
spa_list_for_each(p, &n->ports[SPA_DIRECTION_OUTPUT], link)
|
||||
spa_scheduler_port_check(sched, p->peer);
|
||||
spa_graph_data_port_check(data, p->peer);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
res = !spa_list_is_empty(&sched->ready);
|
||||
res = !spa_list_is_empty(&data->ready);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline void spa_graph_scheduler_pull(struct spa_graph_scheduler *sched, struct spa_graph_node *node)
|
||||
static inline int spa_graph_impl_need_input(void *data, struct spa_graph_node *node)
|
||||
{
|
||||
struct spa_graph_data *d = data;
|
||||
debug("node %p start pull\n", node);
|
||||
node->state = SPA_GRAPH_STATE_CHECK_IN;
|
||||
sched->node = node;
|
||||
d->node = node;
|
||||
if (node->ready_link.next == NULL)
|
||||
spa_list_insert(sched->ready.prev, &node->ready_link);
|
||||
spa_list_append(&d->ready, &node->ready_link);
|
||||
|
||||
while(spa_graph_data_iterate(data));
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static inline void spa_graph_scheduler_push(struct spa_graph_scheduler *sched, struct spa_graph_node *node)
|
||||
static inline int spa_graph_impl_have_output(void *data, struct spa_graph_node *node)
|
||||
{
|
||||
struct spa_graph_data *d = data;
|
||||
debug("node %p start push\n", node);
|
||||
node->state = SPA_GRAPH_STATE_OUT;
|
||||
sched->node = node;
|
||||
d->node = node;
|
||||
if (node->ready_link.next == NULL)
|
||||
spa_list_insert(sched->ready.prev, &node->ready_link);
|
||||
spa_list_append(&d->ready, &node->ready_link);
|
||||
|
||||
while(spa_graph_data_iterate(data));
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static const struct spa_graph_callbacks spa_graph_impl_default = {
|
||||
SPA_VERSION_GRAPH_CALLBACKS,
|
||||
.need_input = spa_graph_impl_need_input,
|
||||
.have_output = spa_graph_impl_have_output,
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,37 +26,26 @@ extern "C" {
|
|||
|
||||
#include <spa/graph.h>
|
||||
|
||||
struct spa_graph_scheduler {
|
||||
struct spa_graph *graph;
|
||||
};
|
||||
|
||||
static inline void spa_graph_scheduler_init(struct spa_graph_scheduler *sched,
|
||||
struct spa_graph *graph)
|
||||
{
|
||||
sched->graph = graph;
|
||||
}
|
||||
|
||||
static inline int spa_graph_node_scheduler_input(void *data)
|
||||
static inline int spa_graph_node_impl_input(void *data)
|
||||
{
|
||||
struct spa_node *n = data;
|
||||
return spa_node_process_input(n);
|
||||
}
|
||||
|
||||
static inline int spa_graph_node_scheduler_output(void *data)
|
||||
static inline int spa_graph_node_impl_output(void *data)
|
||||
{
|
||||
struct spa_node *n = data;
|
||||
return spa_node_process_output(n);
|
||||
}
|
||||
|
||||
|
||||
static const struct spa_graph_node_callbacks spa_graph_node_scheduler_default = {
|
||||
static const struct spa_graph_node_callbacks spa_graph_node_impl_default = {
|
||||
SPA_VERSION_GRAPH_NODE_CALLBACKS,
|
||||
spa_graph_node_scheduler_input,
|
||||
spa_graph_node_scheduler_output,
|
||||
spa_graph_node_impl_input,
|
||||
spa_graph_node_impl_output,
|
||||
};
|
||||
|
||||
static inline int spa_graph_port_scheduler_reuse_buffer(void *data,
|
||||
uint32_t buffer_id)
|
||||
static inline int spa_graph_port_impl_reuse_buffer(void *data,
|
||||
uint32_t buffer_id)
|
||||
{
|
||||
struct spa_graph_port *port = data;
|
||||
struct spa_node *node = port->node->callbacks_data;
|
||||
|
|
@ -64,12 +53,12 @@ static inline int spa_graph_port_scheduler_reuse_buffer(void *data,
|
|||
return spa_node_port_reuse_buffer(node, port->port_id, buffer_id);
|
||||
}
|
||||
|
||||
static const struct spa_graph_port_callbacks spa_graph_port_scheduler_default = {
|
||||
static const struct spa_graph_port_callbacks spa_graph_port_impl_default = {
|
||||
SPA_VERSION_GRAPH_PORT_CALLBACKS,
|
||||
spa_graph_port_scheduler_reuse_buffer,
|
||||
spa_graph_port_impl_reuse_buffer,
|
||||
};
|
||||
|
||||
static inline void spa_graph_scheduler_pull(struct spa_graph_scheduler *sched, struct spa_graph_node *node)
|
||||
static inline int spa_graph_impl_need_input(void *data, struct spa_graph_node *node)
|
||||
{
|
||||
struct spa_graph_port *p;
|
||||
struct spa_graph_node *n, *t;
|
||||
|
|
@ -99,7 +88,7 @@ static inline void spa_graph_scheduler_pull(struct spa_graph_scheduler *sched, s
|
|||
n->state = n->callbacks->process_output(n->callbacks_data);
|
||||
debug("peer %p processed out %d\n", n, n->state);
|
||||
if (n->state == SPA_RESULT_NEED_BUFFER)
|
||||
spa_graph_scheduler_pull(sched, n);
|
||||
spa_graph_need_input(n->graph, n);
|
||||
else {
|
||||
spa_list_for_each(p, &n->ports[SPA_DIRECTION_OUTPUT], link) {
|
||||
if (p->io->status == SPA_RESULT_HAVE_BUFFER)
|
||||
|
|
@ -123,43 +112,14 @@ static inline void spa_graph_scheduler_pull(struct spa_graph_scheduler *sched, s
|
|||
}
|
||||
}
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static inline bool spa_graph_scheduler_iterate(struct spa_graph_scheduler *sched)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void spa_graph_scheduler_push(struct spa_graph_scheduler *sched, struct spa_graph_node *node);
|
||||
|
||||
static inline void spa_graph_scheduler_chain(struct spa_graph_scheduler *sched,
|
||||
struct spa_list *ready)
|
||||
{
|
||||
struct spa_graph_node *n, *t;
|
||||
struct spa_graph_port *p;
|
||||
|
||||
|
||||
spa_list_for_each_safe(n, t, ready, ready_link) {
|
||||
n->state = n->callbacks->process_input(n->callbacks_data);
|
||||
debug("node %p chain processed in %d\n", n, n->state);
|
||||
if (n->state == SPA_RESULT_HAVE_BUFFER)
|
||||
spa_graph_scheduler_push(sched, n);
|
||||
else {
|
||||
n->ready_in = 0;
|
||||
spa_list_for_each(p, &n->ports[SPA_DIRECTION_INPUT], link) {
|
||||
if (p->io->status == SPA_RESULT_OK && !(n->flags & SPA_GRAPH_NODE_FLAG_ASYNC))
|
||||
n->ready_in++;
|
||||
}
|
||||
}
|
||||
spa_list_remove(&n->ready_link);
|
||||
n->ready_link.next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void spa_graph_scheduler_push(struct spa_graph_scheduler *sched, struct spa_graph_node *node)
|
||||
static inline int spa_graph_impl_have_output(void *data, struct spa_graph_node *node)
|
||||
{
|
||||
struct spa_graph_port *p;
|
||||
struct spa_list ready;
|
||||
struct spa_graph_node *n, *t;
|
||||
|
||||
debug("node %p start push\n", node);
|
||||
|
||||
|
|
@ -182,7 +142,22 @@ static inline void spa_graph_scheduler_push(struct spa_graph_scheduler *sched, s
|
|||
spa_list_append(&ready, &pnode->ready_link);
|
||||
}
|
||||
|
||||
spa_graph_scheduler_chain(sched, &ready);
|
||||
spa_list_for_each_safe(n, t, &ready, ready_link) {
|
||||
n->state = n->callbacks->process_input(n->callbacks_data);
|
||||
debug("node %p chain processed in %d\n", n, n->state);
|
||||
if (n->state == SPA_RESULT_HAVE_BUFFER)
|
||||
spa_graph_have_output(n->graph, n);
|
||||
else {
|
||||
n->ready_in = 0;
|
||||
spa_list_for_each(p, &n->ports[SPA_DIRECTION_INPUT], link) {
|
||||
if (p->io->status == SPA_RESULT_OK &&
|
||||
!(n->flags & SPA_GRAPH_NODE_FLAG_ASYNC))
|
||||
n->ready_in++;
|
||||
}
|
||||
}
|
||||
spa_list_remove(&n->ready_link);
|
||||
n->ready_link.next = NULL;
|
||||
}
|
||||
|
||||
node->state = node->callbacks->process_output(node->callbacks_data);
|
||||
debug("node %p processed out %d\n", node, node->state);
|
||||
|
|
@ -193,8 +168,16 @@ static inline void spa_graph_scheduler_push(struct spa_graph_scheduler *sched, s
|
|||
node->ready_in++;
|
||||
}
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static const struct spa_graph_callbacks spa_graph_impl_default = {
|
||||
SPA_VERSION_GRAPH_CALLBACKS,
|
||||
.need_input = spa_graph_impl_need_input,
|
||||
.have_output = spa_graph_impl_have_output,
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -40,10 +40,23 @@ struct spa_graph;
|
|||
struct spa_graph_node;
|
||||
struct spa_graph_port;
|
||||
|
||||
struct spa_graph_callbacks {
|
||||
#define SPA_VERSION_GRAPH_CALLBACKS 0
|
||||
uint32_t version;
|
||||
|
||||
int (*need_input) (void *data, struct spa_graph_node *node);
|
||||
int (*have_output) (void *data, struct spa_graph_node *node);
|
||||
};
|
||||
|
||||
struct spa_graph {
|
||||
struct spa_list nodes;
|
||||
const struct spa_graph_callbacks *callbacks;
|
||||
void *callbacks_data;
|
||||
};
|
||||
|
||||
#define spa_graph_need_input(g,n) ((g)->callbacks->need_input((g)->callbacks_data, (n)))
|
||||
#define spa_graph_have_output(g,n) ((g)->callbacks->have_output((g)->callbacks_data, (n)))
|
||||
|
||||
struct spa_graph_node_callbacks {
|
||||
#define SPA_VERSION_GRAPH_NODE_CALLBACKS 0
|
||||
uint32_t version;
|
||||
|
|
@ -61,6 +74,7 @@ struct spa_graph_port_callbacks {
|
|||
|
||||
struct spa_graph_node {
|
||||
struct spa_list link; /**< link in graph nodes list */
|
||||
struct spa_graph *graph; /**< owner graph */
|
||||
struct spa_list ports[2]; /**< list of input and output ports */
|
||||
struct spa_list ready_link; /**< link for scheduler */
|
||||
#define SPA_GRAPH_NODE_FLAG_ASYNC (1 << 0)
|
||||
|
|
@ -93,6 +107,15 @@ static inline void spa_graph_init(struct spa_graph *graph)
|
|||
spa_list_init(&graph->nodes);
|
||||
}
|
||||
|
||||
static inline void
|
||||
spa_graph_set_callbacks(struct spa_graph *graph,
|
||||
const struct spa_graph_callbacks *callbacks,
|
||||
void *data)
|
||||
{
|
||||
graph->callbacks = callbacks;
|
||||
graph->callbacks_data = data;
|
||||
}
|
||||
|
||||
static inline void
|
||||
spa_graph_node_init(struct spa_graph_node *node)
|
||||
{
|
||||
|
|
@ -116,6 +139,7 @@ static inline void
|
|||
spa_graph_node_add(struct spa_graph *graph,
|
||||
struct spa_graph_node *node)
|
||||
{
|
||||
node->graph = graph;
|
||||
node->state = SPA_RESULT_NEED_BUFFER;
|
||||
node->ready_link.next = NULL;
|
||||
spa_list_append(&graph->nodes, &node->link);
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ struct data {
|
|||
uint32_t n_support;
|
||||
|
||||
struct spa_graph graph;
|
||||
struct spa_graph_scheduler sched;
|
||||
struct spa_graph_data graph_data;
|
||||
struct spa_graph_node source_node;
|
||||
struct spa_graph_port source_out;
|
||||
struct spa_graph_port volume_in;
|
||||
|
|
@ -230,10 +230,7 @@ static void on_sink_event(void *data, struct spa_event *event)
|
|||
static void on_sink_need_input(void *_data)
|
||||
{
|
||||
struct data *data = _data;
|
||||
|
||||
spa_graph_scheduler_pull(&data->sched, &data->sink_node);
|
||||
|
||||
while (spa_graph_scheduler_iterate(&data->sched));
|
||||
spa_graph_need_input(&data->graph, &data->sink_node);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -340,13 +337,13 @@ static int make_nodes(struct data *data, const char *device)
|
|||
spa_node_port_set_io(data->sink, SPA_DIRECTION_INPUT, 0, &data->volume_sink_io[0]);
|
||||
|
||||
spa_graph_node_init(&data->source_node);
|
||||
spa_graph_node_set_callbacks(&data->source_node, &spa_graph_scheduler_default, data->source);
|
||||
spa_graph_node_set_callbacks(&data->source_node, &spa_graph_node_impl_default, data->source);
|
||||
spa_graph_node_add(&data->graph, &data->source_node);
|
||||
spa_graph_port_init(&data->source_out, SPA_DIRECTION_OUTPUT, 0, 0, &data->source_volume_io[0]);
|
||||
spa_graph_port_add(&data->source_node, &data->source_out);
|
||||
|
||||
spa_graph_node_init(&data->volume_node);
|
||||
spa_graph_node_set_callbacks(&data->volume_node, &spa_graph_scheduler_default, data->volume);
|
||||
spa_graph_node_set_callbacks(&data->volume_node, &spa_graph_node_impl_default, data->volume);
|
||||
spa_graph_node_add(&data->graph, &data->volume_node);
|
||||
spa_graph_port_init(&data->volume_in, SPA_DIRECTION_INPUT, 0, 0, &data->source_volume_io[0]);
|
||||
spa_graph_port_add(&data->volume_node, &data->volume_in);
|
||||
|
|
@ -357,7 +354,7 @@ static int make_nodes(struct data *data, const char *device)
|
|||
spa_graph_port_add(&data->volume_node, &data->volume_out);
|
||||
|
||||
spa_graph_node_init(&data->sink_node);
|
||||
spa_graph_node_set_callbacks(&data->sink_node, &spa_graph_scheduler_default, data->sink);
|
||||
spa_graph_node_set_callbacks(&data->sink_node, &spa_graph_node_impl_default, data->sink);
|
||||
spa_graph_node_add(&data->graph, &data->sink_node);
|
||||
spa_graph_port_init(&data->sink_in, SPA_DIRECTION_INPUT, 0, 0, &data->volume_sink_io[0]);
|
||||
spa_graph_port_add(&data->sink_node, &data->sink_in);
|
||||
|
|
@ -532,7 +529,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
|
||||
spa_graph_init(&data.graph);
|
||||
spa_graph_scheduler_init(&data.sched, &data.graph);
|
||||
spa_graph_data_init(&data.graph_data, &data.graph);
|
||||
spa_graph_set_callbacks(&data.graph, &spa_graph_impl_default, &data.graph_data);
|
||||
|
||||
data.map = &default_map.map;
|
||||
data.log = &default_log.log;
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ struct data {
|
|||
uint32_t n_support;
|
||||
|
||||
struct spa_graph graph;
|
||||
struct spa_graph_scheduler sched;
|
||||
struct spa_graph_data graph_data;
|
||||
struct spa_graph_node source1_node;
|
||||
struct spa_graph_port source1_out;
|
||||
struct spa_graph_node source2_node;
|
||||
|
|
@ -242,9 +242,7 @@ static void on_sink_need_input(void *_data)
|
|||
{
|
||||
struct data *data = _data;
|
||||
#ifdef USE_GRAPH
|
||||
spa_graph_scheduler_pull(&data->sched, &data->sink_node);
|
||||
while (spa_graph_scheduler_iterate(&data->sched));
|
||||
|
||||
spa_graph_need_input(&data->graph, &data->sink_node);
|
||||
#else
|
||||
int res;
|
||||
|
||||
|
|
@ -416,19 +414,19 @@ static int make_nodes(struct data *data, const char *device)
|
|||
|
||||
#ifdef USE_GRAPH
|
||||
spa_graph_node_init(&data->source1_node);
|
||||
spa_graph_node_set_callbacks(&data->source1_node, &spa_graph_scheduler_default, data->source1);
|
||||
spa_graph_node_set_callbacks(&data->source1_node, &spa_graph_node_impl_default, data->source1);
|
||||
spa_graph_port_init(&data->source1_out, SPA_DIRECTION_OUTPUT, 0, 0, &data->source1_mix_io[0]);
|
||||
spa_graph_port_add(&data->source1_node, &data->source1_out);
|
||||
spa_graph_node_add(&data->graph, &data->source1_node);
|
||||
|
||||
spa_graph_node_init(&data->source2_node);
|
||||
spa_graph_node_set_callbacks(&data->source2_node, &spa_graph_scheduler_default, data->source2);
|
||||
spa_graph_node_set_callbacks(&data->source2_node, &spa_graph_node_impl_default, data->source2);
|
||||
spa_graph_port_init(&data->source2_out, SPA_DIRECTION_OUTPUT, 0, 0, &data->source2_mix_io[0]);
|
||||
spa_graph_port_add(&data->source2_node, &data->source2_out);
|
||||
spa_graph_node_add(&data->graph, &data->source2_node);
|
||||
|
||||
spa_graph_node_init(&data->mix_node);
|
||||
spa_graph_node_set_callbacks(&data->mix_node, &spa_graph_scheduler_default, data->mix);
|
||||
spa_graph_node_set_callbacks(&data->mix_node, &spa_graph_node_impl_default, data->mix);
|
||||
spa_graph_port_init(&data->mix_in[0], SPA_DIRECTION_INPUT,
|
||||
data->mix_ports[0], 0, &data->source1_mix_io[0]);
|
||||
spa_graph_port_add(&data->mix_node, &data->mix_in[0]);
|
||||
|
|
@ -444,7 +442,7 @@ static int make_nodes(struct data *data, const char *device)
|
|||
spa_graph_port_add(&data->mix_node, &data->mix_out);
|
||||
|
||||
spa_graph_node_init(&data->sink_node);
|
||||
spa_graph_node_set_callbacks(&data->sink_node, &spa_graph_scheduler_default, data->sink);
|
||||
spa_graph_node_set_callbacks(&data->sink_node, &spa_graph_node_impl_default, data->sink);
|
||||
spa_graph_port_init(&data->sink_in, SPA_DIRECTION_INPUT, 0, 0, &data->mix_sink_io[0]);
|
||||
spa_graph_port_add(&data->sink_node, &data->sink_in);
|
||||
spa_graph_node_add(&data->graph, &data->sink_node);
|
||||
|
|
@ -651,7 +649,8 @@ int main(int argc, char *argv[])
|
|||
data.data_loop.invoke = do_invoke;
|
||||
|
||||
spa_graph_init(&data.graph);
|
||||
spa_graph_scheduler_init(&data.sched, &data.graph);
|
||||
spa_graph_data_init(&data.graph_data, &data.graph);
|
||||
spa_graph_set_callbacks(&data.graph, &spa_graph_impl_default, &data.graph_data);
|
||||
|
||||
if ((str = getenv("SPA_DEBUG")))
|
||||
data.log->level = atoi(str);
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ struct data {
|
|||
int iterations;
|
||||
|
||||
struct spa_graph graph;
|
||||
struct spa_graph_scheduler sched;
|
||||
struct spa_graph_data graph_data;
|
||||
struct spa_graph_node source_node;
|
||||
struct spa_graph_port source_out;
|
||||
struct spa_graph_port sink_in;
|
||||
|
|
@ -225,8 +225,7 @@ static void on_sink_pull(struct data *data)
|
|||
spa_node_process_output(data->source);
|
||||
spa_node_process_input(data->sink);
|
||||
} else {
|
||||
spa_graph_scheduler_pull(&data->sched, &data->sink_node);
|
||||
while (spa_graph_scheduler_iterate(&data->sched));
|
||||
spa_graph_need_input(&data->graph, &data->sink_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -237,8 +236,7 @@ static void on_source_push(struct data *data)
|
|||
spa_node_process_output(data->source);
|
||||
spa_node_process_input(data->sink);
|
||||
} else {
|
||||
spa_graph_scheduler_push(&data->sched, &data->source_node);
|
||||
while (spa_graph_scheduler_iterate(&data->sched));
|
||||
spa_graph_have_output(&data->graph, &data->source_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -364,7 +362,7 @@ static int make_nodes(struct data *data)
|
|||
spa_node_port_set_io(data->sink, SPA_DIRECTION_INPUT, 0, &data->source_sink_io[0]);
|
||||
|
||||
spa_graph_node_init(&data->source_node);
|
||||
spa_graph_node_set_callbacks(&data->source_node, &spa_graph_scheduler_default, data->source);
|
||||
spa_graph_node_set_callbacks(&data->source_node, &spa_graph_node_impl_default, data->source);
|
||||
spa_graph_node_add(&data->graph, &data->source_node);
|
||||
|
||||
data->source_node.flags = (data->mode & MODE_ASYNC_PUSH) ? SPA_GRAPH_NODE_FLAG_ASYNC : 0;
|
||||
|
|
@ -372,7 +370,7 @@ static int make_nodes(struct data *data)
|
|||
spa_graph_port_add(&data->source_node, &data->source_out);
|
||||
|
||||
spa_graph_node_init(&data->sink_node);
|
||||
spa_graph_node_set_callbacks(&data->sink_node, &spa_graph_scheduler_default, data->sink);
|
||||
spa_graph_node_set_callbacks(&data->sink_node, &spa_graph_node_impl_default, data->sink);
|
||||
spa_graph_node_add(&data->graph, &data->sink_node);
|
||||
|
||||
data->sink_node.flags = (data->mode & MODE_ASYNC_PULL) ? SPA_GRAPH_NODE_FLAG_ASYNC : 0;
|
||||
|
|
@ -529,7 +527,8 @@ int main(int argc, char *argv[])
|
|||
const char *str;
|
||||
|
||||
spa_graph_init(&data.graph);
|
||||
spa_graph_scheduler_init(&data.sched, &data.graph);
|
||||
spa_graph_data_init(&data.graph_data, &data.graph);
|
||||
spa_graph_set_callbacks(&data.graph, &spa_graph_impl_default, &data.graph_data);
|
||||
|
||||
data.map = &default_map.map;
|
||||
data.log = &default_log.log;
|
||||
|
|
|
|||
|
|
@ -340,16 +340,17 @@ handle_activate_client(struct client *client)
|
|||
jack_graph_manager_next_stop(mgr);
|
||||
|
||||
jc = server->client_table[ref_num];
|
||||
if (jc)
|
||||
if (jc) {
|
||||
notify_client(jc, ref_num, NULL, jack_notify_ActivateClient, true, "", 0, 0);
|
||||
jc->activated = true;
|
||||
spa_list_append(&impl->rt.nodes, &jc->node->graph_link);
|
||||
}
|
||||
|
||||
for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++)
|
||||
notify_clients(impl, jack_notify_PortRegistrationOnCallback, false, "", input_ports[i], 0);
|
||||
for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++)
|
||||
notify_clients(impl, jack_notify_PortRegistrationOnCallback, false, "", output_ports[i], 0);
|
||||
|
||||
jc->activated = true;
|
||||
|
||||
CheckWrite(&result, sizeof(int));
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -400,8 +401,10 @@ static int client_deactivate(struct impl *impl, int ref_num)
|
|||
jack_graph_manager_next_stop(mgr);
|
||||
|
||||
jc = server->client_table[ref_num];
|
||||
if (jc)
|
||||
if (jc) {
|
||||
jc->activated = false;
|
||||
spa_list_remove(&jc->node->graph_link);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -516,6 +519,7 @@ handle_client_open(struct client *client)
|
|||
const struct ucred *ucred;
|
||||
struct sockaddr_un addr;
|
||||
struct pw_jack_node *node;
|
||||
struct pw_properties *properties;
|
||||
|
||||
CheckSize(kClientOpen_size);
|
||||
CheckRead(&PID, sizeof(int));
|
||||
|
|
@ -524,12 +528,16 @@ handle_client_open(struct client *client)
|
|||
|
||||
ucred = pw_client_get_ucred(client->client);
|
||||
|
||||
properties = pw_properties_new(NULL, NULL);
|
||||
pw_properties_setf(properties, "application.jack.PID", "%d", PID);
|
||||
pw_properties_setf(properties, "application.jack.UUID", "%d", UUID);
|
||||
|
||||
node = pw_jack_node_new(impl->core,
|
||||
pw_module_get_global(impl->module),
|
||||
pw_client_get_global(client->client),
|
||||
server,
|
||||
name,
|
||||
ucred ? ucred->pid : PID,
|
||||
NULL,
|
||||
properties,
|
||||
sizeof(struct jack_client));
|
||||
if (node == NULL) {
|
||||
pw_log_error("module-jack %p: can't create node", impl);
|
||||
|
|
@ -563,7 +571,6 @@ handle_client_open(struct client *client)
|
|||
pw_log_debug("module-jack %p: Added client %d \"%s\"", impl, ref_num, name);
|
||||
|
||||
spa_list_append(&client->jack_clients, &jc->client_link);
|
||||
spa_list_append(&impl->rt.nodes, &jc->node->graph_link);
|
||||
|
||||
if (notify_add_client(impl, jc, name, ref_num) < 0) {
|
||||
pw_log_error("module-jack %p: can't notify add_client", impl);
|
||||
|
|
@ -949,6 +956,7 @@ static struct client *client_new(struct impl *impl, int fd)
|
|||
struct pw_client *client;
|
||||
socklen_t len;
|
||||
struct ucred ucred, *ucredp;
|
||||
struct pw_properties *properties;
|
||||
|
||||
len = sizeof(ucred);
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) {
|
||||
|
|
@ -958,8 +966,17 @@ static struct client *client_new(struct impl *impl, int fd)
|
|||
ucredp = &ucred;
|
||||
}
|
||||
|
||||
properties = pw_properties_new("pipewire.protocol", "protocol-jack", NULL);
|
||||
if (properties == NULL)
|
||||
goto no_props;
|
||||
|
||||
if (ucredp) {
|
||||
pw_properties_setf(properties, "application.process.id", "%d", ucredp->pid);
|
||||
pw_properties_setf(properties, "application.process.userid", "%d", ucredp->uid);
|
||||
}
|
||||
|
||||
client = pw_client_new(impl->core, pw_module_get_global(impl->module),
|
||||
ucredp, NULL, sizeof(struct client));
|
||||
ucredp, properties, sizeof(struct client));
|
||||
if (client == NULL)
|
||||
goto no_client;
|
||||
|
||||
|
|
@ -984,6 +1001,7 @@ static struct client *client_new(struct impl *impl, int fd)
|
|||
|
||||
no_source:
|
||||
free(this);
|
||||
no_props:
|
||||
no_client:
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1018,6 +1036,7 @@ static void jack_node_pull(void *data)
|
|||
do_notify, 0, sizeof(notify), ¬ify, false, impl);
|
||||
}
|
||||
|
||||
/* mix all input */
|
||||
spa_list_for_each(p, &n->ports[SPA_DIRECTION_INPUT], link) {
|
||||
if ((pp = p->peer) == NULL || ((pn = pp->node) == NULL))
|
||||
continue;
|
||||
|
|
@ -1039,13 +1058,14 @@ static void jack_node_push(void *data)
|
|||
|
||||
conn = jack_graph_manager_get_current(mgr);
|
||||
|
||||
activation = jack_connection_manager_get_activation(conn, server->freewheel_ref_num);
|
||||
if (activation != 0)
|
||||
pw_log_warn("resume %d, some client did not complete", activation);
|
||||
|
||||
jack_connection_manager_reset(conn, mgr->client_timing);
|
||||
|
||||
activation = jack_connection_manager_get_activation(conn, server->freewheel_ref_num);
|
||||
if (activation == 0)
|
||||
return;
|
||||
|
||||
pw_log_trace("resume %d", activation);
|
||||
jack_activation_count_signal(&conn->input_counter[server->freewheel_ref_num],
|
||||
&server->synchro_table[server->freewheel_ref_num]);
|
||||
|
||||
spa_list_for_each(p, &n->ports[SPA_DIRECTION_INPUT], link) {
|
||||
if ((pp = p->peer) == NULL || ((pn = pp->node) == NULL))
|
||||
|
|
@ -1055,16 +1075,25 @@ static void jack_node_push(void *data)
|
|||
|
||||
spa_list_for_each(node, &impl->rt.nodes, graph_link) {
|
||||
n = &node->node->rt.node;
|
||||
|
||||
spa_list_for_each(p, &n->ports[SPA_DIRECTION_OUTPUT], link) {
|
||||
if ((pp = p->peer) == NULL || ((pn = pp->node) == NULL))
|
||||
continue;
|
||||
pn->state = pn->callbacks->process_output(pn->callbacks_data);
|
||||
}
|
||||
n->state = n->callbacks->process_output(n->callbacks_data);
|
||||
|
||||
/* mix inputs */
|
||||
spa_list_for_each(p, &n->ports[SPA_DIRECTION_INPUT], link) {
|
||||
if ((pp = p->peer) == NULL || ((pn = pp->node) == NULL))
|
||||
continue;
|
||||
pn->state = pn->callbacks->process_output(pn->callbacks_data);
|
||||
pn->state = pn->callbacks->process_input(pn->callbacks_data);
|
||||
}
|
||||
|
||||
n->state = n->callbacks->process_input(n->callbacks_data);
|
||||
|
||||
/* tee outputs */
|
||||
spa_list_for_each(p, &n->ports[SPA_DIRECTION_OUTPUT], link) {
|
||||
if ((pp = p->peer) == NULL || ((pn = pp->node) == NULL))
|
||||
continue;
|
||||
|
|
@ -1340,7 +1369,7 @@ static int init_server(struct impl *impl, const char *name, bool promiscuous)
|
|||
}
|
||||
|
||||
|
||||
static struct impl *module_init(struct pw_module *module, struct pw_properties *properties)
|
||||
static bool module_init(struct pw_module *module, struct pw_properties *properties)
|
||||
{
|
||||
struct pw_core *core = pw_module_get_core(module);
|
||||
struct impl *impl;
|
||||
|
|
@ -1379,11 +1408,11 @@ static struct impl *module_init(struct pw_module *module, struct pw_properties *
|
|||
if (init_server(impl, name, promiscuous) < 0)
|
||||
goto error;
|
||||
|
||||
return impl;
|
||||
return true;
|
||||
|
||||
error:
|
||||
free(impl);
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
@ -1399,6 +1428,5 @@ static void module_destroy(struct impl *impl)
|
|||
|
||||
bool pipewire__module_init(struct pw_module *module, const char *args)
|
||||
{
|
||||
module_init(module, NULL);
|
||||
return true;
|
||||
return module_init(module, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -676,6 +676,10 @@ struct pw_jack_node *pw_jack_node_new(struct pw_core *core,
|
|||
struct jack_graph_manager *mgr = server->graph_manager;
|
||||
struct jack_connection_manager *conn;
|
||||
|
||||
if (properties == NULL)
|
||||
properties = pw_properties_new("jack.server.name", server->engine_control->server_name,
|
||||
"jack.name", name, NULL);
|
||||
|
||||
ref_num = jack_server_allocate_ref_num(server);
|
||||
if (ref_num == -1) {
|
||||
pw_log_error(NAME " %p: can't allocated ref_num", core);
|
||||
|
|
@ -690,6 +694,7 @@ struct pw_jack_node *pw_jack_node_new(struct pw_core *core,
|
|||
pw_log_error(NAME " %p: can't init synchro", core);
|
||||
return NULL;
|
||||
}
|
||||
pw_properties_setf(properties, "jack.ref-num", "%d", ref_num);
|
||||
|
||||
node = pw_node_new(core, NULL, parent, name, properties, sizeof(struct node_data) + user_data_size);
|
||||
if (node == NULL)
|
||||
|
|
@ -744,6 +749,10 @@ pw_jack_driver_new(struct pw_core *core,
|
|||
struct jack_connection_manager *conn;
|
||||
char n[REAL_JACK_PORT_NAME_SIZE];
|
||||
|
||||
if (properties == NULL)
|
||||
properties = pw_properties_new("jack.server.name", server->engine_control->server_name,
|
||||
"jack.name", name, NULL);
|
||||
|
||||
ref_num = jack_server_allocate_ref_num(server);
|
||||
if (ref_num == -1) {
|
||||
pw_log_error(NAME " %p: can't allocated ref_num", core);
|
||||
|
|
@ -758,6 +767,7 @@ pw_jack_driver_new(struct pw_core *core,
|
|||
pw_log_error(NAME " %p: can't init synchro", core);
|
||||
return NULL;
|
||||
}
|
||||
pw_properties_setf(properties, "jack.ref-num", "%d", ref_num);
|
||||
|
||||
node = pw_node_new(core, NULL, parent, name, properties, sizeof(struct node_data) + user_data_size);
|
||||
if (node == NULL)
|
||||
|
|
|
|||
|
|
@ -274,8 +274,10 @@ static inline bool jack_activation_count_signal(struct jack_activation_count *cn
|
|||
{
|
||||
bool res = true;
|
||||
|
||||
if (cnt->value == 0)
|
||||
if (cnt->value == 0) {
|
||||
pw_log_error("activation == 0");
|
||||
res = jack_synchro_signal(synchro);
|
||||
}
|
||||
else if (__atomic_sub_fetch(&cnt->value, 1, __ATOMIC_SEQ_CST) == 0)
|
||||
res = jack_synchro_signal(synchro);
|
||||
|
||||
|
|
@ -1012,7 +1014,7 @@ jack_engine_control_alloc(const char* name)
|
|||
ctrl = (struct jack_engine_control *)jack_shm_addr(&info);
|
||||
ctrl->info = info;
|
||||
|
||||
ctrl->buffer_size = 64;
|
||||
ctrl->buffer_size = 128;
|
||||
ctrl->sample_rate = 48000;
|
||||
ctrl->sync_mode = false;
|
||||
ctrl->temporary = false;
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <spa/graph-scheduler3.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ struct pw_client *pw_client_new(struct pw_core *core,
|
|||
if (impl == NULL)
|
||||
return NULL;
|
||||
|
||||
pw_log_debug("client %p: new", impl);
|
||||
pw_log_debug("client %p: new parent %d", impl, parent ? parent->id : 0);
|
||||
|
||||
this = &impl->this;
|
||||
this->core = core;
|
||||
|
|
@ -123,7 +123,7 @@ struct pw_client *pw_client_new(struct pw_core *core,
|
|||
|
||||
this->info.props = this->properties ? &this->properties->dict : NULL;
|
||||
|
||||
this->global = pw_core_add_global(core, this, parent, core->type.client, PW_VERSION_CLIENT,
|
||||
this->global = pw_core_add_global(core, NULL, parent, core->type.client, PW_VERSION_CLIENT,
|
||||
client_bind_func, this);
|
||||
|
||||
return this;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <spa/lib/debug.h>
|
||||
#include <spa/format-utils.h>
|
||||
#include <spa/graph-scheduler3.h>
|
||||
|
||||
#include <pipewire/pipewire.h>
|
||||
#include <pipewire/private.h>
|
||||
|
|
@ -338,7 +339,7 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, struct pw_properties *pro
|
|||
pw_map_init(&this->globals, 128, 32);
|
||||
|
||||
spa_graph_init(&this->rt.graph);
|
||||
spa_graph_scheduler_init(&this->rt.sched, &this->rt.graph);
|
||||
spa_graph_set_callbacks(&this->rt.graph, &spa_graph_impl_default, NULL);
|
||||
|
||||
spa_debug_set_type_map(this->type.map);
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ void pw_module_info_free(struct pw_module_info *info);
|
|||
|
||||
/** The client information. Extra information can be added in later versions \memberof pw_introspect */
|
||||
struct pw_client_info {
|
||||
#define PW_CLIENT_CHANGE_MASK_PROPS (1 << 0)
|
||||
uint64_t change_mask; /**< bitfield of changed fields since last call */
|
||||
struct spa_dict *props; /**< extra properties */
|
||||
};
|
||||
|
|
@ -164,6 +165,10 @@ pw_node_info_free(struct pw_node_info *info);
|
|||
|
||||
/** The link information. Extra information can be added in later versions \memberof pw_introspect */
|
||||
struct pw_link_info {
|
||||
#define PW_LINK_CHANGE_MASK_OUTPUT (1 << 0)
|
||||
#define PW_LINK_CHANGE_MASK_INPUT (1 << 1)
|
||||
#define PW_LINK_CHANGE_MASK_FORMAT (1 << 2)
|
||||
#define PW_LINK_CHANGE_MASK_PROPS (1 << 3)
|
||||
uint64_t change_mask; /**< bitfield of changed fields since last call */
|
||||
uint32_t output_node_id; /**< server side output node id */
|
||||
uint32_t output_port_id; /**< output port id */
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
int res = SPA_RESULT_ERROR, res2;
|
||||
struct spa_format *format, *current;
|
||||
char *error = NULL;
|
||||
struct pw_resource *resource;
|
||||
bool changed = true;
|
||||
|
||||
if (in_state != PW_PORT_STATE_CONFIGURE && out_state != PW_PORT_STATE_CONFIGURE)
|
||||
return SPA_RESULT_OK;
|
||||
|
|
@ -139,8 +141,10 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
pw_node_set_state(this->output->node, PW_NODE_STATE_SUSPENDED);
|
||||
out_state = PW_PORT_STATE_CONFIGURE;
|
||||
}
|
||||
else
|
||||
else {
|
||||
pw_node_update_state(this->output->node, PW_NODE_STATE_RUNNING, NULL);
|
||||
changed = false;
|
||||
}
|
||||
}
|
||||
if (in_state > PW_PORT_STATE_CONFIGURE && this->input->node->info.state == PW_NODE_STATE_IDLE) {
|
||||
if ((res = pw_port_get_format(this->input,
|
||||
|
|
@ -153,8 +157,10 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
pw_node_set_state(this->input->node, PW_NODE_STATE_SUSPENDED);
|
||||
in_state = PW_PORT_STATE_CONFIGURE;
|
||||
}
|
||||
else
|
||||
else {
|
||||
pw_node_update_state(this->input->node, PW_NODE_STATE_RUNNING, NULL);
|
||||
changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
pw_log_debug("link %p: doing set format", this);
|
||||
|
|
@ -181,10 +187,20 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
|
|||
pw_work_queue_add(impl->work, this->input->node, res2, complete_ready, this->input);
|
||||
}
|
||||
|
||||
|
||||
if (this->info.format)
|
||||
free(this->info.format);
|
||||
this->info.format = format;
|
||||
|
||||
if (changed) {
|
||||
this->info.change_mask |= PW_LINK_CHANGE_MASK_FORMAT;
|
||||
|
||||
spa_list_for_each(resource, &this->resource_list, link)
|
||||
pw_link_resource_info(resource, &this->info);
|
||||
|
||||
this->info.change_mask = 0;
|
||||
}
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
error:
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ struct pw_module *pw_module_load(struct pw_core *core, const char *name, const c
|
|||
this->info.args = args ? strdup(args) : NULL;
|
||||
this->info.props = NULL;
|
||||
|
||||
spa_list_insert(core->module_list.prev, &this->link);
|
||||
spa_list_append(&core->module_list, &this->link);
|
||||
this->global = pw_core_add_global(core, NULL, core->global,
|
||||
core->type.module, PW_VERSION_MODULE,
|
||||
module_bind_func, this);
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ static void node_need_input(void *data)
|
|||
struct impl *impl = data;
|
||||
struct pw_node *this = &impl->this;
|
||||
|
||||
spa_graph_scheduler_pull(this->rt.sched, &this->rt.node);
|
||||
spa_graph_need_input(this->rt.graph, &this->rt.node);
|
||||
}
|
||||
|
||||
static void node_have_output(void *data)
|
||||
|
|
@ -177,7 +177,7 @@ static void node_have_output(void *data)
|
|||
struct impl *impl = data;
|
||||
struct pw_node *this = &impl->this;
|
||||
|
||||
spa_graph_scheduler_push(this->rt.sched, &this->rt.node);
|
||||
spa_graph_have_output(this->rt.graph, &this->rt.node);
|
||||
}
|
||||
|
||||
static void node_unbind_func(void *data)
|
||||
|
|
@ -291,7 +291,7 @@ do_node_add(struct spa_loop *loop,
|
|||
{
|
||||
struct pw_node *this = user_data;
|
||||
|
||||
spa_graph_node_add(this->rt.sched->graph, &this->rt.node);
|
||||
spa_graph_node_add(this->rt.graph, &this->rt.node);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -393,7 +393,7 @@ struct pw_node *pw_node_new(struct pw_core *core,
|
|||
|
||||
this->data_loop = core->data_loop;
|
||||
|
||||
this->rt.sched = &core->rt.sched;
|
||||
this->rt.graph = &core->rt.graph;
|
||||
|
||||
spa_list_init(&this->resource_list);
|
||||
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ void pw_port_add(struct pw_port *port, struct pw_node *node)
|
|||
if (port->implementation->set_io)
|
||||
port->implementation->set_io(port->implementation_data, &port->io);
|
||||
|
||||
port->rt.graph = node->rt.sched->graph;
|
||||
port->rt.graph = node->rt.graph;
|
||||
pw_loop_invoke(node->data_loop, do_add_port, SPA_ID_INVALID, 0, NULL, false, port);
|
||||
|
||||
port_update_state(port, PW_PORT_STATE_CONFIGURE);
|
||||
|
|
|
|||
|
|
@ -24,8 +24,9 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <spa/graph.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <spa/graph-scheduler3.h>
|
||||
|
||||
#include "pipewire/mem.h"
|
||||
#include "pipewire/pipewire.h"
|
||||
|
|
@ -116,7 +117,6 @@ struct pw_core {
|
|||
uint32_t n_support; /**< number of support items */
|
||||
|
||||
struct {
|
||||
struct spa_graph_scheduler sched;
|
||||
struct spa_graph graph;
|
||||
} rt;
|
||||
};
|
||||
|
|
@ -218,7 +218,7 @@ struct pw_node {
|
|||
struct pw_loop *data_loop; /**< the data loop for this node */
|
||||
|
||||
struct {
|
||||
struct spa_graph_scheduler *sched;
|
||||
struct spa_graph *graph;
|
||||
struct spa_graph_node node;
|
||||
} rt;
|
||||
|
||||
|
|
|
|||
|
|
@ -424,15 +424,24 @@ static void handle_rtnode_message(struct pw_proxy *proxy, struct pw_client_node_
|
|||
struct spa_graph_node *n = &data->node->rt.node;
|
||||
|
||||
if (PW_CLIENT_NODE_MESSAGE_TYPE(message) == PW_CLIENT_NODE_MESSAGE_PROCESS_INPUT) {
|
||||
struct spa_list ready;
|
||||
struct spa_graph_port *port;
|
||||
struct spa_graph_port *port, *pp;
|
||||
struct spa_graph_node *pn;
|
||||
|
||||
spa_list_init(&ready);
|
||||
|
||||
spa_list_for_each(port, &n->ports[SPA_DIRECTION_INPUT], link)
|
||||
spa_list_insert(ready.prev, &port->peer->node->ready_link);
|
||||
|
||||
spa_graph_scheduler_chain(data->node->rt.sched, &ready);
|
||||
/* process all input in the mixers */
|
||||
spa_list_for_each(port, &n->ports[SPA_DIRECTION_INPUT], link) {
|
||||
pn = port->peer->node;
|
||||
pn->state = pn->callbacks->process_input(pn->callbacks_data);
|
||||
if (pn->state == SPA_RESULT_HAVE_BUFFER)
|
||||
spa_graph_have_output(data->node->rt.graph, pn);
|
||||
else {
|
||||
pn->ready_in = 0;
|
||||
spa_list_for_each(pp, &pn->ports[SPA_DIRECTION_INPUT], link) {
|
||||
if (pp->io->status == SPA_RESULT_OK &&
|
||||
!(pn->flags & SPA_GRAPH_NODE_FLAG_ASYNC))
|
||||
pn->ready_in++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (PW_CLIENT_NODE_MESSAGE_TYPE(message) == PW_CLIENT_NODE_MESSAGE_PROCESS_OUTPUT) {
|
||||
n->callbacks->process_output(n->callbacks_data);
|
||||
|
|
|
|||
|
|
@ -231,14 +231,15 @@ static void link_event_info(void *object, struct pw_link_info *info)
|
|||
printf("\ttype: %s (version %d)\n", PW_TYPE_INTERFACE__Link, data->version);
|
||||
if (print_all) {
|
||||
printf("%c\toutput-node-id: %u\n", MARK_CHANGE(0), info->output_node_id);
|
||||
printf("%c\toutput-port-id: %u\n", MARK_CHANGE(1), info->output_port_id);
|
||||
printf("%c\tinput-node-id: %u\n", MARK_CHANGE(2), info->input_node_id);
|
||||
printf("%c\tinput-port-id: %u\n", MARK_CHANGE(3), info->input_port_id);
|
||||
printf("%c\tformat:\n", MARK_CHANGE(4));
|
||||
printf("%c\toutput-port-id: %u\n", MARK_CHANGE(0), info->output_port_id);
|
||||
printf("%c\tinput-node-id: %u\n", MARK_CHANGE(1), info->input_node_id);
|
||||
printf("%c\tinput-port-id: %u\n", MARK_CHANGE(1), info->input_port_id);
|
||||
printf("%c\tformat:\n", MARK_CHANGE(2));
|
||||
if (info->format)
|
||||
spa_debug_format(info->format);
|
||||
else
|
||||
printf("\t none\n");
|
||||
print_properties(info->props, MARK_CHANGE(3));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue