mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-07 13:30:09 -05:00
node: improve position and transport
Reorganize some things, let the clients update the segment info in their own activation, then let the server merge it. This avoids clients stepping on eachother. When looping through the clients, copy the segment info when we encounter its owner. Remove the list of segment owners to the activation. This is better than in the activation because we can then just keep one list of owners. Remove the NONBLOCK flag from the eventfd so that we can do blocking reads as well. Just keep a reposition owner in the driver activation. This points to the node that has the reposition info. This avoid complicated synchronization to keep multiple nodes from stepping on eachother. Now they can just prepare the reposition info in their activation and set themselves as the reposition owner. The last one who succeeds wins.
This commit is contained in:
parent
ca34a75173
commit
faaf84286b
5 changed files with 97 additions and 86 deletions
|
|
@ -366,8 +366,19 @@ struct pw_node_activation {
|
|||
uint64_t finish_time;
|
||||
uint64_t prev_signal_time;
|
||||
|
||||
/* for drivers */
|
||||
struct spa_io_position position;
|
||||
/* updates */
|
||||
struct spa_io_segment reposition; /* reposition info, used when driver reposition_owner
|
||||
* has this node id */
|
||||
struct spa_io_segment segment; /* update for the extra segment info fields.
|
||||
* used when driver segment_owner has this node id */
|
||||
|
||||
/* for drivers, shared with all nodes */
|
||||
uint32_t segment_owner[32]; /* id of owners for each segment info struct.
|
||||
* nodes that want to update segment info need to
|
||||
* CAS their node id in this array. */
|
||||
struct spa_io_position position; /* contains current position and segment info.
|
||||
* extra info is updated by nodes that have set
|
||||
* themselves as owner in the segment structs */
|
||||
|
||||
uint64_t sync_timeout; /* sync timeout in nanoseconds
|
||||
* position goes to RUNNING without waiting any
|
||||
|
|
@ -381,20 +392,12 @@ struct pw_node_activation {
|
|||
uint64_t xrun_delay; /* delay of last xrun in microseconds */
|
||||
uint64_t max_delay; /* max of all xruns in microseconds */
|
||||
|
||||
struct {
|
||||
uint32_t seq;
|
||||
#define PW_NODE_ACTIVATION_UPDATE_COMMAND (1<<0)
|
||||
#define PW_NODE_ACTIVATION_UPDATE_REPOSITION (1<<2)
|
||||
#define PW_NODE_ACTIVATION_UPDATE_FLUSH (1<<3) /* flush out current segments and immediately
|
||||
* start the new one */
|
||||
uint32_t change_mask;
|
||||
#define PW_NODE_ACTIVATION_COMMAND_START 0
|
||||
#define PW_NODE_ACTIVATION_COMMAND_STOP 1
|
||||
uint32_t command; /* when change_mask & PW_NODE_ACTIVATION_UPDATE_COMMAND */
|
||||
struct spa_io_segment reposition; /* reposition information */
|
||||
struct spa_io_segment segment; /* update for the extra segment info
|
||||
* fields. */
|
||||
} pending;
|
||||
#define PW_NODE_ACTIVATION_COMMAND_NONE 0
|
||||
#define PW_NODE_ACTIVATION_COMMAND_START 1
|
||||
#define PW_NODE_ACTIVATION_COMMAND_STOP 2
|
||||
uint32_t command; /* next command */
|
||||
uint32_t reposition_owner; /* owner id with new reposition info, last one
|
||||
* to update wins */
|
||||
};
|
||||
|
||||
#define ATOMIC_CAS(v,ov,nv) \
|
||||
|
|
@ -408,6 +411,7 @@ struct pw_node_activation {
|
|||
#define ATOMIC_INC(s) __atomic_add_fetch(&(s), 1, __ATOMIC_SEQ_CST)
|
||||
#define ATOMIC_LOAD(s) __atomic_load_n(&(s), __ATOMIC_SEQ_CST)
|
||||
#define ATOMIC_STORE(s,v) __atomic_store_n(&(s), (v), __ATOMIC_SEQ_CST)
|
||||
#define ATOMIC_XCHG(s,v) __atomic_exchange_n(&(s), (v), __ATOMIC_SEQ_CST)
|
||||
|
||||
#define SEQ_WRITE(s) ATOMIC_INC(s)
|
||||
#define SEQ_WRITE_SUCCESS(s1,s2) ((s1) + 1 == (s2) && ((s2) & 1) == 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue