diff options
| author | 2025-01-17 12:12:01 -0500 | |
|---|---|---|
| committer | 2025-01-17 12:12:01 -0500 | |
| commit | 37684729283f62fd7f1e74bc2b318dc9ad2cb695 (patch) | |
| tree | 2f5be73bf64ac6573e35e8f499515659472a14c9 /src/buffer | |
| parent | d1f1eb9b3713a450c0736caad17febae0721af4d (diff) | |
| download | camu-37684729283f62fd7f1e74bc2b318dc9ad2cb695.tar.gz camu-37684729283f62fd7f1e74bc2b318dc9ad2cb695.tar.bz2 camu-37684729283f62fd7f1e74bc2b318dc9ad2cb695.zip | |
Account for dependency changes, platform testing
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/buffer')
| -rw-r--r-- | src/buffer/audio.c | 48 | ||||
| -rw-r--r-- | src/buffer/audio.h | 10 | ||||
| -rw-r--r-- | src/buffer/common_internal.h | 10 | ||||
| -rw-r--r-- | src/buffer/peak_buffer.c | 14 | ||||
| -rw-r--r-- | src/buffer/peak_buffer.h | 6 | ||||
| -rw-r--r-- | src/buffer/video.c | 39 |
6 files changed, 71 insertions, 56 deletions
diff --git a/src/buffer/audio.c b/src/buffer/audio.c index 707219f..cf42840 100644 --- a/src/buffer/audio.c +++ b/src/buffer/audio.c @@ -5,13 +5,13 @@ #endif #include "audio.h" +#include "volume.h" #include "common.h" #include "common_internal.h" -#include "volume.h" -#define BUFFER_SIZE 4.0 -#define BUFFER_MARK_MIN 1.75 // Must be a most half of the buffer size. -#define BUFFER_MARK_BUFFERED 1.0 +#define BUFFER_SIZE 8.0 +#define BUFFER_MARK_MIN 3.25 // Must be a most half of the buffer size. +#define BUFFER_MARK_BUFFERED 1.25 #ifdef CAMU_AUDIO_BUFFER_FADE #define FADE_STEP(fmt) (1.75f / (fmt)->sample_rate) @@ -37,7 +37,7 @@ static void reset_buffer_state(struct camu_audio_buffer *buf) #endif buf->buffered = false; al_atomic_store(u8)(&buf->flow, FLOWING, AL_ATOMIC_RELAXED); - al_atomic_store(size_t)(&buf->uncork_at, 0, AL_ATOMIC_RELAXED); + al_atomic_store(ptrdiff_t)(&buf->uncork_at, 0, AL_ATOMIC_RELAXED); } bool camu_audio_buffer_init(struct camu_audio_buffer *buf, struct camu_clock *clock) @@ -77,12 +77,12 @@ bool camu_audio_buffer_configure(struct camu_audio_buffer *buf, struct camu_code in_format_name, buf->fmt.in.channel_count, buf->fmt.in.sample_rate, req_format_name, buf->fmt.req.channel_count, buf->fmt.req.sample_rate); - buf->size = camu_audio_format_sec_to_bytes(&buf->fmt.req, BUFFER_SIZE); + buf->size = (ptrdiff_t)camu_audio_format_sec_to_bytes(&buf->fmt.req, BUFFER_SIZE); buf->data = (u8 *)al_malloc(buf->size); al_ring_buffer_init(&buf->rb, buf->data, buf->size); - buf->mark.min = camu_audio_format_sec_to_bytes(&buf->fmt.req, BUFFER_MARK_MIN); - buf->mark.buffered = camu_audio_format_sec_to_bytes(&buf->fmt.req, BUFFER_MARK_BUFFERED); + buf->mark.min = (ptrdiff_t)camu_audio_format_sec_to_bytes(&buf->fmt.req, BUFFER_MARK_MIN); + buf->mark.buffered = (ptrdiff_t)camu_audio_format_sec_to_bytes(&buf->fmt.req, BUFFER_MARK_BUFFERED); camu_peak_buffer_init(&buf->peak, KB(16)); buf->stream = stream; @@ -118,12 +118,6 @@ void camu_audio_buffer_set_no_video(struct camu_audio_buffer *buf, bool no_video #define BUFFERED_SECONDS_DEBUG(buf) 0 #endif -static inline bool frame_is_late(struct camu_clock *clock, f64 base, f64 pts, f64 duration) -{ - if (base == -1.0) base = camu_clock_get_base_pts(clock); - return pts + duration < base; -} - // A return value of false signals that we pushed to the peak buffer. static bool push_internal(struct camu_audio_buffer *buf, f64 pts, u8 **data, s32 sample_count) { @@ -157,15 +151,15 @@ static bool push_internal(struct camu_audio_buffer *buf, f64 pts, u8 **data, s32 return true; } - size_t space = al_ring_buffer_space(&buf->rb); + ptrdiff_t space = al_ring_buffer_space(&buf->rb); if (!buf->buffered && buf->size - space > buf->mark.buffered) { al_log_debug("audio_buffer", "Buffered (mark: %.2fs).", BUFFERED_SECONDS_DEBUG(buf)); buf->callback(buf->userdata, CAMU_BUFFER_BUFFERED); buf->buffered = true; } - size_t have = camu_audio_format_samples_to_bytes(&buf->fmt.req, (size_t)sample_count); - size_t peak = camu_peak_buffer_get_size(&buf->peak); + ptrdiff_t have = (ptrdiff_t)camu_audio_format_samples_to_bytes(&buf->fmt.req, sample_count); + ptrdiff_t peak = camu_peak_buffer_get_size(&buf->peak); if (space < have + peak) { al_assert(have < buf->mark.min); camu_peak_buffer_push(&buf->peak, data[0], have); @@ -178,7 +172,7 @@ static bool push_internal(struct camu_audio_buffer *buf, f64 pts, u8 **data, s32 } al_assert(peak <= buf->mark.min); // We adjust the min mark by the peak buffer size just for consistency. - al_atomic_store(size_t)(&buf->uncork_at, buf->mark.min - peak, AL_ATOMIC_RELAXED); + al_atomic_store(ptrdiff_t)(&buf->uncork_at, buf->mark.min - peak, AL_ATOMIC_RELAXED); buf->callback(buf->userdata, CAMU_BUFFER_CORK); return false; } @@ -264,7 +258,7 @@ void camu_audio_buffer_unpause(struct camu_audio_buffer *buf) // PAUSE_PAUSED signifies that the last read was silence. Meaning we can skip // around in the buffer without worrying about pops. -size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t req) +ptrdiff_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, ptrdiff_t req) { if (al_atomic_load(s32)(&buf->volume.set, AL_ATOMIC_ACQUIRE) > 0) { buf->volume.user = al_atomic_load(f32)(&buf->volume.queued, AL_ATOMIC_RELAXED); @@ -315,8 +309,8 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re } struct camu_audio_format *fmt = &buf->fmt.req; - size_t ret, signal = req; - size_t have = al_ring_buffer_occupied(&buf->rb); + ptrdiff_t ret, signal = req; + ptrdiff_t have = al_ring_buffer_occupied(&buf->rb); #ifdef CAMU_AUDIO_BUFFER_FADE // Cut off fade if it's reaching too far. if (have < buf->fade.offset) have = 0; @@ -329,16 +323,16 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re if (!buf->ignore_desync) { pts -= base_pts; if (pts > 0.0) { // Skip. - ret = camu_audio_format_sec_to_bytes(fmt, pts); + ret = (ptrdiff_t)camu_audio_format_sec_to_bytes(fmt, pts); ret = MIN(ret, have); - al_log_info("audio_buffer", "Skipping %fs of audio (%zu bytes).", pts, ret); + al_log_info("audio_buffer", "Skipping %fs of audio (%zd bytes).", pts, ret); ret = al_ring_buffer_discard(&buf->rb, ret); have -= ret; base_pts += camu_audio_format_bytes_to_sec(fmt, ret); // Could go on to underrun. } else if (pts < 0.0) { // Delay. pts = -pts; - ret = camu_audio_format_sec_to_bytes(fmt, pts); + ret = (ptrdiff_t)camu_audio_format_sec_to_bytes(fmt, pts); ret = MIN(ret, req); al_log_info("audio_buffer", "Delaying audio by %fs.", pts); al_memset(data, 0, ret); @@ -366,7 +360,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re // enough for this request. if (have < req) { signal = have; - al_log_debug("audio_buffer", "Flushed (signal: %zu).", signal); + al_log_debug("audio_buffer", "Flushed (signal: %zd).", signal); buf->callback(buf->userdata, CAMU_BUFFER_EOF); al_atomic_store(u8)(&buf->flow, SIGNALED, AL_ATOMIC_RELEASE); } @@ -377,7 +371,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re // We hit an underrun because data wasn't coming in fast enough. // An underrun can also happen in the audio output if read() (this function) // takes too long. That isn't checked here. - al_log_warn("audio_buffer", "Underrun (req: %zu, have: %zu).", req, have); + al_log_warn("audio_buffer", "Underrun (req: %zd, have: %zd).", req, have); // If we have data by the next read(), try to skip ahead to maintain sync. // This might exacerbate the underrun issue but an underrun is already // unexpected behavior, trying to stay in sync comes first. @@ -435,7 +429,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re #else if (flow == FLOWING) { #endif - ret = al_atomic_load(size_t)(&buf->uncork_at, AL_ATOMIC_RELAXED); + ret = al_atomic_load(ptrdiff_t)(&buf->uncork_at, AL_ATOMIC_RELAXED); if (ret && have - req <= ret) { buf->callback(buf->userdata, CAMU_BUFFER_UNCORK); } diff --git a/src/buffer/audio.h b/src/buffer/audio.h index ca2d405..901becf 100644 --- a/src/buffer/audio.h +++ b/src/buffer/audio.h @@ -27,15 +27,15 @@ struct camu_audio_buffer { struct camu_resampler *resampler; u8 *data; - size_t size; + ptrdiff_t size; struct al_ring_buffer rb; - struct { size_t min, buffered; } mark; + struct { ptrdiff_t min, buffered; } mark; bool buffered; atomic(u8) flow; struct camu_peak_buffer peak; - atomic(size_t) uncork_at; + atomic(ptrdiff_t) uncork_at; struct { f32 user; @@ -46,7 +46,7 @@ struct camu_audio_buffer { #ifdef CAMU_AUDIO_BUFFER_FADE struct { f32 volume; - size_t offset; + ptrdiff_t offset; } fade; #endif @@ -69,5 +69,5 @@ void camu_audio_buffer_push(struct camu_audio_buffer *buf, struct camu_codec_fra void camu_audio_buffer_flush(struct camu_audio_buffer *buf); void camu_audio_buffer_reset(struct camu_audio_buffer *buf); void camu_audio_buffer_unpause(struct camu_audio_buffer *buf); -size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t req); +ptrdiff_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, ptrdiff_t req); void camu_audio_buffer_free(struct camu_audio_buffer *buf); diff --git a/src/buffer/common_internal.h b/src/buffer/common_internal.h index e4cdd33..11caddc 100644 --- a/src/buffer/common_internal.h +++ b/src/buffer/common_internal.h @@ -1,5 +1,9 @@ #pragma once +#include <al/types.h> + +#include "clock.h" + enum { // Flowing. FLOWING, @@ -10,3 +14,9 @@ enum { // Errored. ERRORED }; + +static inline bool frame_is_late(struct camu_clock *clock, f64 base, f64 pts, f64 duration) +{ + if (base == -1.0) base = camu_clock_get_base_pts(clock); + return pts + duration < base; +} diff --git a/src/buffer/peak_buffer.c b/src/buffer/peak_buffer.c index 9687a1f..c1fe254 100644 --- a/src/buffer/peak_buffer.c +++ b/src/buffer/peak_buffer.c @@ -2,20 +2,22 @@ // https://github.com/MusicPlayerDaemon/MPD/blob/c71e586c530e1d066efde7c2ca40c363f74100c7/src/util/PeakBuffer.cxx -void camu_peak_buffer_init(struct camu_peak_buffer *buf, size_t size) +// We use ptrdiff_t here instead of nn_buffer's size_t just to map better to the types in audio_buffer. + +void camu_peak_buffer_init(struct camu_peak_buffer *buf, ptrdiff_t size) { nn_buffer_init(&buf->buf); - nn_buffer_ensure_space(&buf->buf, size); + nn_buffer_ensure_space(&buf->buf, (size_t)size); } -void camu_peak_buffer_push(struct camu_peak_buffer *buf, u8 *data, size_t size) +void camu_peak_buffer_push(struct camu_peak_buffer *buf, u8 *data, ptrdiff_t size) { - nn_buffer_append(&buf->buf, data, size); + nn_buffer_append(&buf->buf, data, (size_t)size); } -size_t camu_peak_buffer_get_size(struct camu_peak_buffer *buf) +ptrdiff_t camu_peak_buffer_get_size(struct camu_peak_buffer *buf) { - return nn_buffer_get_size(&buf->buf); + return (ptrdiff_t)nn_buffer_get_size(&buf->buf); } u8 *camu_peak_buffer_flush(struct camu_peak_buffer *buf) diff --git a/src/buffer/peak_buffer.h b/src/buffer/peak_buffer.h index 9bd3316..73465ec 100644 --- a/src/buffer/peak_buffer.h +++ b/src/buffer/peak_buffer.h @@ -7,8 +7,8 @@ struct camu_peak_buffer { struct nn_buffer buf; }; -void camu_peak_buffer_init(struct camu_peak_buffer *buf, size_t size); -void camu_peak_buffer_push(struct camu_peak_buffer *buf, u8 *data, size_t size); -size_t camu_peak_buffer_get_size(struct camu_peak_buffer *buf); +void camu_peak_buffer_init(struct camu_peak_buffer *buf, ptrdiff_t size); +void camu_peak_buffer_push(struct camu_peak_buffer *buf, u8 *data, ptrdiff_t size); +ptrdiff_t camu_peak_buffer_get_size(struct camu_peak_buffer *buf); u8 *camu_peak_buffer_flush(struct camu_peak_buffer *buf); void camu_peak_buffer_free(struct camu_peak_buffer *buf); diff --git a/src/buffer/video.c b/src/buffer/video.c index 47c1ea9..01f317e 100644 --- a/src/buffer/video.c +++ b/src/buffer/video.c @@ -10,9 +10,9 @@ #endif #endif -#define BUFFER_MARK_LOW ((1.0 / 30.0) * 4) +#define BUFFER_MARK_LOW ((1.0 / 30.0) * 6) #define BUFFER_MARK_BUFFERED ((1.0 / 30.0) * 5) -#define BUFFER_MARK_HIGH ((1.0 / 30.0) * 10) +#define BUFFER_MARK_HIGH ((1.0 / 30.0) * 12) #define BUFFER_MARK_RESET (BUFFER_MARK_HIGH * 2.0) bool camu_video_buffer_init(struct camu_video_buffer *buf, struct camu_clock *clock) @@ -46,11 +46,17 @@ bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_code struct camu_video_format *fmt = &buf->stream->video.fmt; switch (stream->mode) { case CAMU_NORMAL: { - buf->single_frame = true; camu_video_format_copy(&buf->fmt.in, fmt); + + buf->single_frame = true; + buf->avg_frame_duration = 0.0; + const char *format_name = camu_pixel_format_name(fmt->format); if (!format_name) format_name = "unknown"; - al_log_info("video_buffer", "Stream: %s (%dx%d) %s.", format_name, fmt->width, fmt->height, "IMAGE"); + + al_log_info("video_buffer", "Stream: %s (%dx%d) %s.", + format_name, fmt->width, fmt->height, "IMAGE"); + break; } #ifdef CAMU_HAVE_FFMPEG @@ -64,12 +70,16 @@ bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_code camu_video_format_copy(&buf->fmt.in, fmt); buf->single_frame = stream->duration == 0 || frame_rate.den == 0; - if (buf->single_frame) frame_rate = (AVRational){ 0, 1 }; buf->avg_frame_duration = buf->single_frame ? 0.0 : av_q2d(av_inv_q(frame_rate)); const char *format_name = av_get_pix_fmt_name(buf->fmt.in.format); - al_log_info("video_buffer", "Stream: %s (%dx%d) %s %.2ffps.", - format_name, fmt->width, fmt->height, buf->single_frame ? "IMAGE" : "VIDEO", av_q2d(frame_rate)); + if (buf->single_frame) { + al_log_info("video_buffer", "Stream: %s (%dx%d) %s.", + format_name, fmt->width, fmt->height, "IMAGE"); + } else { + al_log_info("video_buffer", "Stream: %s (%dx%d) %s %.3ffps.", + format_name, fmt->width, fmt->height, "VIDEO", av_q2d(frame_rate)); + } break; } @@ -129,13 +139,17 @@ static void after_push_internal(struct camu_video_buffer *buf) if (!buf->buffered && (buf->single_frame || have >= BUFFER_MARK_BUFFERED)) { // Preserve order of: flush -> callback -> set flow, for single frames. - if (buf->single_frame) buf->queue->flush(buf->queue); + if (buf->single_frame) { + buf->queue->flush(buf->queue); + } al_log_debug("video_buffer", "Buffered (mark: %.2fs).", have); buf->callback(buf->userdata, CAMU_BUFFER_BUFFERED); buf->buffered = true; - if (buf->single_frame) al_atomic_store(u8)(&buf->flow, FLUSHED, AL_ATOMIC_RELAXED); + if (buf->single_frame) { + al_atomic_store(u8)(&buf->flow, FLUSHED, AL_ATOMIC_RELAXED); + } } if (have >= BUFFER_MARK_RESET) { @@ -146,12 +160,6 @@ static void after_push_internal(struct camu_video_buffer *buf) } } -static inline bool frame_is_late(struct camu_clock *clock, f64 base, f64 pts, f64 duration) -{ - if (base == -1.0) base = camu_clock_get_base_pts(clock); - return pts + duration < base; -} - #ifdef CAMU_HAVE_FFMPEG static bool push_av_frame_internal(struct camu_video_buffer *buf, AVFrame *frame) { @@ -248,6 +256,7 @@ bool camu_video_buffer_read(struct camu_video_buffer *buf, void *out, bool *weig al_atomic_store(f64)(&buf->pts, base, AL_ATOMIC_RELEASE); } } + u8 ret = buf->queue->read(buf->queue, base, out); u8 flow = al_atomic_load(u8)(&buf->flow, AL_ATOMIC_ACQUIRE); if (ret == CAMU_QUEUE_ERR) { |