summaryrefslogtreecommitdiff
path: root/src/buffer/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer/clock.c')
-rw-r--r--src/buffer/clock.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/src/buffer/clock.c b/src/buffer/clock.c
index 19f721c..1adb945 100644
--- a/src/buffer/clock.c
+++ b/src/buffer/clock.c
@@ -43,6 +43,7 @@ void camu_clock_set(struct camu_clock *clock, f64 base)
clock->offset = 0.0;
atomic_store(f64)(&clock->tick, SET, AL_ATOMIC_RELAXED);
atomic_store(f64)(&clock->pause, PAUSED, AL_ATOMIC_RELAXED);
+ atomic_store(bool)(&clock->pause_for_swap, false, AL_ATOMIC_RELAXED);
atomic_store(bool)(&clock->external_pause, false, AL_ATOMIC_RELAXED);
clock->paused_at = NOT_STARTED;
atomic_store(f64)(&clock->last_pts, base, AL_ATOMIC_RELAXED);
@@ -106,7 +107,12 @@ bool camu_clock_pause(struct camu_clock *clock, u64 target)
}
}
-void camu_clock_external_pause(struct camu_clock *clock)
+void camu_clock_set_pause_for_swap(struct camu_clock *clock)
+{
+ atomic_store(bool)(&clock->pause_for_swap, true, AL_ATOMIC_RELAXED);
+}
+
+void camu_clock_set_external_pause(struct camu_clock *clock)
{
atomic_store(bool)(&clock->external_pause, true, AL_ATOMIC_RELAXED);
}
@@ -116,8 +122,6 @@ void camu_clock_resume(struct camu_clock *clock, u64 target)
{
al_assert(clock->paused_at != NOT_PAUSED);
- atomic_store(bool)(&clock->external_pause, false, AL_ATOMIC_RELAXED);
-
f64 tick = nn_get_tick();
if (target > 0) {
tick = calc_tick_offset(tick, nn_get_timestamp(), target);
@@ -142,15 +146,10 @@ void camu_clock_resume(struct camu_clock *clock, u64 target)
clock->paused_at = NOT_PAUSED;
- atomic_store(f64)(&clock->pause, RUNNING, AL_ATOMIC_RELEASE);
-}
+ atomic_store(bool)(&clock->pause_for_swap, false, AL_ATOMIC_RELAXED);
+ atomic_store(bool)(&clock->external_pause, false, AL_ATOMIC_RELAXED);
-// @TODO: This only works for local sink.
-bool camu_clock_is_user_paused(struct camu_clock *clock)
-{
- f64 tick = atomic_load(f64)(&clock->tick, AL_ATOMIC_RELAXED);
- f64 pause = atomic_load(f64)(&clock->pause, AL_ATOMIC_RELAXED);
- return tick != SET && pause <= 0.0;
+ atomic_store(f64)(&clock->pause, RUNNING, AL_ATOMIC_RELEASE);
}
f64 camu_clock_get_base_pts(struct camu_clock *clock)
@@ -158,7 +157,7 @@ f64 camu_clock_get_base_pts(struct camu_clock *clock)
return clock->base;
}
-f64 camu_clock_get_pts(struct camu_clock *clock, f64 latency, bool allow_set, bool *armed_for_pause)
+f64 camu_clock_get_pts(struct camu_clock *clock, f64 latency, bool allow_set, u8 *status)
{
// Treat pause = 0.0 or -0.0 as paused.
f64 pause = atomic_load(f64)(&clock->pause, AL_ATOMIC_RELAXED);
@@ -171,15 +170,23 @@ f64 camu_clock_get_pts(struct camu_clock *clock, f64 latency, bool allow_set, bo
tick = atomic_compare_and_swap(f64)(&clock->tick, SET, current);
if (tick == SET) tick = current;
} else {
- return CAMU_PTS_PAUSED;
+ return CAMU_PTS_UNSET;
}
}
+ bool allow_pause = !status || *status != CAMU_CLOCK_NO_SIGNAL_PAUSE;
+ if (status) {
+ *status = 0;
+ bool pause_for_swap = atomic_load(bool)(&clock->pause_for_swap, AL_ATOMIC_RELAXED);
+ bool external_pause = atomic_load(bool)(&clock->external_pause, AL_ATOMIC_RELAXED);
+ if (pause_for_swap) *status |= CAMU_CLOCK_PAUSE_FOR_SWAP;
+ if (external_pause) *status |= CAMU_CLOCK_EXTERNAL_PAUSE;
+ }
+
f64 pts = clock->base + (current - tick);
bool signal_pause = false;
- *armed_for_pause = pause != RUNNING || atomic_load(bool)(&clock->external_pause, AL_ATOMIC_RELAXED);
- if (pause > 0.0 && current > pause) {
+ if (allow_pause && pause > 0.0 && current > pause) {
f64 paused_at = -current;
pause = atomic_compare_and_swap(f64)(&clock->pause, pause, paused_at);
if (pause != paused_at) {