filter: don't copy position info

We copied the position information for the deprecated _get_time()
function. Don't do this anymore and just read the values from the
get_time() function directly.

They might race with the processing thread but that's why the
function is deprecated.

Improves performance in tight loops.
This commit is contained in:
Wim Taymans 2023-05-05 17:54:33 +02:00
parent 8452e6d28e
commit 93530df139

View file

@ -139,7 +139,6 @@ struct filter {
struct spa_process_latency_info process_latency; struct spa_process_latency_info process_latency;
struct data data; struct data data;
uintptr_t seq;
struct pw_time time; struct pw_time time;
uint64_t base_pos; uint64_t base_pos;
uint32_t clock_id; uint32_t clock_id;
@ -957,23 +956,6 @@ static int impl_port_reuse_buffer(void *object, uint32_t port_id, uint32_t buffe
return 0; return 0;
} }
static inline void copy_position(struct filter *impl)
{
struct spa_io_position *p = impl->rt.position;
if (SPA_UNLIKELY(p != NULL)) {
SEQ_WRITE(impl->seq);
impl->time.now = p->clock.nsec;
impl->time.rate = p->clock.rate;
if (SPA_UNLIKELY(impl->clock_id != p->clock.id)) {
impl->base_pos = p->clock.position - impl->time.ticks;
impl->clock_id = p->clock.id;
}
impl->time.ticks = p->clock.position - impl->base_pos;
impl->time.delay = 0;
SEQ_WRITE(impl->seq);
}
}
static int static int
do_call_process(struct spa_loop *loop, do_call_process(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)
@ -1028,12 +1010,12 @@ static int impl_node_process(void *object)
spa_list_for_each(p, &impl->port_list, link) { spa_list_for_each(p, &impl->port_list, link) {
struct spa_io_buffers *io = p->io; struct spa_io_buffers *io = p->io;
if (io == NULL || if (SPA_UNLIKELY(io == NULL ||
io->buffer_id >= p->n_buffers) io->buffer_id >= p->n_buffers))
continue; continue;
if (p->direction == SPA_DIRECTION_INPUT) { if (p->direction == SPA_DIRECTION_INPUT) {
if (io->status != SPA_STATUS_HAVE_DATA) if (SPA_UNLIKELY(io->status != SPA_STATUS_HAVE_DATA))
continue; continue;
/* push new buffer */ /* push new buffer */
@ -1042,7 +1024,7 @@ static int impl_node_process(void *object)
push_queue(p, &p->dequeued, b); push_queue(p, &p->dequeued, b);
drained = false; drained = false;
} else { } else {
if (io->status == SPA_STATUS_HAVE_DATA) if (SPA_UNLIKELY(io->status == SPA_STATUS_HAVE_DATA))
continue; continue;
/* recycle old buffer */ /* recycle old buffer */
@ -1052,18 +1034,17 @@ static int impl_node_process(void *object)
} }
} }
copy_position(impl);
call_process(impl); call_process(impl);
/** recycle/push queued buffers */ /** recycle/push queued buffers */
spa_list_for_each(p, &impl->port_list, link) { spa_list_for_each(p, &impl->port_list, link) {
struct spa_io_buffers *io = p->io; struct spa_io_buffers *io = p->io;
if (io == NULL) if (SPA_UNLIKELY(io == NULL))
continue; continue;
if (p->direction == SPA_DIRECTION_INPUT) { if (p->direction == SPA_DIRECTION_INPUT) {
if (io->status != SPA_STATUS_HAVE_DATA) if (SPA_UNLIKELY(io->status != SPA_STATUS_HAVE_DATA))
continue; continue;
/* pop buffer to recycle */ /* pop buffer to recycle */
@ -1075,7 +1056,7 @@ static int impl_node_process(void *object)
} }
io->status = SPA_STATUS_NEED_DATA; io->status = SPA_STATUS_NEED_DATA;
} else { } else {
if (io->status == SPA_STATUS_HAVE_DATA) if (SPA_UNLIKELY(io->status == SPA_STATUS_HAVE_DATA))
continue; continue;
if ((b = pop_queue(p, &p->queued)) != NULL) { if ((b = pop_queue(p, &p->queued)) != NULL) {
@ -1090,7 +1071,7 @@ static int impl_node_process(void *object)
} }
} }
impl->drained = drained; impl->drained = drained;
if (drained && impl->draining) if (SPA_UNLIKELY(drained && impl->draining))
call_drained(impl); call_drained(impl);
return SPA_STATUS_NEED_DATA | SPA_STATUS_HAVE_DATA; return SPA_STATUS_NEED_DATA | SPA_STATUS_HAVE_DATA;
@ -1921,18 +1902,22 @@ SPA_EXPORT
int pw_filter_get_time(struct pw_filter *filter, struct pw_time *time) int pw_filter_get_time(struct pw_filter *filter, struct pw_time *time)
{ {
struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this); struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this);
uintptr_t seq1, seq2; struct spa_io_position *p = impl->position;
do { if (SPA_LIKELY(p != NULL)) {
seq1 = SEQ_READ(impl->seq); impl->time.now = p->clock.nsec;
impl->time.rate = p->clock.rate;
if (SPA_UNLIKELY(impl->clock_id != p->clock.id)) {
impl->base_pos = p->clock.position - impl->time.ticks;
impl->clock_id = p->clock.id;
}
impl->time.ticks = p->clock.position - impl->base_pos;
impl->time.delay = 0;
*time = impl->time; *time = impl->time;
seq2 = SEQ_READ(impl->seq); }
} while (!SEQ_READ_SUCCESS(seq1, seq2));
pw_log_trace("%p: %"PRIi64" %"PRIi64" %"PRIu64" %d/%d ", filter, pw_log_trace("%p: %"PRIi64" %"PRIi64" %"PRIu64" %d/%d ", filter,
time->now, time->delay, time->ticks, time->now, time->delay, time->ticks,
time->rate.num, time->rate.denom); time->rate.num, time->rate.denom);
return 0; return 0;
} }