mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
node-driver: remove timers when not a driver
This commit is contained in:
parent
45c045382e
commit
35194d6de0
2 changed files with 91 additions and 27 deletions
|
|
@ -1623,6 +1623,7 @@ int spa_alsa_reassign_follower(struct state *state)
|
||||||
SPA_FLAG_IS_SET(state->position->clock.flags, SPA_IO_CLOCK_FLAG_FREEWHEEL);
|
SPA_FLAG_IS_SET(state->position->clock.flags, SPA_IO_CLOCK_FLAG_FREEWHEEL);
|
||||||
|
|
||||||
if (state->freewheel != freewheel) {
|
if (state->freewheel != freewheel) {
|
||||||
|
spa_log_debug(state->log, NAME" %p: freewheel %d->%d", state, state->freewheel, freewheel);
|
||||||
state->freewheel = freewheel;
|
state->freewheel = freewheel;
|
||||||
if (freewheel)
|
if (freewheel)
|
||||||
snd_pcm_pause(state->hndl, 1);
|
snd_pcm_pause(state->hndl, 1);
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ struct impl {
|
||||||
struct itimerspec timerspec;
|
struct itimerspec timerspec;
|
||||||
|
|
||||||
bool started;
|
bool started;
|
||||||
|
bool following;
|
||||||
uint64_t next_time;
|
uint64_t next_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -79,6 +80,69 @@ static void reset_props(struct props *props)
|
||||||
props->freewheel = DEFAULT_FREEWHEEL;
|
props->freewheel = DEFAULT_FREEWHEEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_timeout(struct impl *this, uint64_t next_time)
|
||||||
|
{
|
||||||
|
spa_log_trace(this->log, "set timeout %"PRIu64, next_time);
|
||||||
|
this->timerspec.it_value.tv_sec = next_time / SPA_NSEC_PER_SEC;
|
||||||
|
this->timerspec.it_value.tv_nsec = next_time % SPA_NSEC_PER_SEC;
|
||||||
|
spa_system_timerfd_settime(this->data_system,
|
||||||
|
this->timer_source.fd, SPA_FD_TIMER_ABSTIME, &this->timerspec, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_timers(struct impl *this)
|
||||||
|
{
|
||||||
|
struct timespec now;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if ((res = spa_system_clock_gettime(this->data_system, CLOCK_MONOTONIC, &now)) < 0)
|
||||||
|
return res;
|
||||||
|
this->next_time = SPA_TIMESPEC_TO_NSEC(&now);
|
||||||
|
|
||||||
|
if (this->following) {
|
||||||
|
set_timeout(this, 0);
|
||||||
|
} else {
|
||||||
|
set_timeout(this, this->next_time);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool is_following(struct impl *this)
|
||||||
|
{
|
||||||
|
return this->position && this->clock && this->position->clock.id != this->clock->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_reassign_follower(struct spa_loop *loop,
|
||||||
|
bool async,
|
||||||
|
uint32_t seq,
|
||||||
|
const void *data,
|
||||||
|
size_t size,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
struct impl *this = user_data;
|
||||||
|
set_timers(this);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int reassign_follower(struct impl *this)
|
||||||
|
{
|
||||||
|
bool following;
|
||||||
|
|
||||||
|
if (this->clock)
|
||||||
|
SPA_FLAG_UPDATE(this->clock->flags,
|
||||||
|
SPA_IO_CLOCK_FLAG_FREEWHEEL, this->props.freewheel);
|
||||||
|
|
||||||
|
if (!this->started)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
following = is_following(this);
|
||||||
|
if (following != this->following) {
|
||||||
|
spa_log_debug(this->log, NAME" %p: reassign follower %d->%d", this, this->following, following);
|
||||||
|
this->following = following;
|
||||||
|
spa_loop_invoke(this->data_loop, do_reassign_follower, 0, NULL, 0, true, this);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size)
|
static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size)
|
||||||
{
|
{
|
||||||
struct impl *this = object;
|
struct impl *this = object;
|
||||||
|
|
@ -99,15 +163,9 @@ static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size)
|
||||||
default:
|
default:
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
return 0;
|
reassign_follower(this);
|
||||||
}
|
|
||||||
|
|
||||||
static void set_timer(struct impl *this, uint64_t next_time)
|
return 0;
|
||||||
{
|
|
||||||
this->timerspec.it_value.tv_sec = next_time / SPA_NSEC_PER_SEC;
|
|
||||||
this->timerspec.it_value.tv_nsec = next_time % SPA_NSEC_PER_SEC;
|
|
||||||
spa_system_timerfd_settime(this->data_system,
|
|
||||||
this->timer_source.fd, SPA_FD_TIMER_ABSTIME, &this->timerspec, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_timeout(struct spa_source *source)
|
static void on_timeout(struct spa_source *source)
|
||||||
|
|
@ -138,8 +196,6 @@ static void on_timeout(struct spa_source *source)
|
||||||
this->next_time = nsec + duration * SPA_NSEC_PER_SEC / rate;
|
this->next_time = nsec + duration * SPA_NSEC_PER_SEC / rate;
|
||||||
|
|
||||||
if (SPA_LIKELY(this->clock)) {
|
if (SPA_LIKELY(this->clock)) {
|
||||||
SPA_FLAG_UPDATE(this->clock->flags,
|
|
||||||
SPA_IO_CLOCK_FLAG_FREEWHEEL, this->props.freewheel);
|
|
||||||
this->clock->nsec = nsec;
|
this->clock->nsec = nsec;
|
||||||
this->clock->position += duration;
|
this->clock->position += duration;
|
||||||
this->clock->duration = duration;
|
this->clock->duration = duration;
|
||||||
|
|
@ -151,7 +207,27 @@ static void on_timeout(struct spa_source *source)
|
||||||
spa_node_call_ready(&this->callbacks,
|
spa_node_call_ready(&this->callbacks,
|
||||||
SPA_STATUS_HAVE_DATA | SPA_STATUS_NEED_DATA);
|
SPA_STATUS_HAVE_DATA | SPA_STATUS_NEED_DATA);
|
||||||
|
|
||||||
set_timer(this, this->next_time);
|
set_timeout(this, this->next_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_start(struct impl *this)
|
||||||
|
{
|
||||||
|
if (this->started)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
this->following = is_following(this);
|
||||||
|
set_timers(this);
|
||||||
|
this->started = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_stop(struct impl *this)
|
||||||
|
{
|
||||||
|
if (!this->started)
|
||||||
|
return 0;
|
||||||
|
this->started = false;
|
||||||
|
set_timeout(this, 0);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int impl_node_send_command(void *object, const struct spa_command *command)
|
static int impl_node_send_command(void *object, const struct spa_command *command)
|
||||||
|
|
@ -164,24 +240,11 @@ static int impl_node_send_command(void *object, const struct spa_command *comman
|
||||||
|
|
||||||
switch (SPA_NODE_COMMAND_ID(command)) {
|
switch (SPA_NODE_COMMAND_ID(command)) {
|
||||||
case SPA_NODE_COMMAND_Start:
|
case SPA_NODE_COMMAND_Start:
|
||||||
{
|
do_start(this);
|
||||||
struct timespec now;
|
|
||||||
|
|
||||||
if (this->started)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
||||||
this->next_time = SPA_TIMESPEC_TO_NSEC(&now);
|
|
||||||
this->started = true;
|
|
||||||
set_timer(this, this->next_time);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case SPA_NODE_COMMAND_Suspend:
|
case SPA_NODE_COMMAND_Suspend:
|
||||||
case SPA_NODE_COMMAND_Pause:
|
case SPA_NODE_COMMAND_Pause:
|
||||||
if (!this->started)
|
do_stop(this);
|
||||||
return 0;
|
|
||||||
this->started = false;
|
|
||||||
set_timer(this, 0);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
|
@ -249,7 +312,7 @@ static int impl_node_process(void *object)
|
||||||
if (this->props.freewheel) {
|
if (this->props.freewheel) {
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
this->next_time = SPA_TIMESPEC_TO_NSEC(&now);
|
this->next_time = SPA_TIMESPEC_TO_NSEC(&now);
|
||||||
set_timer(this, this->next_time);
|
set_timeout(this, this->next_time);
|
||||||
}
|
}
|
||||||
return SPA_STATUS_OK;
|
return SPA_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue