diff options
| author | 2024-01-06 19:54:21 -0500 | |
|---|---|---|
| committer | 2024-01-06 19:54:21 -0500 | |
| commit | e6c1c0afc69ee13465bb68a6bdeb35b6876146d4 (patch) | |
| tree | ffea140be35691dfc24e9a6ca6c54e2d0247e8a8 /src/buffer | |
| parent | 11bbaf5198d15da44731ffb63411558f1c72f97e (diff) | |
| download | camu-e6c1c0afc69ee13465bb68a6bdeb35b6876146d4.tar.gz camu-e6c1c0afc69ee13465bb68a6bdeb35b6876146d4.tar.bz2 camu-e6c1c0afc69ee13465bb68a6bdeb35b6876146d4.zip | |
Initial synced playback
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/buffer')
| -rw-r--r-- | src/buffer/audio.c | 10 | ||||
| -rw-r--r-- | src/buffer/clock.c | 73 | ||||
| -rw-r--r-- | src/buffer/clock.h | 9 | ||||
| -rw-r--r-- | src/buffer/video.c | 1 |
4 files changed, 54 insertions, 39 deletions
diff --git a/src/buffer/audio.c b/src/buffer/audio.c index 9799a95..ffb10dc 100644 --- a/src/buffer/audio.c +++ b/src/buffer/audio.c @@ -70,10 +70,9 @@ bool camu_audio_buffer_init(struct camu_audio_buffer *buf, struct camu_clock *cl { buf->mixer = mixer; buf->clock = clock; - buf->pts = camu_mixer_get_latency(buf->mixer); buf->buffered = false; buf->pause = PAUSE_PRE; - buf->ignore_desync = true; + buf->ignore_desync = false; #ifdef CAMU_AUDIO_BUFFER_FADE buf->fade_period = 0; buf->fade_offset = 0; @@ -198,7 +197,7 @@ void camu_audio_buffer_reset(struct camu_audio_buffer *buf) { al_atomic_size_t_store(&buf->continue_mark, 0, AL_ATOMIC_RELAXED); al_atomic_u8_store(&buf->flow, FLOWING, AL_ATOMIC_RELAXED); - buf->pts = camu_clock_get_base_pts(buf->clock); + buf->pts = camu_clock_get_base_pts(buf->clock) + camu_mixer_get_latency(buf->mixer); buf->buffered = false; buf->pause = PAUSE_PRE; al_ring_buffer_reset(&buf->rb); @@ -259,7 +258,8 @@ static void handle_fade(struct camu_audio_buffer *buf, u8 *data, size_t size, bo size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t req) { - if (camu_clock_is_paused(buf->clock)) { + f64 pts = camu_clock_get_pts(buf->clock); + if (pts < 0.0) { #ifdef CAMU_AUDIO_BUFFER_FADE if (buf->pause == PAUSE_PLAYING) { // Fade out. Signified by >0 fade_period and PAUSE_FADING. @@ -299,7 +299,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re #ifdef CAMU_AUDIO_BUFFER_FADE if (buf->pause != PAUSE_FADING) { #endif - f64 pts = camu_clock_get_pts(buf->clock) - buf->pts; + pts -= buf->pts; // We can assume a call to audio_buffer_read will happen before // the user NEEDS the data, so, we can't accurately assess the sync here. if (UNLIKELY(!buf->ignore_desync && (buf->pause == PAUSE_PRE || buf->pause == PAUSE_UNPAUSED))) { diff --git a/src/buffer/clock.c b/src/buffer/clock.c index c9b18ce..a1c3e83 100644 --- a/src/buffer/clock.c +++ b/src/buffer/clock.c @@ -1,55 +1,68 @@ +#include <al/lib.h> + #include "clock.h" -void camu_clock_init(struct camu_clock *clock) +void camu_clock_set(struct camu_clock *clock, u64 base, u64 start) { - f64 tick = aki_get_tick(); - al_atomic_f64_store(&clock->pause, tick, AL_ATOMIC_RELAXED); - al_atomic_f64_store(&clock->start, tick, AL_ATOMIC_RELAXED); - al_atomic_f64_store(&clock->base, 0.0, AL_ATOMIC_RELAXED); + al_atomic_f64_store(&clock->base, base / 1000000.f, AL_ATOMIC_RELAXED); + al_atomic_f64_store(&clock->tick, 0.0, AL_ATOMIC_RELAXED); + al_atomic_u64_store(&clock->start, start, AL_ATOMIC_RELAXED); + camu_clock_resume(clock); } -void camu_clock_pause(struct camu_clock *clock) +void camu_clock_resume(struct camu_clock *clock) { - f64 pause = al_atomic_f64_load(&clock->pause, AL_ATOMIC_RELAXED); - if (pause != -1.0) return; - al_atomic_f64_store(&clock->pause, aki_get_tick(), AL_ATOMIC_RELAXED); + u64 start = al_atomic_u64_load(&clock->start, AL_ATOMIC_ACQUIRE); + if (start == 0L) return; + u64 ts = aki_get_timestamp(); + al_assert(start < ts); + f64 diff = (ts - start) / 1000000.f; + f64 tick = al_atomic_f64_load(&clock->tick, AL_ATOMIC_RELAXED); + if (tick == 0.0) { + tick = aki_get_tick() - al_atomic_f64_load(&clock->base, AL_ATOMIC_RELAXED); + } + al_atomic_f64_store(&clock->tick, tick + diff, AL_ATOMIC_RELAXED); + al_atomic_u64_store(&clock->start, 0L, AL_ATOMIC_RELEASE); } -void camu_clock_resume(struct camu_clock *clock) +static f64 get_pts_internal(struct camu_clock *clock) { - f64 pause = al_atomic_f64_load(&clock->pause, AL_ATOMIC_RELAXED); - if (pause == -1.0) return; - f64 start = al_atomic_f64_load(&clock->start, AL_ATOMIC_RELAXED); - f64 base = al_atomic_f64_load(&clock->base, AL_ATOMIC_RELAXED); - if (start == 0.0) start = (pause - base); - al_atomic_f64_store(&clock->pause, -1.0, AL_ATOMIC_RELAXED); - al_atomic_f64_store(&clock->start, aki_get_tick() - (pause - start), AL_ATOMIC_RELAXED); + f64 tick = al_atomic_f64_load(&clock->tick, AL_ATOMIC_RELAXED); + return aki_get_tick() - tick; } -void camu_clock_seek(struct camu_clock *clock, f64 pos) +void camu_clock_pause(struct camu_clock *clock) { - al_atomic_f64_store(&clock->start, 0.0, AL_ATOMIC_RELAXED); - al_atomic_f64_store(&clock->base, pos, AL_ATOMIC_RELAXED); - f64 tick = aki_get_tick(); - al_atomic_f64_store(&clock->pause, tick, AL_ATOMIC_RELAXED); + u64 start = al_atomic_u64_load(&clock->start, AL_ATOMIC_ACQUIRE); + if (start != 0L) return; + al_atomic_f64_store(&clock->base, get_pts_internal(clock), AL_ATOMIC_RELAXED); + al_atomic_u64_store(&clock->start, aki_get_timestamp(), AL_ATOMIC_RELEASE); +} + +void camu_clock_seek(struct camu_clock *clock, u64 base, u64 start) +{ + (void)clock; + (void)base; + (void)start; } bool camu_clock_is_paused(struct camu_clock *clock) { - f64 pause = al_atomic_f64_load(&clock->pause, AL_ATOMIC_RELAXED); - return pause != -1.0; + u64 start = al_atomic_u64_load(&clock->start, AL_ATOMIC_RELAXED); + return start != 0L; } f64 camu_clock_get_base_pts(struct camu_clock *clock) { - f64 base = al_atomic_f64_load(&clock->base, AL_ATOMIC_RELAXED); - return base; + return al_atomic_f64_load(&clock->base, AL_ATOMIC_RELAXED); } f64 camu_clock_get_pts(struct camu_clock *clock) { - f64 pause = al_atomic_f64_load(&clock->pause, AL_ATOMIC_RELAXED); - f64 start = al_atomic_f64_load(&clock->start, AL_ATOMIC_RELAXED); - if (pause != -1.f) return pause - start; - return aki_get_tick() - start; + u64 start = al_atomic_u64_load(&clock->start, AL_ATOMIC_RELAXED); + if (start != 0L) return -1.0; + f64 base = al_atomic_f64_load(&clock->base, AL_ATOMIC_RELAXED); + f64 pts = get_pts_internal(clock); + if (pts < base) return -1.0; + return pts; } diff --git a/src/buffer/clock.h b/src/buffer/clock.h index 9f34807..e39a963 100644 --- a/src/buffer/clock.h +++ b/src/buffer/clock.h @@ -4,13 +4,14 @@ #include <al/atomic.h> struct camu_clock { - atomic_f64 base, start, pause; + atomic_f64 base, tick; + atomic_u64 start; }; -void camu_clock_init(struct camu_clock *clock); -void camu_clock_pause(struct camu_clock *clock); +void camu_clock_set(struct camu_clock *clock, u64 base, u64 start); void camu_clock_resume(struct camu_clock *clock); -void camu_clock_seek(struct camu_clock *clock, f64 pos); +void camu_clock_pause(struct camu_clock *clock); +void camu_clock_seek(struct camu_clock *clock, u64 base, u64 start); bool camu_clock_is_paused(struct camu_clock *clock); f64 camu_clock_get_base_pts(struct camu_clock *clock); f64 camu_clock_get_pts(struct camu_clock *clock); diff --git a/src/buffer/video.c b/src/buffer/video.c index 6c8d6e3..3d3961b 100644 --- a/src/buffer/video.c +++ b/src/buffer/video.c @@ -137,6 +137,7 @@ void camu_video_buffer_flush(struct camu_video_buffer *buf) bool camu_video_buffer_read(struct camu_video_buffer *buf, void *out) { f64 pts = buf->single_frame ? 0.0 : camu_clock_get_pts(buf->clock); + if (pts < 0.0) pts = camu_clock_get_base_pts(buf->clock); u8 ret = buf->queue->read(buf->queue, pts, out); if (ret == CAMU_QUEUE_EOF || (ret == CAMU_QUEUE_OK && buf->single_frame)) { buf->callback(buf->userdata, CAMU_BUFFER_EOF); |