summaryrefslogtreecommitdiff
path: root/src/buffer
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2024-10-23 18:15:07 -0400
committerAndrew Opalach <andrew@akon.city> 2024-10-23 18:15:07 -0400
commit831f260ba2f6bc89f0451f6cc628bd131913a363 (patch)
tree5db96c2782fd74f6799bd328742d21c8ffa3ca66 /src/buffer
parent626f299dd3512d44df4bcf95fc7a21b9417c06b0 (diff)
downloadcamu-831f260ba2f6bc89f0451f6cc628bd131913a363.tar.gz
camu-831f260ba2f6bc89f0451f6cc628bd131913a363.tar.bz2
camu-831f260ba2f6bc89f0451f6cc628bd131913a363.zip
Sink-side list sync resilience, vcr fix
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/buffer')
-rw-r--r--src/buffer/audio.c18
-rw-r--r--src/buffer/audio.h1
2 files changed, 16 insertions, 3 deletions
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;