mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
link: use DISABLED flag on port of inactive links
Don't unlink the ports of an inactive link because then it might be possible that the scheduler can't recycle a buffer, instead use a port flag to mark the ports disabled and change to scheduler to skip those ports.
This commit is contained in:
parent
a8fa4383a1
commit
0eb44b340a
6 changed files with 16 additions and 9 deletions
|
|
@ -49,7 +49,7 @@ static inline int spa_graph_impl_need_input(void *data, struct spa_graph_node *n
|
||||||
struct spa_graph_node *pnode;
|
struct spa_graph_node *pnode;
|
||||||
uint32_t prequired, pready;
|
uint32_t prequired, pready;
|
||||||
|
|
||||||
if ((pport = p->peer) == NULL) {
|
if ((pport = p->peer) == NULL || (pport->flags & SPA_GRAPH_PORT_FLAG_DISABLED)) {
|
||||||
spa_debug("node %p port %p has no peer", node, p);
|
spa_debug("node %p port %p has no peer", node, p);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +94,7 @@ static inline int spa_graph_impl_have_output(void *data, struct spa_graph_node *
|
||||||
struct spa_graph_node *pnode;
|
struct spa_graph_node *pnode;
|
||||||
uint32_t prequired, pready;
|
uint32_t prequired, pready;
|
||||||
|
|
||||||
if ((pport = p->peer) == NULL) {
|
if ((pport = p->peer) == NULL || (pport->flags & SPA_GRAPH_PORT_FLAG_DISABLED)) {
|
||||||
spa_debug("node %p port %p has no peer", node, p);
|
spa_debug("node %p port %p has no peer", node, p);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ struct spa_graph_node {
|
||||||
struct spa_graph *graph; /**< owner graph */
|
struct spa_graph *graph; /**< owner graph */
|
||||||
struct spa_list ports[2]; /**< list of input and output ports */
|
struct spa_list ports[2]; /**< list of input and output ports */
|
||||||
struct spa_list ready_link; /**< link for scheduler */
|
struct spa_list ready_link; /**< link for scheduler */
|
||||||
#define SPA_GRAPH_NODE_FLAG_ASYNC (1 << 0)
|
#define SPA_GRAPH_NODE_FLAG_ASYNC (1 << 0)
|
||||||
uint32_t flags; /**< node flags */
|
uint32_t flags; /**< node flags */
|
||||||
uint32_t required[2]; /**< required number of ports */
|
uint32_t required[2]; /**< required number of ports */
|
||||||
uint32_t ready[2]; /**< number of ports with data */
|
uint32_t ready[2]; /**< number of ports with data */
|
||||||
|
|
@ -74,6 +74,7 @@ struct spa_graph_port {
|
||||||
struct spa_graph_node *node; /**< owner node */
|
struct spa_graph_node *node; /**< owner node */
|
||||||
enum spa_direction direction; /**< port direction */
|
enum spa_direction direction; /**< port direction */
|
||||||
uint32_t port_id; /**< port id */
|
uint32_t port_id; /**< port id */
|
||||||
|
#define SPA_GRAPH_PORT_FLAG_DISABLED (1 << 0)
|
||||||
uint32_t flags; /**< port flags */
|
uint32_t flags; /**< port flags */
|
||||||
struct spa_io_buffers *io; /**< io area of the port */
|
struct spa_io_buffers *io; /**< io area of the port */
|
||||||
struct spa_graph_port *peer; /**< peer */
|
struct spa_graph_port *peer; /**< peer */
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,10 @@ extern "C" {
|
||||||
#define SPA_RESULT_ASYNC_SEQ(res) ((res) & SPA_ASYNC_SEQ_MASK)
|
#define SPA_RESULT_ASYNC_SEQ(res) ((res) & SPA_ASYNC_SEQ_MASK)
|
||||||
#define SPA_RESULT_RETURN_ASYNC(seq) (SPA_ASYNC_BIT | ((seq) & SPA_ASYNC_SEQ_MASK))
|
#define SPA_RESULT_RETURN_ASYNC(seq) (SPA_ASYNC_BIT | ((seq) & SPA_ASYNC_SEQ_MASK))
|
||||||
|
|
||||||
|
#define SPA_FLAG_CHECK(field,flag) (((field) & (flag)) == (flag))
|
||||||
|
#define SPA_FLAG_SET(field,flag) ((field) |= (flag))
|
||||||
|
#define SPA_FLAG_UNSET(field,flag) ((field) &= ~(flag))
|
||||||
|
|
||||||
enum spa_direction {
|
enum spa_direction {
|
||||||
SPA_DIRECTION_INPUT = 0,
|
SPA_DIRECTION_INPUT = 0,
|
||||||
SPA_DIRECTION_OUTPUT = 1,
|
SPA_DIRECTION_OUTPUT = 1,
|
||||||
|
|
|
||||||
|
|
@ -413,7 +413,6 @@ pull_frames(struct state *state,
|
||||||
|
|
||||||
if (total_frames == 0 && do_pull) {
|
if (total_frames == 0 && do_pull) {
|
||||||
total_frames = SPA_MIN(frames, state->threshold);
|
total_frames = SPA_MIN(frames, state->threshold);
|
||||||
spa_log_warn(state->log, "write %zd frames of silence", total_frames);
|
|
||||||
snd_pcm_areas_silence(my_areas, offset, state->channels, total_frames, state->format);
|
snd_pcm_areas_silence(my_areas, offset, state->channels, total_frames, state->format);
|
||||||
state->underrun += total_frames;
|
state->underrun += total_frames;
|
||||||
underrun = true;
|
underrun = true;
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@ static inline void try_pull(struct impl *this, uint32_t frames, bool do_pull)
|
||||||
struct spa_io_buffers *io = this->io;
|
struct spa_io_buffers *io = this->io;
|
||||||
|
|
||||||
if (spa_list_is_empty(&this->ready) && do_pull) {
|
if (spa_list_is_empty(&this->ready) && do_pull) {
|
||||||
spa_log_trace(this->log, "alsa-util %p: %d", this, io->status);
|
spa_log_trace(this->log, "a2dp-sink %p: %d", this, io->status);
|
||||||
io->status = SPA_STATUS_NEED_BUFFER;
|
io->status = SPA_STATUS_NEED_BUFFER;
|
||||||
if (this->range) {
|
if (this->range) {
|
||||||
this->range->offset = this->sample_count * this->frame_size;
|
this->range->offset = this->sample_count * this->frame_size;
|
||||||
|
|
|
||||||
|
|
@ -712,7 +712,8 @@ do_activate_link(struct spa_loop *loop,
|
||||||
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
||||||
{
|
{
|
||||||
struct pw_link *this = user_data;
|
struct pw_link *this = user_data;
|
||||||
spa_graph_port_link(&this->rt.out_port, &this->rt.in_port);
|
SPA_FLAG_UNSET(this->rt.out_port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
|
||||||
|
SPA_FLAG_UNSET(this->rt.in_port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -953,7 +954,8 @@ do_deactivate_link(struct spa_loop *loop,
|
||||||
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
||||||
{
|
{
|
||||||
struct pw_link *this = user_data;
|
struct pw_link *this = user_data;
|
||||||
spa_graph_port_unlink(&this->rt.out_port);
|
SPA_FLAG_SET(this->rt.out_port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
|
||||||
|
SPA_FLAG_SET(this->rt.in_port.flags, SPA_GRAPH_PORT_FLAG_DISABLED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1165,13 +1167,14 @@ struct pw_link *pw_link_new(struct pw_core *core,
|
||||||
spa_graph_port_init(&this->rt.out_port,
|
spa_graph_port_init(&this->rt.out_port,
|
||||||
PW_DIRECTION_OUTPUT,
|
PW_DIRECTION_OUTPUT,
|
||||||
this->rt.out_port.port_id,
|
this->rt.out_port.port_id,
|
||||||
0,
|
SPA_GRAPH_PORT_FLAG_DISABLED,
|
||||||
&this->io);
|
&this->io);
|
||||||
spa_graph_port_init(&this->rt.in_port,
|
spa_graph_port_init(&this->rt.in_port,
|
||||||
PW_DIRECTION_INPUT,
|
PW_DIRECTION_INPUT,
|
||||||
this->rt.in_port.port_id,
|
this->rt.in_port.port_id,
|
||||||
0,
|
SPA_GRAPH_PORT_FLAG_DISABLED,
|
||||||
&this->io);
|
&this->io);
|
||||||
|
spa_graph_port_link(&this->rt.out_port, &this->rt.in_port);
|
||||||
|
|
||||||
this->rt.in_port.scheduler_data = this;
|
this->rt.in_port.scheduler_data = this;
|
||||||
this->rt.out_port.scheduler_data = this;
|
this->rt.out_port.scheduler_data = this;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue