#pragma once #include #include // Synced: // () = other clients only // Pause: // - User input -> start fade and request pause from server // - Get response -> (start fade) arm pause or reseek if late // Resume: // - User input -> request resume from server // - Get response -> arm resume, apply offset to queued // Next/Prev: // - User input -> start fade request next from server // - Get response -> (start fade) arm pause, arm resume on next, then swap on pause // // Local: // Pause: // - User input -> start fade and pause immediately // Reumse: // - User input -> resume and fade in // Next/Prev: // - User input -> swap #define CAMU_PTS_PAUSED ((f64)0xffffffffffffffff) #define CAMU_PTS_SIGNAL_PAUSE ((f64)0x7fffffffffffffff) #define CAMU_PTS_CONSIDER_PAUSED(pts) (pts == CAMU_PTS_PAUSED || pts == CAMU_PTS_SIGNAL_PAUSE) enum { CAMU_CLOCK_PAUSED = 0 }; struct camu_clock { f64 base; f64 offset; atomic(f64) tick; atomic(f64) pause; atomic(bool) external_pause; f64 paused_at; atomic(f64) last_pts; void (*callback)(void *, u8); void *userdata; }; void camu_clock_init(struct camu_clock *clock, void (*callback)(void *, u8), void *userdata); void camu_clock_set(struct camu_clock *clock, f64 base); void camu_clock_offset(struct camu_clock *clock, f64 offset); void camu_clock_seek(struct camu_clock *clock, f64 base, u64 target); bool camu_clock_pause(struct camu_clock *clock, u64 target); void camu_clock_external_pause(struct camu_clock *clock); void camu_clock_resume(struct camu_clock *clock, u64 target); f64 camu_clock_get_base_pts(struct camu_clock *clock); f64 camu_clock_get_pts(struct camu_clock *clock, f64 latency, bool allow_set, bool *armed_for_pause); f64 camu_clock_get_last_pts(struct camu_clock *clock);