mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
mainloop: convert from wallclock to rtclock
This is needed for the mainloop timeouts
This commit is contained in:
parent
70e9e622eb
commit
413c233b9a
3 changed files with 58 additions and 24 deletions
|
|
@ -508,6 +508,9 @@ struct pa_operation
|
||||||
|
|
||||||
bool pa_mainloop_api_is_pipewire(pa_mainloop_api *api);
|
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);
|
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);
|
void pa_operation_done(pa_operation *o);
|
||||||
int pa_operation_sync(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);
|
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)
|
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_mainloop *mainloop = SPA_CONTAINER_OF(a, pa_mainloop, api);
|
||||||
pa_time_event *ev;
|
pa_time_event *ev;
|
||||||
struct timespec ts;
|
|
||||||
|
|
||||||
ev = calloc(1, sizeof(pa_time_event));
|
ev = calloc(1, sizeof(pa_time_event));
|
||||||
ev->source = pw_loop_add_timer(mainloop->loop, source_timer_func, ev);
|
ev->source = pw_loop_add_timer(mainloop->loop, source_timer_func, ev);
|
||||||
ev->mainloop = mainloop;
|
ev->mainloop = mainloop;
|
||||||
ev->cb = cb;
|
ev->cb = cb;
|
||||||
ev->userdata = userdata;
|
ev->userdata = userdata;
|
||||||
|
pw_log_debug("new timer %p", ev);
|
||||||
|
|
||||||
if (tv == NULL) {
|
set_timer(ev, tv);
|
||||||
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);
|
|
||||||
|
|
||||||
return ev;
|
return ev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void api_time_restart(pa_time_event* e, const struct timeval *tv)
|
static void api_time_restart(pa_time_event* e, const struct timeval *tv)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
|
||||||
|
|
||||||
pa_assert(e);
|
pa_assert(e);
|
||||||
|
set_timer(e, tv);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void api_time_free(pa_time_event* e)
|
static void api_time_free(pa_time_event* e)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@
|
||||||
|
|
||||||
#include <pipewire/log.h>
|
#include <pipewire/log.h>
|
||||||
|
|
||||||
|
#include <pulse/timeval.h>
|
||||||
#include <pulse/rtclock.h>
|
#include <pulse/rtclock.h>
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
SPA_EXPORT
|
SPA_EXPORT
|
||||||
pa_usec_t pa_rtclock_now(void)
|
pa_usec_t pa_rtclock_now(void)
|
||||||
|
|
@ -36,3 +38,34 @@ pa_usec_t pa_rtclock_now(void)
|
||||||
return res;
|
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…
Add table
Add a link
Reference in a new issue