mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-10-14 20:02:38 +00:00
mainloop: convert from wallclock to rtclock
This is needed for the mainloop timeouts
This commit is contained in:
parent
70e9e622eb
commit
413c233b9a
|
@ -508,6 +508,9 @@ struct pa_operation
|
|||
|
||||
bool pa_mainloop_api_is_pipewire(pa_mainloop_api *api);
|
||||
|
||||
#define PA_TIMEVAL_RTCLOCK ((time_t) (1LU << 30))
|
||||
struct timeval* pa_rtclock_from_wallclock(struct timeval *tv);
|
||||
|
||||
pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb, size_t userdata_size);
|
||||
void pa_operation_done(pa_operation *o);
|
||||
int pa_operation_sync(pa_operation *o);
|
||||
|
|
|
@ -116,48 +116,46 @@ static void source_timer_func(void *data, uint64_t expirations)
|
|||
ev->cb(&ev->mainloop->api, ev, &tv, ev->userdata);
|
||||
}
|
||||
|
||||
static void set_timer(pa_time_event *ev, const struct timeval *tv)
|
||||
{
|
||||
pa_mainloop *mainloop = ev->mainloop;
|
||||
struct timespec ts;
|
||||
struct timeval ttv = *tv;
|
||||
|
||||
if (tv == NULL) {
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1;
|
||||
} else {
|
||||
if ((tv->tv_usec & PA_TIMEVAL_RTCLOCK) == 0)
|
||||
pa_rtclock_from_wallclock(&ttv);
|
||||
ts.tv_sec = ttv.tv_sec;
|
||||
ts.tv_nsec = ttv.tv_usec * 1000LL;
|
||||
}
|
||||
pw_log_debug("set timer %p %ld %ld", ev, ts.tv_sec, ts.tv_nsec);
|
||||
pw_loop_update_timer(mainloop->loop, ev->source, &ts, NULL, true);
|
||||
}
|
||||
|
||||
static pa_time_event* api_time_new(pa_mainloop_api*a, const struct timeval *tv, pa_time_event_cb_t cb, void *userdata)
|
||||
{
|
||||
pa_mainloop *mainloop = SPA_CONTAINER_OF(a, pa_mainloop, api);
|
||||
pa_time_event *ev;
|
||||
struct timespec ts;
|
||||
|
||||
ev = calloc(1, sizeof(pa_time_event));
|
||||
ev->source = pw_loop_add_timer(mainloop->loop, source_timer_func, ev);
|
||||
ev->mainloop = mainloop;
|
||||
ev->cb = cb;
|
||||
ev->userdata = userdata;
|
||||
pw_log_debug("new timer %p", ev);
|
||||
|
||||
if (tv == NULL) {
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1;
|
||||
}
|
||||
else {
|
||||
ts.tv_sec = tv->tv_sec;
|
||||
ts.tv_nsec = tv->tv_usec * 1000LL;
|
||||
}
|
||||
pw_log_debug("new timer %p %ld %ld", ev, ts.tv_sec, ts.tv_nsec);
|
||||
pw_loop_update_timer(mainloop->loop, ev->source, &ts, NULL, true);
|
||||
set_timer(ev, tv);
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
static void api_time_restart(pa_time_event* e, const struct timeval *tv)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
pa_assert(e);
|
||||
|
||||
if (tv == NULL) {
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1;
|
||||
}
|
||||
else {
|
||||
ts.tv_sec = tv->tv_sec;
|
||||
ts.tv_nsec = tv->tv_usec * 1000LL;
|
||||
}
|
||||
pw_log_debug("io %p", e);
|
||||
pw_loop_update_timer(e->mainloop->loop, e->source, &ts, NULL, true);
|
||||
set_timer(e, tv);
|
||||
}
|
||||
|
||||
static void api_time_free(pa_time_event* e)
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
|
||||
#include <pipewire/log.h>
|
||||
|
||||
#include <pulse/timeval.h>
|
||||
#include <pulse/rtclock.h>
|
||||
#include "internal.h"
|
||||
|
||||
SPA_EXPORT
|
||||
pa_usec_t pa_rtclock_now(void)
|
||||
|
@ -36,3 +38,34 @@ pa_usec_t pa_rtclock_now(void)
|
|||
return res;
|
||||
}
|
||||
|
||||
static struct timeval *pa_rtclock_get(struct timeval *tv)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
pa_assert(tv);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
tv->tv_sec = ts.tv_sec;
|
||||
tv->tv_usec = ts.tv_nsec / PA_NSEC_PER_USEC;
|
||||
return tv;
|
||||
}
|
||||
|
||||
struct timeval* pa_rtclock_from_wallclock(struct timeval *tv)
|
||||
{
|
||||
struct timeval wc_now, rt_now;
|
||||
|
||||
pa_assert(tv);
|
||||
|
||||
pa_gettimeofday(&wc_now);
|
||||
pa_rtclock_get(&rt_now);
|
||||
|
||||
if (pa_timeval_cmp(&wc_now, tv) < 0)
|
||||
pa_timeval_add(&rt_now, pa_timeval_diff(tv, &wc_now));
|
||||
else
|
||||
pa_timeval_sub(&rt_now, pa_timeval_diff(&wc_now, tv));
|
||||
|
||||
*tv = rt_now;
|
||||
|
||||
return tv;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue