summaryrefslogtreecommitdiff
path: root/src/buffer
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer')
-rw-r--r--src/buffer/audio.c2
-rw-r--r--src/buffer/peak_buffer.c24
-rw-r--r--src/buffer/peak_buffer.h12
-rw-r--r--src/buffer/video.c39
-rw-r--r--src/buffer/video_null.h4
5 files changed, 43 insertions, 38 deletions
diff --git a/src/buffer/audio.c b/src/buffer/audio.c
index fd395e0..699b05e 100644
--- a/src/buffer/audio.c
+++ b/src/buffer/audio.c
@@ -12,7 +12,7 @@
#define BUFFER_SIZE 8.0
#define BUFFER_MARK_MIN 3.25 // Must be a most half of the buffer size.
-#define BUFFER_MARK_BUFFERED 0.25
+#define BUFFER_MARK_BUFFERED 0.35
#ifdef CAMU_AUDIO_BUFFER_FADE
#define FADE_STEP(fmt) (2.50f / (fmt)->sample_rate)
diff --git a/src/buffer/peak_buffer.c b/src/buffer/peak_buffer.c
index c1fe254..854595a 100644
--- a/src/buffer/peak_buffer.c
+++ b/src/buffer/peak_buffer.c
@@ -4,29 +4,29 @@
// 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)
+void camu_peak_buffer_init(struct camu_peak_buffer *peak, ptrdiff_t size)
{
- nn_buffer_init(&buf->buf);
- nn_buffer_ensure_space(&buf->buf, (size_t)size);
+ nn_buffer_init(&peak->buffer);
+ nn_buffer_ensure_space(&peak->buffer, (size_t)size);
}
-void camu_peak_buffer_push(struct camu_peak_buffer *buf, u8 *data, ptrdiff_t size)
+void camu_peak_buffer_push(struct camu_peak_buffer *peak, u8 *data, ptrdiff_t size)
{
- nn_buffer_append(&buf->buf, data, (size_t)size);
+ nn_buffer_append(&peak->buffer, data, (size_t)size);
}
-ptrdiff_t camu_peak_buffer_get_size(struct camu_peak_buffer *buf)
+ptrdiff_t camu_peak_buffer_get_size(struct camu_peak_buffer *peak)
{
- return (ptrdiff_t)nn_buffer_get_size(&buf->buf);
+ return (ptrdiff_t)peak->buffer.size;
}
-u8 *camu_peak_buffer_flush(struct camu_peak_buffer *buf)
+u8 *camu_peak_buffer_flush(struct camu_peak_buffer *peak)
{
- nn_buffer_set_size(&buf->buf, 0);
- return nn_buffer_get_ptr(&buf->buf, 0);
+ peak->buffer.size = 0;
+ return nn_buffer_get_ptr(&peak->buffer, 0);
}
-void camu_peak_buffer_free(struct camu_peak_buffer *buf)
+void camu_peak_buffer_free(struct camu_peak_buffer *peak)
{
- nn_buffer_free(&buf->buf);
+ nn_buffer_free(&peak->buffer);
}
diff --git a/src/buffer/peak_buffer.h b/src/buffer/peak_buffer.h
index 73465ec..2a68e9c 100644
--- a/src/buffer/peak_buffer.h
+++ b/src/buffer/peak_buffer.h
@@ -4,11 +4,11 @@
#include <nnwt/common.h>
struct camu_peak_buffer {
- struct nn_buffer buf;
+ struct nn_buffer buffer;
};
-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);
+void camu_peak_buffer_init(struct camu_peak_buffer *peak, ptrdiff_t size);
+void camu_peak_buffer_push(struct camu_peak_buffer *peak, u8 *data, ptrdiff_t size);
+ptrdiff_t camu_peak_buffer_get_size(struct camu_peak_buffer *peak);
+u8 *camu_peak_buffer_flush(struct camu_peak_buffer *peak);
+void camu_peak_buffer_free(struct camu_peak_buffer *peak);
diff --git a/src/buffer/video.c b/src/buffer/video.c
index 9a33540..8bedbf6 100644
--- a/src/buffer/video.c
+++ b/src/buffer/video.c
@@ -10,10 +10,15 @@
#include "common.h"
#include "common_internal.h"
-#define BUFFER_MARK_LOW ((1.0 / 24.0) * 2)
-#define BUFFER_MARK_BUFFERED ((1.0 / 24.0) * 4) // Must be >1.
-#define BUFFER_MARK_HIGH ((1.0 / 24.0) * 6)
-#define BUFFER_MARK_RESET (BUFFER_MARK_HIGH * 2.0)
+// This used to scale based on avg_frame_duration, but that's actually
+// quite incompatible with very low frame rates.
+// MARK_LOW is considered directly after reading a frame, so in other words,
+// it will trigger at the point where there is about (LOW+1) frames left. Even at
+// something like 240fps that's still ~12 whole ms to uncork and produce a new frame.
+#define BUFFER_MARK_LOW 2
+#define BUFFER_MARK_BUFFERED 5 // Must be >1.
+#define BUFFER_MARK_HIGH 7
+#define BUFFER_MARK_RESET (BUFFER_MARK_HIGH * 2)
bool camu_video_buffer_init(struct camu_video_buffer *buf, struct camu_clock *clock)
{
@@ -70,7 +75,7 @@ bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_code
camu_video_format_copy(req, in);
if (fmt->width > 0 && fmt->height > 0 &&
#ifdef CAMU_VIDEO_BUFFER_REQUIRE_RGB
- (fmt->format != CAMU_PIXEL_FORMAT_RGBA && fmt->format != CAMU_PIXEL_FORMAT_RGB)
+ (fmt->format != CAMU_PIXEL_FORMAT_RGBA && fmt->format != CAMU_PIXEL_FORMAT_RGB32)
#else
(fmt->format == CAMU_PIXEL_FORMAT_PAL8)
#endif
@@ -79,8 +84,10 @@ bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_code
req->width = fmt->width;
req->height = fmt->height;
#ifdef CAMU_HAVE_FFMPEG
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt->format);
- req->format = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? CAMU_PIXEL_FORMAT_RGBA : CAMU_PIXEL_FORMAT_RGB;
+ //const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get((enum AVPixelFormat)fmt->format);
+ //bool has_alpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) != 0;
+ //req->format = CAMU_PIXEL_FORMAT_RGB32;
+ req->format = CAMU_PIXEL_FORMAT_RGBA;
buf->scaler = camu_ff_scaler_create();
if (!buf->scaler->init(buf->scaler, &buf->fmt)) {
// Scaler will be freed in video_buffer_free().
@@ -116,8 +123,7 @@ static void after_push_internal(struct camu_video_buffer *buf)
// If a reset where to happen from the this thread, the latest read()
// frame could be freed before it was used.
s32 count = buf->queue->count(buf->queue);
- f64 have = count * buf->avg_frame_duration;
- if (!buf->buffered && (buf->single_frame || have >= BUFFER_MARK_BUFFERED)) {
+ if (!buf->buffered && (buf->single_frame || count >= BUFFER_MARK_BUFFERED)) {
// Preserve order of: set flow -> flush -> callback, for single frames.
if (buf->single_frame) {
al_atomic_store(u8)(&buf->flow, FLUSHED, AL_ATOMIC_RELAXED);
@@ -125,9 +131,9 @@ static void after_push_internal(struct camu_video_buffer *buf)
}
buf->buffered = true;
buf->buffered_with_one_frame = count == 1;
- log_debug("Buffered (mark: %.2fs).", have);
+ log_debug("Buffered (mark: %.2fs).", count * buf->avg_frame_duration);
buf->callback(buf->userdata, CAMU_BUFFER_BUFFERED);
- } else if (have >= BUFFER_MARK_HIGH) {
+ } else if (count >= BUFFER_MARK_HIGH) {
buf->callback(buf->userdata, CAMU_BUFFER_CORK);
}
}
@@ -157,8 +163,8 @@ static bool push_av_frame_internal(struct camu_video_buffer *buf, AVFrame *frame
void camu_video_buffer_push(struct camu_video_buffer *buf, struct camu_codec_frame *frame)
{
- // A single frame will be sent again after a seek, discard it here (for now).
if (buf->single_frame && buf->buffered) {
+ log_warn("Unexpected duplicate frame received.");
camu_codec_frame_discard(frame);
return;
}
@@ -198,10 +204,9 @@ void camu_video_buffer_flush(struct camu_video_buffer *buf)
buf->queue->flush(buf->queue);
if (!buf->buffered) {
s32 count = buf->queue->count(buf->queue);
- f64 have = count * buf->avg_frame_duration;
buf->buffered = true;
buf->buffered_with_one_frame = count == 1;
- log_debug("Buffered (mark: %.2fs).", have);
+ log_debug("Buffered (mark: %.2fs).", count * buf->avg_frame_duration);
buf->callback(buf->userdata, CAMU_BUFFER_BUFFERED);
}
}
@@ -247,10 +252,10 @@ bool camu_video_buffer_read(struct camu_video_buffer *buf, void *out, bool *weig
al_atomic_store(u8)(&buf->flow, SIGNALED, AL_ATOMIC_RELEASE);
} else if (flow == FLOWING) {
// Never attempt to uncork if flow = FLUSHED.
- f64 have = buf->queue->count(buf->queue) * buf->avg_frame_duration;
- if (have <= BUFFER_MARK_LOW) {
+ s32 count = buf->queue->count(buf->queue);
+ if (count <= BUFFER_MARK_LOW) {
buf->callback(buf->userdata, CAMU_BUFFER_UNCORK);
- } else if (have >= BUFFER_MARK_RESET) {
+ } else if (count >= BUFFER_MARK_RESET) {
log_warn("Buffer overflow, resetting.");
ret = CAMU_QUEUE_ERR; // Don't use the frame written to out.
buf->queue->reset(buf->queue);
diff --git a/src/buffer/video_null.h b/src/buffer/video_null.h
index 15d2aba..06b284c 100644
--- a/src/buffer/video_null.h
+++ b/src/buffer/video_null.h
@@ -7,6 +7,7 @@
#include "clock.h"
struct camu_video_buffer {
+ struct camu_codec_stream *stream;
bool single_frame;
f64 avg_frame_duration;
#ifdef CAMU_SCREEN_THREADED
@@ -37,9 +38,8 @@ static bool camu_video_buffer_init(struct camu_video_buffer *buf, struct camu_cl
static bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_codec_stream *stream,
struct camu_renderer *renderer)
{
- (void)buf;
- (void)stream;
(void)renderer;
+ buf->stream = stream;
return true;
}