From 831f260ba2f6bc89f0451f6cc628bd131913a363 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Wed, 23 Oct 2024 18:15:07 -0400 Subject: Sink-side list sync resilience, vcr fix Signed-off-by: Andrew Opalach --- src/buffer/audio.c | 18 +++++++++++++++--- src/buffer/audio.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src/buffer') diff --git a/src/buffer/audio.c b/src/buffer/audio.c index 1bf42bf..2af24b2 100644 --- a/src/buffer/audio.c +++ b/src/buffer/audio.c @@ -31,6 +31,7 @@ static void reset_buffer_state(struct camu_audio_buffer *buf) { buf->pts = -1.0; buf->pause = PAUSE_PAUSED; + al_atomic_store(u8)(&buf->unpause, 0, AL_ATOMIC_RELAXED); buf->volume = 1.f; #ifdef CAMU_AUDIO_BUFFER_FADE buf->fade_offset = 0; @@ -185,13 +186,12 @@ void camu_audio_buffer_push(struct camu_audio_buffer *buf, struct camu_codec_fra al_free(frame); } -// Not thread-safe, must be called while the buffer is not being read from or written to. void camu_audio_buffer_unpause(struct camu_audio_buffer *buf) { - buf->pause = PAUSE_PAUSED; + al_atomic_store(u8)(&buf->unpause, 1, AL_ATOMIC_RELAXED); } -// Not thread-safe. +// Not thread-safe, must be called while the buffer is not being read from or written to. void camu_audio_buffer_reset(struct camu_audio_buffer *buf) { reset_buffer_state(buf); @@ -253,11 +253,19 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re return req; #endif } + + if (al_atomic_load(u8)(&buf->unpause, AL_ATOMIC_ACQUIRE)) { + // If pause != PLAYING here, this will cause unexpected behavior. + buf->pause = PAUSE_PAUSED; + al_atomic_store(u8)(&buf->unpause, 0, AL_ATOMIC_RELEASE); + } + u8 flow = al_atomic_load(u8)(&buf->flow, AL_ATOMIC_ACQUIRE); if (flow == SIGNALED) { buf->callback(buf->userdata, CAMU_BUFFER_EOF); return 0; } + f64 pts = camu_clock_get_pts(buf->clock, buf->latency); size_t ret, signal = req; size_t have = al_ring_buffer_occupied(&buf->rb); @@ -298,6 +306,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re #ifdef CAMU_AUDIO_BUFFER_FADE } #endif + if (have < req) { // We don't have enough data to fulfill our request. if (flow == FLUSHED) { // Stream is flushed. // Check peak buffer for any remaining data. @@ -335,6 +344,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re // The amount of available data could've increased in the flow = FLUSHED case. req = AL_MIN(req, have); } + if (req > 0) { #ifdef CAMU_AUDIO_BUFFER_FADE if (buf->pause == PAUSE_FADING) { @@ -361,6 +371,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re } #endif } + // Check if we should request to uncork. if (flow == FLOWING) { ret = al_atomic_load(size_t)(&buf->uncork_at, AL_ATOMIC_RELAXED); @@ -368,6 +379,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re buf->callback(buf->userdata, CAMU_BUFFER_UNCORK); } } + // To signal EOF, return less then req. return signal; } diff --git a/src/buffer/audio.h b/src/buffer/audio.h index 3adccc7..0f84d5a 100644 --- a/src/buffer/audio.h +++ b/src/buffer/audio.h @@ -17,6 +17,7 @@ struct camu_audio_buffer { f64 pts; u8 pause; + atomic(u8) unpause; struct camu_clock *clock; bool ignore_desync; f64 latency; -- cgit v1.2.3-101-g0448