summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buffer/audio.c48
-rw-r--r--src/buffer/audio.h10
-rw-r--r--src/buffer/common_internal.h10
-rw-r--r--src/buffer/peak_buffer.c14
-rw-r--r--src/buffer/peak_buffer.h6
-rw-r--r--src/buffer/video.c39
-rw-r--r--src/cache/backings/file_common.c2
-rw-r--r--src/cache/handlers/cdio.c2
-rw-r--r--src/cache/handlers/http.c5
-rw-r--r--src/codec/codec.h9
-rw-r--r--src/fruits/cmc/cmc.c20
-rw-r--r--src/fruits/cmc/ui/pane_search.c2
-rw-r--r--src/fruits/cmsrv/cmsrv.c26
-rw-r--r--src/fruits/cmsrv/ui.c27
-rw-r--r--src/fruits/cmv/cmv.c14
-rw-r--r--src/fruits/common.h10
-rw-r--r--src/fruits/ctv/ctv.c7
-rw-r--r--src/fruits/ctv/meson.build2
-rw-r--r--src/fruits/droid/ctv/gradle/libs.versions.toml2
-rw-r--r--src/fruits/droid/ctv/gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--src/liana/handlers.c4
-rw-r--r--src/liana/handlers.h2
-rw-r--r--src/liana/handlers/codec_server.c2
-rw-r--r--src/liana/list.c33
-rw-r--r--src/liana/list_cmp.h51
-rw-r--r--src/liana/vcr.c27
-rw-r--r--src/liana/vcr.h2
-rw-r--r--src/libsink/sink.c25
-rw-r--r--src/libsink/sink.h1
-rw-r--r--src/mixer/audio_miniaudio.c2
-rw-r--r--src/mixer/mixer.c28
-rw-r--r--src/portal/cpy/str.pxd4
-rw-r--r--src/portal/cpy/types.pxd4
-rw-r--r--src/portal/py/modules/youtube.py2
-rw-r--r--src/portal/src/packet_ext.c4
-rw-r--r--src/portal/src/search.c10
-rw-r--r--src/render/queue_libplacebo.c2
-rw-r--r--src/render/renderer.h2
-rw-r--r--src/render/renderer_libplacebo.c24
-rw-r--r--src/render/renderer_libplacebo.h1
-rw-r--r--src/screen/screen.c20
-rw-r--r--src/screen/screen.h1
-rw-r--r--src/server/common.h4
-rw-r--r--src/server/db.c34
-rw-r--r--src/server/server.c35
-rw-r--r--src/sink/desktop.c10
-rw-r--r--src/util/color_palette.c14
-rw-r--r--src/util/queue.h45
48 files changed, 366 insertions, 284 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) {
diff --git a/src/cache/backings/file_common.c b/src/cache/backings/file_common.c
index 3914f95..0ee2574 100644
--- a/src/cache/backings/file_common.c
+++ b/src/cache/backings/file_common.c
@@ -9,7 +9,7 @@ static off_t file_backing_get_size_estimate(struct cch_backing *backing)
static bool file_open_internal(struct cch_backing_file *file, str *path, size_t size)
{
- s32 flags = size != 0 ? NNWT_FILE_CREATE : 0;
+ s32 flags = size != 0 ? NNWT_FILE_CREATE : NNWT_FILE_READONLY;
if (!nn_file_open(&file->file, path, flags)) return false;
file->filesize = nn_file_get_filesize(&file->file);
if (!size) {
diff --git a/src/cache/handlers/cdio.c b/src/cache/handlers/cdio.c
index ffaaa62..ac90c03 100644
--- a/src/cache/handlers/cdio.c
+++ b/src/cache/handlers/cdio.c
@@ -184,7 +184,7 @@ static bool open_cd_drive(struct cch_handler_cdio *cdio)
struct cch_entry *cch_handler_cdio_create(void)
{
- struct cch_backing *backing = cch_backing_file_create(al_str_c("/tmp/camu_cd_data"), 4096);
+ struct cch_backing *backing = cch_backing_file_create(&al_str_c("/tmp/camu_cd_data"), 4096);
if (!backing) return NULL;
struct cch_handler_cdio *cdio = al_alloc_object(struct cch_handler_cdio);
cdio->backing = backing;
diff --git a/src/cache/handlers/http.c b/src/cache/handlers/http.c
index b5f2504..3bbb751 100644
--- a/src/cache/handlers/http.c
+++ b/src/cache/handlers/http.c
@@ -8,7 +8,7 @@
#include "http.h"
-#define USER_AGENT al_str_c("Mozilla/5.0 (Windows NT 10.0; rv:122.0) Gecko/20100101 Firefox/122.0")
+static str USER_AGENT = al_str_c("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0");
static bool handler_http_can_seek(struct cch_handler *handler)
{
@@ -70,8 +70,9 @@ static void handler_http_maybe_spawn_worker(struct cch_handler *handler, size_t
struct nn_http *request = &al_array_last(http->requests);
nn_http_init(request);
nn_http_set_url(request, &http->url);
- nn_http_set_user_agent(request, USER_AGENT);
+ nn_http_set_user_agent(request, &USER_AGENT);
nn_http_request_stream(request, NNWT_HTTP_GET, http->loop, http_callback, http);
+ al_log_debug("cache_handler_http", "Spawning worker for %.*s.", al_str_fmt(&http->url));
}
static bool handler_http_wait_for_range(struct cch_handler *handler, struct cch_handler_wait *wait)
diff --git a/src/codec/codec.h b/src/codec/codec.h
index fac3be8..b70e3cb 100644
--- a/src/codec/codec.h
+++ b/src/codec/codec.h
@@ -248,10 +248,10 @@ static const char *camu_audio_format_name(s32 format)
#endif
}
-static inline s32 camu_audio_format_bytes_per_sample(struct camu_audio_format *fmt)
+static inline size_t camu_audio_format_bytes_per_sample(struct camu_audio_format *fmt)
{
#ifdef CAMU_HAVE_FFMPEG
- return av_get_bytes_per_sample(fmt->format);
+ return (size_t)av_get_bytes_per_sample(fmt->format);
#else
switch (fmt->format) {
case CAMU_SAMPLE_FORMAT_U8:
@@ -271,15 +271,14 @@ static inline s32 camu_audio_format_bytes_per_sample(struct camu_audio_format *f
case CAMU_SAMPLE_FORMAT_DBLP:
return 8;
default:
- al_assert_and_return(-1);
+ al_assert_and_return(0);
}
#endif
}
static inline size_t camu_audio_format_samples_to_bytes(struct camu_audio_format *fmt, size_t samples)
{
- s32 bytes_per_sample = camu_audio_format_bytes_per_sample(fmt);
- return samples * bytes_per_sample * fmt->channel_count;
+ return samples * camu_audio_format_bytes_per_sample(fmt) * fmt->channel_count;
}
static inline f64 camu_audio_format_samples_to_sec(struct camu_audio_format *fmt, size_t samples)
diff --git a/src/fruits/cmc/cmc.c b/src/fruits/cmc/cmc.c
index 35f2d9b..af3e567 100644
--- a/src/fruits/cmc/cmc.c
+++ b/src/fruits/cmc/cmc.c
@@ -58,7 +58,7 @@ static void client_callback(void *userdata, u8 op, void *opaque)
case CLI_ADD: {
str *arg;
al_array_foreach_ptr(c->args, i, arg) {
- camu_client_add_from_path(&c->client, al_str_c("default"), arg);
+ camu_client_add_from_path(&c->client, &al_str_c("default"), arg);
al_str_free(arg);
}
camu_client_disconnect(&c->client);
@@ -67,7 +67,7 @@ static void client_callback(void *userdata, u8 op, void *opaque)
case CLI_SEARCH: {
str *arg;
al_array_foreach_ptr(c->args, i, arg) {
- camu_client_create_search(&c->client, al_str_c("youtube"), arg);
+ camu_client_create_search(&c->client, &al_str_c("youtube"), arg);
al_str_free(arg);
}
camu_client_disconnect(&c->client);
@@ -106,7 +106,7 @@ static void client_callback(void *userdata, u8 op, void *opaque)
al_array_push(page->list, s);
}
al_array_push(search->pages, page);
- camu_client_add_from_post(&c->client, al_str_c("default"), &al_array_at(page->list, 0), 0);
+ camu_client_add_from_post(&c->client, &al_str_c("default"), &al_array_at(page->list, 0), 0);
break;
}
}
@@ -124,30 +124,32 @@ static bool parse_cmd(s32 argc, wchar_t **argv)
c.command = CLI_OPEN_UI;
return true;
}
- if (al_str_eq(al_str_cr(argv[1]), al_str_c("add"))) {
+
+ if (al_str_eq(&al_str_cr(argv[1]), &al_str_c("add"))) {
if (argc < 3) return false;
c.command = CLI_ADD;
char path[PATH_MAX];
str arg;
for (s32 i = 2; i < argc; i++) {
if (realpath(argv[i], path)) {
- al_str_clone(&arg, al_str_cr(path));
+ al_str_clone(&arg, &al_str_cs(path));
al_array_push(c.args, arg);
}
}
- } else if (al_str_eq(al_str_cr(argv[1]), al_str_c("search"))) {
+ } else if (al_str_eq(&al_str_cr(argv[1]), &al_str_c("search"))) {
if (argc < 3) return false;
c.command = CLI_SEARCH;
str query;
al_str_from(&query, "");
for (s32 i = 2; i < argc; i++) {
- al_str_cat(&query, al_str_cr(argv[i]));
+ al_str_cat(&query, &al_str_cr(argv[i]));
if (i != argc - 1) {
- al_str_cat(&query, al_str_c(" "));
+ al_str_cat(&query, &al_str_c(" "));
}
}
al_array_push(c.args, query);
}
+
return true;
}
@@ -169,7 +171,7 @@ s32 wmain(s32 argc, wchar_t **argv)
c.client.callback = client_callback;
c.client.userdata = &c;
- if (!camu_client_login(&c.client, &c.loop, CAMU_TEST_TYPE, CAMU_TEST_ADDR, CAMU_PORT, al_str_c("andrew"))) {
+ if (!camu_client_login(&c.client, &c.loop, CAMU_TEST_TYPE, &CAMU_TEST_ADDR, CAMU_PORT, &al_str_c("andrew"))) {
return EXIT_FAILURE;
}
diff --git a/src/fruits/cmc/ui/pane_search.c b/src/fruits/cmc/ui/pane_search.c
index cc549e1..c3d1165 100644
--- a/src/fruits/cmc/ui/pane_search.c
+++ b/src/fruits/cmc/ui/pane_search.c
@@ -4,7 +4,7 @@
void cmc_sp_init(struct cmc_ui *ui)
{
- if (ui->c->searches.size > 0) {
+ if (ui->c->searches.count > 0) {
ui->sp.search = al_array_at(ui->c->searches, 0);
}
cmc_sp_layout(ui, notcurses_stdplane(ui->nc));
diff --git a/src/fruits/cmsrv/cmsrv.c b/src/fruits/cmsrv/cmsrv.c
index 6f00a05..4cd1691 100644
--- a/src/fruits/cmsrv/cmsrv.c
+++ b/src/fruits/cmsrv/cmsrv.c
@@ -39,19 +39,19 @@ static u8 server_line_callback(void *userdata, str *line)
{
struct cmsrv *s = (struct cmsrv *)userdata;
struct lia_list *list = al_array_at(s->server.lists, 0);
- if (al_str_eq(line, al_str_c(";PAUSE"))) {
+ if (al_str_eq(line, &al_str_c(";PAUSE"))) {
lia_list_toggle_pause(list, LIANA_SEQUENCE_ANY, -1.0);
- } else if (al_str_eq(line, al_str_c(";NEXT"))) {
+ } else if (al_str_eq(line, &al_str_c(";NEXT"))) {
lia_list_skip(list, LIANA_SEQUENCE_ANY, 1);
- } else if (al_str_eq(line, al_str_c(";PREV"))) {
+ } else if (al_str_eq(line, &al_str_c(";PREV"))) {
lia_list_skip(list, LIANA_SEQUENCE_ANY, -1);
- } else if (al_str_eq(line, al_str_c(";SHUFFLE"))) {
+ } else if (al_str_eq(line, &al_str_c(";SHUFFLE"))) {
lia_list_shuffle(list);
- } else if (al_str_eq(line, al_str_c(";SORT"))) {
+ } else if (al_str_eq(line, &al_str_c(";SORT"))) {
lia_list_sort(list);
- } else if (al_str_eq(line, al_str_c(";REVERSE"))) {
+ } else if (al_str_eq(line, &al_str_c(";REVERSE"))) {
lia_list_reverse(list);
- } else if (al_str_eq(line, al_str_c(";CLEAR"))) {
+ } else if (al_str_eq(line, &al_str_c(";CLEAR"))) {
lia_list_clear(list);
} else {
struct nn_packet *packet = nn_packet_create();
@@ -63,7 +63,7 @@ static u8 server_line_callback(void *userdata, str *line)
nn_packet_write_u8(packet, CAMU_RESOURCE_HTTP);
#endif
#if CACHE_HAVE_CDIO
- } else if (al_str_cmp(line, al_str_c("cdda://"), 0, 7) == 0) {
+ } else if (al_str_cmp(line, &al_str_c("cdda://"), 0, 7) == 0) {
nn_packet_write_u8(packet, CAMU_RESOURCE_CDIO);
#endif
} else {
@@ -115,8 +115,8 @@ static s32 log_callback(void *userdata, u8 level, char *message)
{
struct cmsrv *s = (struct cmsrv *)userdata;
(void)level;
- cmsrv_ui_push_message(&s->ui, message);
- return al_strlen(message);
+ cmsrv_ui_push_message(&s->ui, al_strndup(message, AL_LOG_MESSAGE_SIZE));
+ return al_strnlen(message, AL_LOG_MESSAGE_SIZE);
}
#endif
@@ -172,7 +172,7 @@ s32 wmain(s32 argc, wchar_t **argv)
camu_server_init(&s.server, &s.loop);
s.server.meta_callback = server_meta_callback;
s.server.userdata = &s;
- if (!camu_server_listen(&s.server, CAMU_TEST_TYPE, CAMU_TEST_ADDR, CAMU_PORT)) {
+ if (!camu_server_listen(&s.server, CAMU_TEST_TYPE, &CAMU_TEST_ADDR, CAMU_PORT)) {
return EXIT_FAILURE;
}
@@ -181,9 +181,9 @@ s32 wmain(s32 argc, wchar_t **argv)
nn_socket_init(&s.local.sock, NNWT_SOCKET_NONBLOCKING);
s.local.cli.callback = server_line_callback;
s.local.cli.userdata = &s;
- nn_line_processor_init(&s.local.cli, al_str_c("\n"));
+ nn_line_processor_init(&s.local.cli, &al_str_c("\n"));
nn_line_processor_open_socket(&s.local.cli, &s.local.sock);
- if (nn_socket_bind(&s.local.sock, CAMU_TEST_CONTROL_PATH, 0) && nn_socket_listen(&s.local.sock)) {
+ if (nn_socket_bind(&s.local.sock, &CAMU_TEST_CONTROL_PATH, 0) && nn_socket_listen(&s.local.sock)) {
nn_line_processor_run(&s.local.cli, &s.loop);
}
#endif
diff --git a/src/fruits/cmsrv/ui.c b/src/fruits/cmsrv/ui.c
index ba1f8b3..e64f580 100644
--- a/src/fruits/cmsrv/ui.c
+++ b/src/fruits/cmsrv/ui.c
@@ -82,15 +82,22 @@ static void render_log(struct cmsrv_ui *ui)
u32 max_width = ncplane_dim_x(n) - 2;
u32 max_height = ncplane_dim_y(n) - 2;
- u64 c = 0;
- ncchannels_set_fg_default(&c);
- ncplane_rounded_box(n, NCSTYLE_NONE, c, max_height + 1, max_width + 1, 0);
-
- u32 size = ui->log.messages.size;
+ u32 size = ui->log.messages.count;
u32 index = size > max_height ? size - max_height : 0;
for (u32 i = index; i < size; i++) {
- ncplane_putnstr_yx(n, (i - index) + 1, 1, max_width, al_array_at(ui->log.messages, i));
+ // We can't use putnstr here to control the width because lots of
+ // these messages will have wide characters.
+ ncplane_putstr_yx(n, (i - index) + 1, 1, al_array_at(ui->log.messages, i));
+ }
+ for (u32 i = 0; i < index; i++) {
+ al_free(al_array_at(ui->log.messages, i));
}
+ al_array_remove_range(ui->log.messages, 0, index);
+
+ u64 c = 0;
+ ncchannels_set_fg_default(&c);
+ ncplane_cursor_move_yx(n, 0, 0);
+ ncplane_rounded_box(n, NCSTYLE_NONE, c, max_height + 1, max_width + 1, 0);
}
static void layout_lists(struct cmsrv_ui *ui, struct ncplane *parent)
@@ -117,7 +124,7 @@ static void erase_lists(struct cmsrv_ui *ui)
static void putnwstr_maxwidth_yx(struct ncplane *n, u32 y, u32 x, u32 maxwidth, wstr *w)
{
ncplane_cursor_move_yx(n, y, x);
- u32 end = MIN(w->len, maxwidth);
+ u32 end = MIN(w->length, maxwidth);
for (u32 i = 0; i < end; i++) {
ncplane_putwc(n, al_wstr_at(w, i));
}
@@ -135,11 +142,11 @@ static void render_lists(struct cmsrv_ui *ui)
struct lia_list *list;
al_array_foreach(ui->server->lists, i, list) {
if (current_line++ >= max_height) break;
- for (u32 j = 0; j < MIN(max_width, list->name.len); j++) {
+ for (u32 j = 0; j < MIN(max_width, list->name.length); j++) {
ncplane_putchar_yx(n, i, j, al_str_at(&list->name, j));
}
s32 index = MAX(list->current - (entries_per_list / 2), 0);
- s32 size = (s32)list->entries.size;
+ s32 size = (s32)list->entries.count;
s32 end = MIN(index + entries_per_list, size);
for (s32 j = index; j < end; j++) {
struct lia_list_entry *entry = al_array_at(list->entries, j);
@@ -197,7 +204,7 @@ static void render_nodes(struct cmsrv_ui *ui)
ncplane_putnstr_yx(n, i, 0, max_width, strbuf);
struct lia_node_connection *conn;
al_array_foreach(node->connections, j, conn) {
- al_snprintf(strbuf, sizeof(strbuf), "%u", conn->pool.ready.size);
+ al_snprintf(strbuf, sizeof(strbuf), "%u", conn->pool.ready.count);
ncplane_putnstr_yx(n, i + j + 1, 2, max_width, strbuf);
}
}
diff --git a/src/fruits/cmv/cmv.c b/src/fruits/cmv/cmv.c
index 02beffb..55d7d55 100644
--- a/src/fruits/cmv/cmv.c
+++ b/src/fruits/cmv/cmv.c
@@ -14,7 +14,7 @@
#ifndef CAMU_SINK_ONLY
#ifndef _WIN32
-static str *CMV_UNIX_PATH = al_str_c("/tmp/cmv_sock");
+static str CMV_UNIX_PATH = al_str_c("/tmp/cmv_sock");
#endif
#endif
@@ -93,9 +93,9 @@ s32 wmain(s32 argc, wchar_t **argv)
bool local = argc > 1;
if (local) {
#ifndef _WIN32
- type = NNWT_SOCKET_UNIX; addr = CMV_UNIX_PATH;
+ type = NNWT_SOCKET_UNIX; addr = &CMV_UNIX_PATH;
#else
- type = NNWT_SOCKET_TCP; addr = CAMU_LOCALHOST;
+ type = NNWT_SOCKET_TCP; addr = &CAMU_LOCALHOST;
#endif
camu_server_init(&c.server, &c.loop);
c.server.meta_callback = server_meta_callback;
@@ -109,7 +109,7 @@ s32 wmain(s32 argc, wchar_t **argv)
#endif
} else {
type = CAMU_TEST_TYPE;
- addr = CAMU_TEST_ADDR;
+ addr = &CAMU_TEST_ADDR;
}
#else
type = NNWT_SOCKET_TCP; addr = CAMU_TEST_ADDR;
@@ -129,10 +129,10 @@ s32 wmain(s32 argc, wchar_t **argv)
if (local) {
for (s32 i = 1; i < argc; i++) {
#ifndef _WIN32
- str arg = *al_str_cr(argv[i]);
+ str arg = al_str_cr(argv[i]);
#else
str arg;
- if (!al_wstr_to_str(al_wstr_cr(argv[i]), &arg)) {
+ if (!al_wstr_to_str(&al_wstr_cr(argv[i]), &arg)) {
al_log_error("cmv", "Failed to parse argument #%i.", i);
continue;
}
@@ -146,7 +146,7 @@ s32 wmain(s32 argc, wchar_t **argv)
nn_packet_write_u8(packet, CAMU_RESOURCE_HTTP);
#endif
#if CACHE_HAVE_CDIO
- } else if (al_str_cmp(&arg, al_str_c("cdda://"), 0, 7) == 0) {
+ } else if (al_str_cmp(&arg, &al_str_c("cdda://"), 0, 7) == 0) {
nn_packet_write_u8(packet, CAMU_RESOURCE_CDIO);
#endif
} else {
diff --git a/src/fruits/common.h b/src/fruits/common.h
index c7b432a..fb9a127 100644
--- a/src/fruits/common.h
+++ b/src/fruits/common.h
@@ -3,13 +3,13 @@
AL_UNUSED_VARIABLE_PUSH
-static str *CAMU_DB_PATH = al_str_c("/home/andrew/c/camu/data/camu_db_test");
+static str CAMU_DB_PATH = al_str_c("/home/andrew/c/camu/data/camu_db_test");
-static str *CAMU_TEST_IP = al_str_c("108.52.160.112");
-static str *CAMU_LOCALHOST = al_str_c("127.0.0.1");
+static str CAMU_TEST_IP = al_str_c("108.52.160.112");
+static str CAMU_LOCALHOST = al_str_c("127.0.0.1");
-static str *CAMU_TEST_PATH = al_str_c("/tmp/camu_sock");
-static str *CAMU_TEST_CONTROL_PATH = al_str_c("/tmp/camu_control_sock");
+static str CAMU_TEST_PATH = al_str_c("/tmp/camu_sock");
+static str CAMU_TEST_CONTROL_PATH = al_str_c("/tmp/camu_control_sock");
AL_UNUSED_VARIABLE_POP
diff --git a/src/fruits/ctv/ctv.c b/src/fruits/ctv/ctv.c
index b350c8a..ded4182 100644
--- a/src/fruits/ctv/ctv.c
+++ b/src/fruits/ctv/ctv.c
@@ -1,5 +1,6 @@
#include <stl/window.h>
#include <stl/platform.h>
+#include <al/log.h>
#include "../../screen/screen.h"
#include "../../render/renderer_libplacebo.h"
@@ -106,10 +107,8 @@ static s32 log_callback(void *userdata, u8 level, char *message)
{
(void)userdata;
(void)level;
- __android_log_print(ANDROID_LOG_DEBUG, "CTV", "%s", message);
- s32 ret = al_strlen(message);
- al_free(message);
- return ret;
+ __android_log_print(ANDROID_LOG_DEBUG, "CTV", "%.*s", AL_LOG_MESSAGE_SIZE, message);
+ return al_strnlen(message, AL_LOG_MESSAGE_SIZE);
}
void glfmMain(GLFMDisplay *display)
diff --git a/src/fruits/ctv/meson.build b/src/fruits/ctv/meson.build
index dff208d..5a4dca8 100644
--- a/src/fruits/ctv/meson.build
+++ b/src/fruits/ctv/meson.build
@@ -1,4 +1,4 @@
-ctv_src = ['ctv.c']
+ctv_src = ['ctv.c', '../../sink/common.c']
ctv_deps = [common_deps, libsink]
ctv_args = ['-DCAMU_MIXER_THREADED', '-DCAMU_SCREEN_THREADED']
diff --git a/src/fruits/droid/ctv/gradle/libs.versions.toml b/src/fruits/droid/ctv/gradle/libs.versions.toml
index ea02696..e1ef643 100644
--- a/src/fruits/droid/ctv/gradle/libs.versions.toml
+++ b/src/fruits/droid/ctv/gradle/libs.versions.toml
@@ -1,5 +1,5 @@
[versions]
-agp = "8.7.3"
+agp = "8.8.0"
[libraries]
diff --git a/src/fruits/droid/ctv/gradle/wrapper/gradle-wrapper.properties b/src/fruits/droid/ctv/gradle/wrapper/gradle-wrapper.properties
index 354c93e..698ab10 100644
--- a/src/fruits/droid/ctv/gradle/wrapper/gradle-wrapper.properties
+++ b/src/fruits/droid/ctv/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Wed Oct 30 14:10:25 EDT 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/src/liana/handlers.c b/src/liana/handlers.c
index 1a28024..e52d8bb 100644
--- a/src/liana/handlers.c
+++ b/src/liana/handlers.c
@@ -1,7 +1,9 @@
#include "handlers.h"
#include "handlers/codec.h"
+#ifdef CACHE_HAVE_CDIO
#include "handlers/cdio.h"
+#endif
struct lia_handler_entry liana_handlers[] = {
{
@@ -29,7 +31,7 @@ struct lia_handler_entry liana_handlers[] = {
struct lia_handler_entry *lia_handler_by_name(str *name)
{
for (u32 i = 0; i < ARRAY_SIZE(liana_handlers); i++) {
- if (al_str_eq(liana_handlers[i].name, name)) {
+ if (al_str_eq(&liana_handlers[i].name, name)) {
return &liana_handlers[i];
}
}
diff --git a/src/liana/handlers.h b/src/liana/handlers.h
index 0193f18..223ead5 100644
--- a/src/liana/handlers.h
+++ b/src/liana/handlers.h
@@ -3,7 +3,7 @@
#include "handler.h"
struct lia_handler_entry {
- str *name;
+ str name;
struct lia_server_handler *(*create_server_handler)(void);
struct lia_client_handler *(*create_client_handler)(void);
};
diff --git a/src/liana/handlers/codec_server.c b/src/liana/handlers/codec_server.c
index 24552bb..ff62d47 100644
--- a/src/liana/handlers/codec_server.c
+++ b/src/liana/handlers/codec_server.c
@@ -43,7 +43,7 @@ static void codec_server_write_info(struct lia_server_handler *handler, struct n
struct lia_codec_server *codec = (struct lia_codec_server *)handler;
u64 duration = codec->demux->get_duration(codec->demux);
nn_packet_write_u64(packet, duration);
- nn_packet_write_u32(packet, codec->demux->streams.size);
+ nn_packet_write_u32(packet, codec->demux->streams.count);
struct camu_codec_stream *stream;
al_array_foreach_ptr(codec->demux->streams, i, stream) {
nn_packet_write_u8(packet, stream->mode);
diff --git a/src/liana/list.c b/src/liana/list.c
index 3c8a9c0..fa21fe6 100644
--- a/src/liana/list.c
+++ b/src/liana/list.c
@@ -9,7 +9,7 @@
/*
static void buffer_ahead(struct lia_list *list)
{
- s32 size = (s32)list->entries.size;
+ s32 size = (s32)list->entries.count;
if (list->current >= 0 && list->current + 1 < size) {
s32 ahead = list->current + 1;
for (s32 i = ahead; i < MIN(ahead + LIANA_BUFFER_AHEAD, size); i++) {
@@ -89,7 +89,7 @@ static bool entry_load_and_get_duration(struct lia_list *list, struct lia_list_e
if (status == LIANA_ENTRY_ERRORED) {
if (sequence >= 0) {
al_array_remove_at(list->entries, (u32)sequence);
- if (sequence == list->current && (u32)list->current == list->entries.size) {
+ if (sequence == list->current && (u32)list->current == list->entries.count) {
// This maps to the behavior of only skipping ahead on errors.
list->current--;
list->idle = true;
@@ -139,7 +139,7 @@ static void set_queued(struct lia_list *list)
static void evaluate_queued(struct lia_list *list)
{
- s32 size = (s32)list->entries.size;
+ s32 size = (s32)list->entries.count;
s32 next = list->current + 1;
if (next >= size || next == list->queued)
return;
@@ -226,7 +226,7 @@ static bool handle_add(struct lia_list *list, struct lia_list_entry *entry)
};
struct lia_list_sink *sink;
al_array_foreach(list->sinks, i, sink) {
- al_assert(sink->set == -1);
+ //al_assert(sink->set == -1);
sink->set = list->current;
sink->callback(sink->userdata, LIANA_SINK_SET, entry, list->current, &time);
}
@@ -276,7 +276,7 @@ static void unset_all(struct lia_list *list)
static void handle_unset(struct lia_list *list)
{
unset_all(list);
- list->current = list->entries.size - 1;
+ list->current = list->entries.count - 1;
list->idle = true;
struct lia_list_sink *sink;
al_array_foreach(list->sinks, i, sink) {
@@ -286,7 +286,7 @@ static void handle_unset(struct lia_list *list)
static struct lia_list_entry *get_entry_from_sequence(struct lia_list *list, s32 sequence)
{
- s32 size = (s32)list->entries.size;
+ s32 size = (s32)list->entries.count;
if (sequence < 0 || sequence >= size) return NULL;
return al_array_at(list->entries, sequence);
}
@@ -555,7 +555,7 @@ static bool handle_end(struct lia_list *list, u32 id, u32 reset_id)
return false;
#endif
- s32 size = (s32)list->entries.size;
+ s32 size = (s32)list->entries.count;
if (sequence == list->current) {
s32 next = sequence + 1;
if (list->queued >= 0) {
@@ -588,7 +588,7 @@ static void handle_reverse(struct lia_list *list)
{
if (list->current == -1) return;
struct lia_list_entry *previous = al_array_at(list->entries, list->current);
- u32 size = list->entries.size;
+ u32 size = list->entries.count;
for (u32 i = 0; i < size; i++) {
u32 tail = size - (i + 1);
if (tail <= i) break;
@@ -609,10 +609,15 @@ static void handle_shuffle(struct lia_list *list)
{
if (list->current == -1) return;
struct lia_list_entry *previous = al_array_at(list->entries, list->current);
- u32 size = list->entries.size;
- if (size == 0) return;
- for (u32 i = 0; i < size - 1; i++) {
- u32 j = i + al_rand() / (AL_RAND_MAX / (size - i) + 1);
+ u32 size = list->entries.count;
+ if (size <= 1) return;
+ /* https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
+ for i from 0 to n−2 do
+ j ← random integer such that i ≤ j ≤ n-1
+ exchange a[i] and a[j]
+ */
+ for (u32 i = 0; i < size - 2; i++) {
+ u32 j = i + (al_rand() % (size - i));
SWAP(al_array_at(list->entries, i), al_array_at(list->entries, j));
}
adjust_current(list, previous);
@@ -627,13 +632,13 @@ static void handle_clear(struct lia_list *list)
al_wstr_free(&entry->name);
al_free(entry);
}
- list->entries.size = 0;
+ list->entries.count = 0;
}
static void run_queue(struct lia_list *list)
{
if (!list->cmd) {
- if (al_array_is_empty(list->queue)) return;
+ if (!list->queue.count) return;
al_array_pop_at(list->queue, 0, list->cmd);
}
struct lia_list_cmd *cmd = list->cmd;
diff --git a/src/liana/list_cmp.h b/src/liana/list_cmp.h
index ef923fb..c9c0812 100644
--- a/src/liana/list_cmp.h
+++ b/src/liana/list_cmp.h
@@ -8,36 +8,37 @@ AL_UNUSED_FUNCTION_PUSH
static void camu_db_num_from_path(wstr *path, s64 *id, s64 *index)
{
- s32 index0 = al_wstr_rfind(path, L'/');
- if (index0 < 0) return;
+ u32 last_slash = al_wstr_rfind(path, L'/');
+ if (last_slash == al_wstr_npos) {
+ return;
+ }
+ wstr temp = al_wstr_substr(path, last_slash + 1, path->length);
- wstr w = *al_wstr_substr(path, index0 + 1, path->len);
- index0 = al_wstr_find(&w, L'_');
- if (index0 < 0) return;
- w = *al_wstr_substr(&w, index0 + 1, w.len);
- index0 = al_wstr_find(&w, L'_');
- if (index0 < 0) return;
- w = *al_wstr_substr(&w, index0 + 1, w.len);
- index0 = al_wstr_find(&w, L'_');
- if (index0 < 0) return;
- w = *al_wstr_substr(&w, 0, index0);
+ // Skip 2 '_' characters.
+ if (!(al_wstr_tok(&temp, L'_') && al_wstr_tok(&temp, L'_'))) {
+ return;
+ }
- str s;
- al_wstr_to_str(&w, &s);
- s64 num = al_str_to_long(&s, 10);
- al_str_free(&s);
- if (num == INT64_MIN || num == INT64_MAX) return;
+ u32 target = al_wstr_find(&temp, L'_');
+ if (target == al_wstr_npos) {
+ return;
+ }
+ temp = al_wstr_substr(&temp, 0, target);
+
+ bool error;
+ s64 num = al_wstr_to_long(&temp, 10, &error);
+ if (error) return;
*id = num;
- index0 = al_wstr_rfind(path, L'.');
- s32 index1 = al_wstr_rfind(path, 'a');
- if (index0 < 0 || index1 < 0) return;
- w = *al_wstr_substr(path, index1 + 1, index0);
+ u32 ext_dot = al_wstr_rfind(path, L'.');
+ u32 media_a = al_wstr_rfind(path, 'a');
+ if (ext_dot == al_wstr_npos || media_a == al_wstr_npos) {
+ return;
+ }
+ temp = al_wstr_substr(path, media_a + 1, ext_dot);
- al_wstr_to_str(&w, &s);
- num = al_str_to_long(&s, 10);
- al_str_free(&s);
- if (num == INT64_MIN || num == INT64_MAX) return;
+ num = al_wstr_to_long(&temp, 10, &error);
+ if (error) return;
*index = num;
}
diff --git a/src/liana/vcr.c b/src/liana/vcr.c
index 06f0fe4..c5b704e 100644
--- a/src/liana/vcr.c
+++ b/src/liana/vcr.c
@@ -53,9 +53,9 @@ void lia_vcr_init(struct lia_vcr *vcr, struct nn_event_loop *loop, struct nn_pac
static void return_entire_cache(struct lia_vcr_track *track)
{
struct lia_vcr *vcr = track->vcr;
- u32 size = track->cache.cache.size;
- nn_packet_stream_return_packets(vcr->data, al_array_offset(track->cache.cache, 0), size);
- track->cache.cache.size = 0;
+ u32 count = track->cache.cache.count;
+ nn_packet_stream_return_packets(vcr->data, al_array_offset(track->cache.cache, 0), count);
+ track->cache.cache.count = 0;
}
static nn_thread_result NNWT_THREADCALL vcr_track_thread(void *userdata)
@@ -88,7 +88,7 @@ static nn_thread_result NNWT_THREADCALL vcr_track_thread(void *userdata)
u32 size = nn_packet_get_size(packet);
u64 buffer = al_atomic_sub(u64)(&vcr->count, size, AL_ATOMIC_RELAXED);
#ifndef CAMU_DIRECT_MODE
- u8 buffered = al_atomic_load(u8)(&track->buffered, AL_ATOMIC_RELAXED);
+ bool buffered = al_atomic_load(bool)(&track->buffered, AL_ATOMIC_RELAXED);
if (buffered && buffer <= vcr->mark.low) {
nn_signal_send(&vcr->signal);
}
@@ -180,7 +180,7 @@ void lia_vcr_add_track(struct lia_vcr *vcr, struct lia_vcr_track *track)
track->vcr = vcr;
nn_cond_init(&track->cond);
nn_mutex_init(&track->mutex);
- al_atomic_store(u8)(&track->buffered, !VCR_TRACK_THREADED(track), AL_ATOMIC_RELAXED);
+ al_atomic_store(bool)(&track->buffered, !VCR_TRACK_THREADED(track), AL_ATOMIC_RELAXED);
nn_packet_cache_init(&track->cache, 256);
al_array_push(vcr->tracks, track);
al_atomic_store(s32)(&track->state, VCR_TRACK_RUNNING, AL_ATOMIC_RELAXED);
@@ -188,7 +188,7 @@ void lia_vcr_add_track(struct lia_vcr *vcr, struct lia_vcr_track *track)
bool lia_vcr_is_empty(struct lia_vcr *vcr)
{
- return al_array_is_empty(vcr->tracks);
+ return !vcr->tracks.count;
}
static struct lia_vcr_track *get_track_from_index(struct lia_vcr *vcr, s32 index)
@@ -203,10 +203,10 @@ static struct lia_vcr_track *get_track_from_index(struct lia_vcr *vcr, s32 index
#ifndef CAMU_DIRECT_MODE
static void cork_if_buffered(struct lia_vcr *vcr, u64 buffer)
{
- u8 buffered = 1;
+ bool buffered = true;
struct lia_vcr_track *track;
al_array_foreach(vcr->tracks, i, track) {
- buffered &= al_atomic_load(u8)(&track->buffered, AL_ATOMIC_RELAXED);
+ buffered &= al_atomic_load(bool)(&track->buffered, AL_ATOMIC_RELAXED);
}
if (buffered) {
if (vcr->expand == VCR_EXPAND_UNTOUCHED) {
@@ -263,15 +263,15 @@ void lia_vcr_push_packet(struct lia_vcr *vcr, struct nn_packet *packet)
break;
}
if (VCR_TRACK_THREADED(track)) {
- if (!nn_packet_cache_send_packet(&track->cache, packet)) {
- break;
- }
u64 buffer;
if ((buffer = al_atomic_add(u64)(&vcr->count, size, AL_ATOMIC_RELAXED)) >= vcr->mark.buffered) {
#ifndef CAMU_DIRECT_MODE
cork_if_buffered(vcr, buffer);
#endif
}
+ if (!nn_packet_cache_send_packet(&track->cache, packet)) {
+ break;
+ }
// Keep packet.
return;
} else {
@@ -301,13 +301,12 @@ void lia_vcr_push_packet(struct lia_vcr *vcr, struct nn_packet *packet)
void lia_vcr_set_buffered(struct lia_vcr_track *track)
{
- al_atomic_store(u8)(&track->buffered, 1, AL_ATOMIC_RELAXED);
+ al_atomic_store(bool)(&track->buffered, true, AL_ATOMIC_RELAXED);
}
void lia_vcr_cork(struct lia_vcr_track *track)
{
al_atomic_store(s32)(&track->state, VCR_TRACK_STOPPED, AL_ATOMIC_RELAXED);
- al_atomic_store(u8)(&track->buffered, 1, AL_ATOMIC_RELAXED);
}
void lia_vcr_uncork(struct lia_vcr_track *track)
@@ -350,7 +349,7 @@ void lia_vcr_flush(struct lia_vcr *vcr)
if (VCR_TRACK_THREADED(track)) {
vcr_track_close_internal(track);
return_entire_cache(track);
- al_atomic_store(u8)(&track->buffered, 0, AL_ATOMIC_RELAXED);
+ al_atomic_store(bool)(&track->buffered, false, AL_ATOMIC_RELAXED);
track->client->flush(track->client);
nn_packet_cache_enable(&track->cache);
al_atomic_store(s32)(&track->state, VCR_TRACK_RUNNING, AL_ATOMIC_RELAXED);
diff --git a/src/liana/vcr.h b/src/liana/vcr.h
index 8aefaa2..bd4f0f9 100644
--- a/src/liana/vcr.h
+++ b/src/liana/vcr.h
@@ -15,7 +15,7 @@ struct lia_vcr_track {
struct camu_codec_stream stream;
struct lia_client_handler *client;
atomic(s32) state;
- atomic(u8) buffered;
+ atomic(bool) buffered;
struct nn_packet_cache cache;
struct nn_cond cond;
struct nn_mutex mutex;
diff --git a/src/libsink/sink.c b/src/libsink/sink.c
index 03f76b7..0f56c5b 100644
--- a/src/libsink/sink.c
+++ b/src/libsink/sink.c
@@ -11,6 +11,8 @@
#include "sink.h"
#include "common.h"
+//#define CAMU_SINK_ONESHOT
+
#ifndef CAMU_SINK_NO_VIDEO
#include "../render/renderer_libplacebo.h"
#endif
@@ -58,8 +60,6 @@ enum {
// If a buffer is still INIT or QUEUED after the entry is configured, it's "empty".
#define BUFFER_EMPTY(buf) ((buf)->state == BUFFER_INIT || (buf)->state == BUFFER_QUEUED)
-#define BUFFER_NOT_EMPTY(buf) (!BUFFER_EMPTY(buf))
-
#define AUDIO_EMPTY(entry) BUFFER_EMPTY(&(entry)->audio)
#ifndef CAMU_SINK_NO_VIDEO
#define VIDEO_EMPTY(entry) BUFFER_EMPTY(&(entry)->video)
@@ -487,7 +487,7 @@ static void maybe_remove_previous(struct camu_sink *sink)
al_array_foreach(sink->previous, i, previous) {
remove_entry_buffers(sink, previous);
}
- sink->previous.size = 0;
+ sink->previous.count = 0;
}
// Due to the looseness of the previous queue, we may have to explicitly remove an entry
@@ -558,7 +558,7 @@ static void maybe_cleanup_old_entries(struct camu_sink *sink)
al_array_remove_at(sink->entries, i);
lia_client_disconnect(&entry->client);
}
- if (sink->entries.size <= ENTRY_MAX_AGE) return;
+ if (sink->entries.count <= ENTRY_MAX_AGE) return;
}
// Checking sink->lru >= ENTRY_MAX_AGE should guarantee
@@ -570,7 +570,7 @@ static void maybe_cleanup_old_entries(struct camu_sink *sink)
al_array_remove_at(sink->entries, i);
lia_client_disconnect(&entry->client);
}
- if (sink->entries.size <= ENTRY_MAX_AGE) return;
+ if (sink->entries.count <= ENTRY_MAX_AGE) return;
}
}
}
@@ -714,6 +714,10 @@ static void pause_and_swap_to(struct camu_sink *sink, struct camu_sink_entry *ta
static bool end_entry_and_advance_queue(struct camu_sink *sink, struct camu_sink_entry *entry)
{
al_log_info("sink", "Entry ended.");
+#ifdef CAMU_SINK_ONESHOT
+ sink->callback(sink->userdata, CAMU_SINK_MOCK_CLOSE, 0, NULL);
+ return false;
+#endif
entry->ended = true;
queue_cmd(sink, (struct camu_sink_cmd){
.op = END,
@@ -743,6 +747,7 @@ static void audio_buffer_callback(void *userdata, u8 op)
struct camu_sink *sink = entry->sink;
switch (op) {
case CAMU_BUFFER_BUFFERED:
+ lia_vcr_set_buffered(entry->audio.track);
nn_mutex_lock(&sink->mutex);
add_audio_if_set_and_buffered(entry);
nn_mutex_unlock(&sink->mutex);
@@ -765,7 +770,6 @@ static void audio_buffer_callback(void *userdata, u8 op)
nn_mutex_unlock(&sink->mutex);
break;
case CAMU_BUFFER_EOF: {
- lia_vcr_set_buffered(entry->audio.track);
nn_mutex_lock(&sink->mutex);
al_log_info("sink", "Audio EOF.");
if (entry->audio.state == BUFFER_ADDED) {
@@ -797,6 +801,7 @@ static void video_buffer_callback(void *userdata, u8 op)
struct camu_sink *sink = entry->sink;
switch (op) {
case CAMU_BUFFER_BUFFERED: {
+ lia_vcr_set_buffered(entry->video.track);
nn_mutex_lock(&sink->mutex);
add_video_if_set_and_buffered(entry);
nn_mutex_unlock(&sink->mutex);
@@ -809,7 +814,6 @@ static void video_buffer_callback(void *userdata, u8 op)
lia_vcr_uncork(entry->video.track);
break;
case CAMU_BUFFER_EOF: {
- lia_vcr_set_buffered(entry->video.track);
bool swapped = false;
nn_mutex_lock(&sink->mutex);
al_log_info("sink", "Video EOF.");
@@ -867,7 +871,7 @@ static void clock_callback(void *userdata, u8 op)
}
}
-static void evaluate_latency(struct camu_sink *sink, struct camu_sink_entry *entry)
+static void evaluate_and_set_latency(struct camu_sink *sink, struct camu_sink_entry *entry)
{
#ifdef CAMU_SINK_LOCAL
#ifndef CAMU_SINK_NO_VIDEO
@@ -933,7 +937,7 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
al_assert(false);
}
if (VIDEO_ADDED_OR_EMPTY(entry)) {
- evaluate_latency(sink, entry);
+ evaluate_and_set_latency(sink, entry);
}
nn_mutex_unlock(&sink->mutex);
break;
@@ -954,7 +958,7 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
al_assert(false);
}
if (AUDIO_ADDED_OR_EMPTY(entry)) {
- evaluate_latency(sink, entry);
+ evaluate_and_set_latency(sink, entry);
}
nn_mutex_unlock(&sink->mutex);
break;
@@ -1292,6 +1296,7 @@ static bool set_command_callback(void *userdata, struct nn_rpc_connection *conn,
struct camu_sink_entry *current = sink->current;
#ifdef CAMU_SINK_LOCAL
+ (void)at;
if (current && !current->ended && !camu_clock_is_paused(&current->clock)) {
camu_clock_pause(&current->clock, 0);
}
diff --git a/src/libsink/sink.h b/src/libsink/sink.h
index 10fc182..68fac15 100644
--- a/src/libsink/sink.h
+++ b/src/libsink/sink.h
@@ -29,6 +29,7 @@ enum {
CAMU_SINK_START,
CAMU_SINK_STOP,
CAMU_SINK_CLEAR,
+ CAMU_SINK_MOCK_CLOSE,
CAMU_SINK_EXIT
};
diff --git a/src/mixer/audio_miniaudio.c b/src/mixer/audio_miniaudio.c
index f0afeee..ba093f4 100644
--- a/src/mixer/audio_miniaudio.c
+++ b/src/mixer/audio_miniaudio.c
@@ -155,7 +155,7 @@ static void data_callback(ma_device *device, void *output, const void *input, u3
}
#define DEFAULT_PERIODS 3
-#define DEFAULT_PERIOD_SIZE_IN_MILLISECONDS 64
+#define DEFAULT_PERIOD_SIZE_IN_MILLISECONDS 48
static bool audio_miniaudio_configure_stream(struct camu_audio *audio, void *opaque)
{
diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c
index 1360934..36ac95d 100644
--- a/src/mixer/mixer.c
+++ b/src/mixer/mixer.c
@@ -12,7 +12,7 @@
static s32 data_callback(void *userdata, u8 *data, s32 frame_count, bool *silence)
{
struct camu_mixer *mixer = (struct camu_mixer *)userdata;
- size_t req = camu_audio_format_samples_to_bytes(&mixer->fmt.req, (size_t)frame_count);
+ ptrdiff_t req = (ptrdiff_t)camu_audio_format_samples_to_bytes(&mixer->fmt.req, (size_t)frame_count);
#ifdef CAMU_MIXER_THREADED_START_STOP
if (UNLIKELY(mixer->paused)) {
al_memset(data, 0, req);
@@ -36,17 +36,17 @@ static s32 data_callback(void *userdata, u8 *data, s32 frame_count, bool *silenc
// Read from all current buffers on each callback to
// emulate the behavior of an actual mixer.
al_array_foreach(mixer->buffers, i, buf) {
- if (i < mixer->buffers.size - 1) {
+ if (i < mixer->buffers.count - 1) {
camu_audio_buffer_read(buf, data, req);
}
}
for (;;) {
- if (al_array_is_empty(mixer->buffers)) {
+ if (!mixer->buffers.count) {
al_memset(data, 0, req);
} else {
- size_t signal;
buf = al_array_last(mixer->buffers);
*silence = false;
+ ptrdiff_t signal;
if ((signal = camu_audio_buffer_read(buf, data, req)) < req) {
#ifdef CAMU_MIXER_THREADED
if (al_atomic_load(u8)(&mixer->queued, AL_ATOMIC_RELAXED)) {
@@ -71,7 +71,7 @@ bool camu_mixer_init(struct camu_mixer *mixer, struct camu_audio *audio)
mixer->audio = audio;
mixer->audio->data_callback = data_callback;
mixer->audio->userdata = mixer;
- mixer->audio->init(mixer->audio, al_str_c("cmv"));
+ mixer->audio->init(mixer->audio, &al_str_c("cmv"));
mixer->volume = 1.f;
mixer->paused = true;
mixer->empty_after = 0;
@@ -156,21 +156,21 @@ static void remove_buffer_internal(struct camu_mixer *mixer, struct camu_audio_b
static void run_queue_internal(struct camu_mixer *mixer)
{
struct camu_audio_buffer *buf;
- if (mixer->rem_queue.size > 0) {
+ if (mixer->rem_queue.count > 0) {
al_array_foreach(mixer->rem_queue, i, buf) {
remove_buffer_internal(mixer, buf);
}
- mixer->rem_queue.size = 0;
+ mixer->rem_queue.count = 0;
}
- if (mixer->add_queue.size > 0) {
- al_array_reserve(mixer->buffers, mixer->buffers.size + mixer->add_queue.size);
+ if (mixer->add_queue.count > 0) {
+ al_array_reserve(mixer->buffers, mixer->buffers.count + mixer->add_queue.count);
al_array_foreach(mixer->add_queue, i, buf) {
add_buffer_internal(mixer, buf);
}
- mixer->add_queue.size = 0;
+ mixer->add_queue.count = 0;
}
al_atomic_store(u8)(&mixer->queued, 0, AL_ATOMIC_RELAXED);
- if (al_array_is_empty(mixer->buffers)) {
+ if (!mixer->buffers.count) {
mixer->empty_after = MIXER_TRAILING_SILENCE;
} else {
mixer->empty_after = 0;
@@ -192,7 +192,7 @@ void camu_mixer_add_buffer(struct camu_mixer *mixer, struct camu_audio_buffer *b
al_array_foreach_rev(mixer->rem_queue, i, rbuf) {
if (rbuf == buf) {
al_array_remove_at(mixer->rem_queue, i);
- bool queue_empty = mixer->add_queue.size + mixer->rem_queue.size == 0;
+ bool queue_empty = mixer->add_queue.count + mixer->rem_queue.count == 0;
if (queue_empty) {
al_atomic_store(u8)(&mixer->queued, 0, AL_ATOMIC_RELAXED);
}
@@ -223,7 +223,7 @@ void camu_mixer_remove_buffer(struct camu_mixer *mixer, struct camu_audio_buffer
al_array_foreach_rev(mixer->add_queue, i, rbuf) {
if (rbuf == buf) {
al_array_remove_at(mixer->add_queue, i);
- bool queue_empty = mixer->add_queue.size + mixer->rem_queue.size == 0;
+ bool queue_empty = mixer->add_queue.count + mixer->rem_queue.count == 0;
if (queue_empty) {
al_atomic_store(u8)(&mixer->queued, 0, AL_ATOMIC_RELAXED);
}
@@ -239,7 +239,7 @@ void camu_mixer_remove_buffer(struct camu_mixer *mixer, struct camu_audio_buffer
nn_mutex_unlock(&mixer->mutex);
#else
remove_buffer_internal(mixer, buf);
- if (al_array_is_empty(mixer->buffers)) {
+ if (!mixer->buffers.count) {
mixer->empty_after = MIXER_TRAILING_SILENCE;
}
#endif
diff --git a/src/portal/cpy/str.pxd b/src/portal/cpy/str.pxd
index 3ef1e90..77cd093 100644
--- a/src/portal/cpy/str.pxd
+++ b/src/portal/cpy/str.pxd
@@ -2,7 +2,7 @@ include "types.pxd"
cdef extern from "<al/str.h>":
ctypedef struct str:
- u32 len
+ u32 length
u32 alloc
char *data
@@ -11,7 +11,7 @@ cdef extern from "<al/str.h>":
cdef extern from "<al/wstr.h>":
ctypedef struct wstr:
- u32 len
+ u32 length
u32 alloc
wchar_t *data
diff --git a/src/portal/cpy/types.pxd b/src/portal/cpy/types.pxd
index 09cb224..d630afa 100644
--- a/src/portal/cpy/types.pxd
+++ b/src/portal/cpy/types.pxd
@@ -8,7 +8,9 @@ from libc.stdint cimport uint64_t
from libc.stdint cimport int64_t
from libc.stddef cimport wchar_t
-ctypedef bint bool
+from libcpp cimport bool
+cdef extern from "<stdbool.h>":
+ pass
ctypedef uint8_t u8
ctypedef int8_t s8
diff --git a/src/portal/py/modules/youtube.py b/src/portal/py/modules/youtube.py
index 582a16c..9d5a135 100644
--- a/src/portal/py/modules/youtube.py
+++ b/src/portal/py/modules/youtube.py
@@ -27,7 +27,7 @@ ydl_opts = {
'logger': YDLLogger(),
'cachedir': False,
'socket_timeout': 10,
- 'extractor_args': {'youtube': {'skip': ['hls'], 'player_client': ['android_vr']}}
+ 'extractor_args': {'youtube': {'skip': ['hls'], 'player_client': ['tv', 'ios']}} # 'android_vr',
# 'cookiefile': ''
}
diff --git a/src/portal/src/packet_ext.c b/src/portal/src/packet_ext.c
index 9b6d6be..8f30470 100644
--- a/src/portal/src/packet_ext.c
+++ b/src/portal/src/packet_ext.c
@@ -12,7 +12,7 @@ void nn_packet_write_post(struct nn_packet *packet, struct camu_post *post)
NNWT_PACKET_WRITE_TYPE(packet, u8, post->type);
nn_packet_write_str(packet, &post->unique_id);
nn_packet_write_str(packet, &post->url);
- NNWT_PACKET_WRITE_TYPE(packet, u32, post->dates.size);
+ NNWT_PACKET_WRITE_TYPE(packet, u32, post->dates.count);
struct camu_post_date *date;
al_array_foreach_ptr(post->dates, i, date) {
NNWT_PACKET_WRITE_TYPE(packet, u8, date->type);
@@ -32,7 +32,7 @@ void nn_packet_write_post(struct nn_packet *packet, struct camu_post *post)
nn_packet_write_optional_int(packet, &post->quotes);
nn_packet_write_optional_int(packet, &post->comments);
nn_packet_write_optional_int(packet, &post->views);
- NNWT_PACKET_WRITE_TYPE(packet, u32, post->media.size);
+ NNWT_PACKET_WRITE_TYPE(packet, u32, post->media.count);
struct camu_post_media *media;
al_array_foreach_ptr(post->media, i, media) {
NNWT_PACKET_WRITE_TYPE(packet, u8, media->type);
diff --git a/src/portal/src/search.c b/src/portal/src/search.c
index 447e44c..e5d5dca 100644
--- a/src/portal/src/search.c
+++ b/src/portal/src/search.c
@@ -91,7 +91,7 @@ static nn_thread_result NNWT_THREADCALL queue_thread(void *userdata)
al_str_clone(&search->query, &cmd->query);
search->bridge = bridge;
al_array_push(bridge->searches, search);
- al_log_info("portal", "New search %x (%.*s).", id, AL_STR_PRINTF(&cmd->query));
+ al_log_info("portal", "New search %x (%.*s).", id, al_str_fmt(&cmd->query));
result.id = search->id;
} else {
}
@@ -107,7 +107,7 @@ static nn_thread_result NNWT_THREADCALL queue_thread(void *userdata)
al_array_foreach_ptr(search->pages, j, page) {
if (page->num == cmd->num) break;
}
- al_log_info("portal", "Loading page %i (%.*s).", cmd->num, AL_STR_PRINTF(&search->query));
+ al_log_info("portal", "Loading page %i (%.*s).", cmd->num, al_str_fmt(&search->query));
if (portal_bridge_get_page(search, search->id, cmd->num) == -1) {
break;
}
@@ -125,7 +125,7 @@ static nn_thread_result NNWT_THREADCALL queue_thread(void *userdata)
}
camu_queue_push(bridge->results, result);
}
- bridge->queue.size = 0;
+ bridge->queue.count = 0;
nn_signal_send(&bridge->results_signal);
}
nn_mutex_unlock(&bridge->mutex);
@@ -164,7 +164,7 @@ void camu_portal_init(struct camu_portal_bridge *bridge, struct camu_post_cache
void camu_portal_create_search(struct camu_portal_bridge *bridge, str *module, str *query,
void (*callback)(void *, void *, struct camu_portal_result *), void *userdata)
{
- struct camu_portal_cmd cmd;
+ struct camu_portal_cmd cmd = { 0 };
cmd.op = CAMU_CLIENT_CREATE_SEARCH;
al_str_clone(&cmd.module, module);
al_str_clone(&cmd.query, query);
@@ -181,7 +181,7 @@ void camu_portal_create_search(struct camu_portal_bridge *bridge, str *module, s
void camu_portal_get_page(struct camu_portal_bridge *bridge, s32 id, u32 num,
void (*callback)(void *, void *, struct camu_portal_result *), void *userdata)
{
- struct camu_portal_cmd cmd;
+ struct camu_portal_cmd cmd = { 0 };
cmd.op = CAMU_CLIENT_GET_PAGE;
cmd.id = id;
cmd.num = num;
diff --git a/src/render/queue_libplacebo.c b/src/render/queue_libplacebo.c
index 861dd5e..22df3dc 100644
--- a/src/render/queue_libplacebo.c
+++ b/src/render/queue_libplacebo.c
@@ -219,7 +219,7 @@ static bool map_av_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *
ASS_Image *ass_frame = ass_render_frame(lq->ass_renderer, lq->ass_track, now, &change);
if (ass_frame) {
struct camu_overlay_lp *overlay = NULL;
- if (lq->overlays.size > 0) {
+ if (lq->overlays.count > 0) {
overlay = al_array_last(lq->overlays);
}
if (!overlay || change > 0) {
diff --git a/src/render/renderer.h b/src/render/renderer.h
index a9780e5..c78e1c1 100644
--- a/src/render/renderer.h
+++ b/src/render/renderer.h
@@ -39,7 +39,7 @@ struct camu_renderer {
void *priv);
struct camu_frame_queue *(*create_queue)(struct camu_renderer *);
u32 (*get_latency)(struct camu_renderer *);
- void (*resize)(struct camu_renderer *, s32 *, s32 *);
+ void (*resize)(struct camu_renderer *, s32 *, s32 *, bool);
void (*render)(struct camu_renderer *, struct camu_screen *, bool);
#ifdef CAMU_HAVE_FFMPEG
s32 (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, s32 flags);
diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c
index 3de0fdc..2539e1f 100644
--- a/src/render/renderer_libplacebo.c
+++ b/src/render/renderer_libplacebo.c
@@ -13,7 +13,7 @@
static f32 clear_color[4] = { 0.0f, 0.0f, 0.0f, 1.f };
-static void renderer_lp_resize(struct camu_renderer *renderer, s32 *width, s32 *height)
+static void renderer_lp_resize(struct camu_renderer *renderer, s32 *width, s32 *height, bool double_swap)
{
struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer;
if (lr->swapchain) {
@@ -22,14 +22,18 @@ static void renderer_lp_resize(struct camu_renderer *renderer, s32 *width, s32 *
lr->have_frame = false;
}
pl_swapchain_resize(lr->swapchain, width, height);
+ lr->double_swap = double_swap;
}
}
static void log_callback(void *userdata, enum pl_log_level level, const char *message)
{
(void)userdata;
- (void)level;
- al_log_info("render_libplacebo", message);
+ if (level < PL_LOG_INFO) {
+ al_log_info("render_libplacebo", message);
+ } else {
+ al_log_debug("render_libplacebo", message);
+ }
}
static bool renderer_lp_create_renderer(struct camu_renderer *renderer, s32 *width, s32 *height,
@@ -140,9 +144,10 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, s32 *wid
lr->renderer = pl_renderer_create(lr->logger, lr->gpu);
- lr->have_frame = false;
-
pl_swapchain_resize(lr->swapchain, width, height);
+ lr->double_swap = false;
+
+ lr->have_frame = false;
al_memset(&lr->params, 0, sizeof(struct pl_render_params));
//lr->params = pl_render_fast_params;
@@ -215,6 +220,11 @@ static void renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
}
#endif
+ if (lr->double_swap) {
+ pl_swapchain_swap_buffers(lr->swapchain);
+ lr->double_swap = false;
+ }
+
if (!lr->have_frame) {
struct pl_swapchain_frame frame;
pl_swapchain_start_frame(lr->swapchain, &frame);
@@ -229,7 +239,7 @@ static void renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
bool do_gpu_finish = false;
struct camu_screen_video *video;
- while (scr->videos.size > 0) {
+ while (scr->videos.count > 0) {
bool any_eof = false;
al_array_foreach_ptr(scr->videos, i, video) {
bool weighted;
@@ -269,7 +279,7 @@ static void renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
}
}
- if (al_array_is_empty(scr->videos) && !force) {
+ if (!scr->videos.count && !force) {
return;
}
diff --git a/src/render/renderer_libplacebo.h b/src/render/renderer_libplacebo.h
index 38407bb..a4bd40e 100644
--- a/src/render/renderer_libplacebo.h
+++ b/src/render/renderer_libplacebo.h
@@ -26,6 +26,7 @@ struct camu_renderer_lp {
pl_gpu gpu;
pl_log logger;
pl_swapchain swapchain;
+ bool double_swap;
struct pl_frame target;
bool have_frame;
pl_renderer renderer;
diff --git a/src/screen/screen.c b/src/screen/screen.c
index e76650f..e6f9970 100644
--- a/src/screen/screen.c
+++ b/src/screen/screen.c
@@ -30,11 +30,16 @@ static void should_close_callback(void *userdata)
static void resize_callback(void *userdata, s32 width, s32 height)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
+ bool fullscreen = scr->window->fullscreen;
if (scr->renderer) {
- scr->renderer->resize(scr->renderer, &width, &height);
+ // Checking if window->fullscreen changed here relies on the order of resize events.
+ // If it's possible for a different resize to be buffered before the resize
+ // of the fullscreen toggle, this may not work as expected.
+ scr->renderer->resize(scr->renderer, &width, &height, fullscreen != scr->last_fullscreen);
}
scr->width = width;
scr->height = height;
+ scr->last_fullscreen = fullscreen;
struct camu_screen_video *video;
al_array_foreach_ptr(scr->videos, i, video) {
camu_view_calculate(&video->view, scr->width, scr->height);
@@ -316,6 +321,7 @@ bool camu_screen_create_window(struct camu_screen *scr, const char *name)
}
scr->width = scr->window->width;
scr->height = scr->window->height;
+ scr->last_fullscreen = false;
#ifdef STELA_EVENT_BUFFER
nn_thread_create(&scr->thread, event_thread, scr);
#endif
@@ -357,7 +363,7 @@ static void add_buffer_internal(struct camu_screen *scr, struct camu_video_buffe
if (buf->view.mode != CAMU_VIEW_NONE) {
video.view = buf->view;
#if 0
- } else if (!al_array_is_empty(scr->videos)) {
+ } else if (scr->videos.count > 0) {
video.view = al_array_last(scr->videos).view;
video.view.width = fmt->width;
video.view.height = fmt->height;
@@ -400,15 +406,15 @@ static void run_queue_internal(struct camu_screen *scr)
al_array_foreach(scr->rem_queue, i, buf) {
remove_buffer_internal(scr, buf);
}
- scr->rem_queue.size = 0;
+ scr->rem_queue.count = 0;
// src->videos cannot be touched outside of the add/remove queue context.
// For example, reserving space inside of screen_add_buffer() instead
// of here would be very wrong.
- al_array_reserve(scr->videos, scr->videos.size + scr->add_queue.size);
+ al_array_reserve(scr->videos, scr->videos.count + scr->add_queue.count);
al_array_foreach(scr->add_queue, i, buf) {
add_buffer_internal(scr, buf);
}
- scr->add_queue.size = 0;
+ scr->add_queue.count = 0;
}
#endif
@@ -426,7 +432,7 @@ void camu_screen_add_buffer(struct camu_screen *scr, struct camu_video_buffer *b
al_array_foreach_rev(scr->rem_queue, i, rbuf) {
if (rbuf == buf) {
al_array_remove_at(scr->rem_queue, i);
- bool queue_empty = scr->add_queue.size + scr->rem_queue.size == 0;
+ bool queue_empty = scr->add_queue.count + scr->rem_queue.count == 0;
if (queue_empty) {
al_atomic_store(u8)(&scr->queued, 0, AL_ATOMIC_RELAXED);
}
@@ -457,7 +463,7 @@ void camu_screen_remove_buffer(struct camu_screen *scr, struct camu_video_buffer
al_array_foreach_rev(scr->add_queue, i, rbuf) {
if (rbuf == buf) {
al_array_remove_at(scr->add_queue, i);
- bool queue_empty = scr->add_queue.size + scr->rem_queue.size == 0;
+ bool queue_empty = scr->add_queue.count + scr->rem_queue.count == 0;
if (queue_empty) {
al_atomic_store(u8)(&scr->queued, 0, AL_ATOMIC_RELAXED);
}
diff --git a/src/screen/screen.h b/src/screen/screen.h
index d567521..c84cfc0 100644
--- a/src/screen/screen.h
+++ b/src/screen/screen.h
@@ -59,6 +59,7 @@ struct camu_screen {
bool force_render;
s32 width;
s32 height;
+ bool last_fullscreen;
u64 last_click_ts;
f64 last_mouse_y;
f64 last_mouse_x;
diff --git a/src/server/common.h b/src/server/common.h
index 9948c02..80afb9b 100644
--- a/src/server/common.h
+++ b/src/server/common.h
@@ -56,8 +56,8 @@ AL_UNUSED_FUNCTION_PUSH
static bool camu_is_url(str *s, u32 i)
{
- return al_str_cmp(s, al_str_c("https://"), i, 8) == 0
- || al_str_cmp(s, al_str_c("http://"), i, 7) == 0;
+ return al_str_cmp(s, &al_str_c("https://"), i, 8) == 0
+ || al_str_cmp(s, &al_str_c("http://"), i, 7) == 0;
}
AL_UNUSED_FUNCTION_POP
diff --git a/src/server/db.c b/src/server/db.c
index ce4c99e..4cc449e 100644
--- a/src/server/db.c
+++ b/src/server/db.c
@@ -4,28 +4,34 @@
#include "server.h"
-static bool open_user(struct camu_server *server, struct nn_dir_entry *dir)
+// This is still nothing.
+
+static void open_user(struct camu_server *server, struct nn_dir *camu_db, struct nn_dir_entry *dir)
{
+ str path;
+ nn_dir_entry_get_path(dir, camu_db, &path);
struct nn_file file;
- if (!nn_file_open(&file, &dir->path, 0)) {
- return false;
+ if (!nn_file_open(&file, &path, 0)) {
+ goto out;
}
str s;
nn_file_read_as_str(&file, &s);
json_error_t error;
- json_t *root = json_loadb(s.data, s.len, 0, &error);
+ json_t *root = json_loadb(s.data, s.length, 0, &error);
if (!root) {
al_log_error("server", "Failed to parse %.*s:%d:%d (%s).",
- AL_STR_PRINTF(&dir->path), error.line, error.column, error.text);
- return false;
+ al_str_fmt(&path), error.line, error.column, error.text);
+ al_str_free(&s);
+ goto out;
}
struct camu_user *user = al_alloc_object(struct camu_user);
al_str_from(&user->name, json_string_value(json_object_get(root, "username")));
- al_log_info("server", "Loaded user \"%.*s\"", AL_STR_PRINTF(&user->name));
+ al_log_info("server", "Loaded user \"%.*s\"", al_str_fmt(&user->name));
al_array_push(server->users, user);
json_decref(root);
al_str_free(&s);
- return true;
+out:
+ al_str_free(&path);
}
bool camu_db_open(struct camu_server *server, str *path)
@@ -36,20 +42,22 @@ bool camu_db_open(struct camu_server *server, str *path)
}
struct nn_dir_entry entry;
while (nn_dir_read(&camu_db, &entry)) {
- if (al_str_eq(&entry.name, al_str_c("users"))) {
+ if (al_str_eq(&al_str_cr(nn_dir_entry_get_os_name(&entry)), &al_str_c("users"))) {
struct nn_dir users;
- if (nn_dir_open(&users, &entry.path)) {
+ str users_path;
+ nn_dir_entry_get_path(&entry, &camu_db, &users_path);
+ if (nn_dir_open(&users, &users_path)) {
struct nn_dir_entry user;
while (nn_dir_read(&users, &user)) {
if (user.type == NNWT_ENTRY_FILE) {
- open_user(server, &user);
+ open_user(server, &camu_db, &user);
}
- nn_dir_entry_free(&user);
}
nn_dir_close(&users);
}
+ al_str_free(&users_path);
+ break;
}
- nn_dir_entry_free(&entry);
}
nn_dir_close(&camu_db);
return true;
diff --git a/src/server/server.c b/src/server/server.c
index e949ee1..bdc1f96 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -58,7 +58,7 @@ static void write_user_state(struct camu_server *server, struct camu_user *user,
{
(void)user;
#ifdef CAMU_HAVE_PORTAL
- nn_packet_write_u32(packet, server->bridge.searches.size);
+ nn_packet_write_u32(packet, server->bridge.searches.count);
struct camu_search *search;
al_array_foreach(server->bridge.searches, i, search) {
nn_packet_write_s32(packet, search->id);
@@ -99,7 +99,7 @@ static bool identify_callback(void *userdata, struct nn_rpc_connection *conn,
}
client->user = user;
al_array_push(server->clients, client);
- al_log_info("server", "User \"%.*s\" logged in.", AL_STR_PRINTF(&user->name));
+ al_log_info("server", "User \"%.*s\" logged in.", al_str_fmt(&user->name));
write_user_state(server, user, rpacket);
break;
}
@@ -111,7 +111,7 @@ static bool identify_callback(void *userdata, struct nn_rpc_connection *conn,
al_str_clone(&sink->name, &name);
sink->server = server;
al_array_push(server->sinks, sink);
- handle_toggle_sink(server, al_str_c("default"), sink, true);
+ handle_toggle_sink(server, &al_str_c("default"), sink, true);
al_log_info("server", "New sink.");
break;
}
@@ -187,7 +187,7 @@ static void process_pending(struct camu_resource *resource)
array(struct lia_list_entry *) pending;
// resource->pending may be edited during a list_pump() call.
al_array_clone(pending, resource->pending);
- resource->pending.size = 0;
+ resource->pending.count = 0;
struct lia_list_entry *entry;
al_array_foreach(pending, i, entry) {
lia_list_pump(entry->list);
@@ -270,12 +270,12 @@ static void client_portal_callback(void *userdata0, void *userdata1, struct camu
case CAMU_CLIENT_GET_PAGE: {
struct camu_result_page *page = result->page;
nn_packet_write_u32(packet, page->num);
- nn_packet_write_u32(packet, page->posts.size);
+ nn_packet_write_u32(packet, page->posts.count);
struct camu_post *post;
al_array_foreach_ptr(page->posts, i, post) {
nn_packet_write_post(packet, post);
}
- nn_packet_write_u32(packet, page->list.size);
+ nn_packet_write_u32(packet, page->list.count);
str *unique_id;
al_array_foreach_ptr(page->list, i, unique_id) {
nn_packet_write_str(packet, unique_id);
@@ -346,14 +346,14 @@ out:
static struct cch_entry *entry_from_post(struct camu_server *server, struct camu_post *post, u32 index)
{
struct cch_entry *entry = NULL;
- if (index <= post->media.size) {
+ if (index <= post->media.count) {
struct camu_post_media *media = &al_array_at(post->media, index);
if (!al_str_is_empty(&media->url)) {
entry = cch_handler_http_create(&media->url, server->loop);
}
}
if (!entry) {
- al_log_warn("server", "Failed to load resource %.*s %u.", AL_STR_PRINTF(&post->unique_id), index);
+ al_log_warn("server", "Failed to load resource %.*s %u.", al_str_fmt(&post->unique_id), index);
return NULL;
}
entry->handler->maybe_spawn_worker(entry->handler, 0);
@@ -371,7 +371,7 @@ static void simple_search_portal_callback(void *userdata0, void *userdata1, stru
return;
}
case CAMU_CLIENT_GET_PAGE: {
- if (!result->page || al_array_is_empty(result->page->list)) break;
+ if (!result->page || !result->page->list.count) break;
struct camu_post *post = camu_post_cache_get(&server->cache, &al_array_at(result->page->list, 0));
if (!post) break;
struct cch_entry *entry = entry_from_post(server, post, 0);
@@ -436,9 +436,10 @@ static void handle_add_command(struct camu_server *server, struct lia_list *list
str url;
nn_packet_read_str(packet, &url);
u32 track = 0;
- if (url.len > 7) {
- s64 index = al_str_to_long(al_str_substr(&url, 7, url.len), 10);
- if (index > 0 && index <= entry->chapters.size)
+ if (url.length > 7) {
+ bool error;
+ s64 index = al_str_to_long(&al_str_substr(&url, 7, url.length), 10, &error);
+ if (!error && index <= entry->chapters.count)
track = (u32)index - 1;
}
entry->chapter = &al_array_at(entry->chapters, track);
@@ -479,12 +480,12 @@ static void handle_add_command(struct camu_server *server, struct lia_list *list
resource->load = LIANA_ENTRY_PREPARING;
str query;
if (al_str_at(&search, 0) == ';') { // search.
- al_str_clone(&query, al_str_substr(&search, 1, search.len));
+ al_str_clone(&query, &al_str_substr(&search, 1, search.length));
} else {
al_str_from(&query, "link:");
al_str_cat(&query, &search);
}
- camu_portal_create_search(&server->bridge, al_str_c("youtube"), &query, simple_search_portal_callback, portal);
+ camu_portal_create_search(&server->bridge, &al_str_c("youtube"), &query, simple_search_portal_callback, portal);
al_str_free(&query);
break;
}
@@ -615,7 +616,7 @@ static void connection_closed_callback(void *userdata, struct nn_rpc_connection
struct camu_server_client *client;
al_array_foreach(server->clients, i, client) {
if (client->conn == conn) {
- al_log_info("server", "User \"%.*s\" logged out.", AL_STR_PRINTF(&client->user->name));
+ al_log_info("server", "User \"%.*s\" logged out.", al_str_fmt(&client->user->name));
cleanup_client(client);
al_array_remove_at(server->clients, i);
break;
@@ -656,7 +657,7 @@ static bool multiplex_callback(void *userdata, u8 id, struct nn_packet_stream *s
void camu_server_init(struct camu_server *server, struct nn_event_loop *loop)
{
server->loop = loop;
- server->addr = al_str_zero();
+ server->addr = al_str_null();
al_array_init(server->nodes);
al_array_init(server->clients);
al_array_init(server->sinks);
@@ -664,7 +665,7 @@ void camu_server_init(struct camu_server *server, struct nn_event_loop *loop)
al_array_init(server->lists);
struct lia_list *list = al_alloc_object(struct lia_list);
- lia_list_init(list, al_str_c("default"));
+ lia_list_init(list, &al_str_c("default"));
list->callback = list_callback;
list->userdata = server;
al_array_push(server->lists, list);
diff --git a/src/sink/desktop.c b/src/sink/desktop.c
index cb5e7c6..6fe6001 100644
--- a/src/sink/desktop.c
+++ b/src/sink/desktop.c
@@ -17,12 +17,20 @@
static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque)
{
struct camu_desktop *c = (struct camu_desktop *)userdata;
+
+ if (op == CAMU_SINK_MOCK_CLOSE) {
+ c->should_quit = 1;
+ camu_screen_wake(&c->scr);
+ return CAMU_SINK_OK;
+ }
+
if (!camu_default_sink_callback(&c->scr, &c->mixer, op, type, opaque)) {
camu_sink_close(&c->sink);
if (c->exit_callback) {
c->exit_callback(c->userdata, c);
}
}
+
return CAMU_SINK_OK;
}
@@ -108,7 +116,7 @@ bool camu_desktop_connect(struct camu_desktop *c, u8 type, struct nn_event_loop
al_str_from(&c->sink.default_list, "default");
c->sink.callback = sink_callback;
c->sink.userdata = c;
- return camu_sink_connect(&c->sink, type, addr, port, al_str_c("desktop"));
+ return camu_sink_connect(&c->sink, type, addr, port, &al_str_c("desktop"));
}
bool camu_desktop_tick(struct camu_desktop *c)
diff --git a/src/util/color_palette.c b/src/util/color_palette.c
index bb4da03..886ba8e 100644
--- a/src/util/color_palette.c
+++ b/src/util/color_palette.c
@@ -40,24 +40,32 @@ bool camu_color_palette_init(str *path)
nn_file_read_as_str(&file, &s);
nn_file_close(&file);
json_error_t error;
- json_t *root = json_loadb(s.data, s.len, 0, &error);
+ json_t *root = json_loadb(s.data, s.length, 0, &error);
if (!root) return false;
json_t *special = json_object_get(root, "special");
json_t *colors = json_object_get(root, "colors");
if (!special || !colors) return false;
json_t *object;
+ bool to_long_error;
const char *color;
+ u32 value;
for (u32 i = 0; i < ARRAY_SIZE(special_colors); i++) {
object = json_object_get(special, special_colors[i]);
if (!object) return false;
color = json_string_value(object);
- global_color_palette.colors[i] = (u32)al_str_to_long(al_str_w((char *)color, 1, 6), 16);
+ value = (u32)al_str_to_long(&al_str_w((char *)color, 1, 6), 16, &to_long_error);
+ if (!to_long_error) {
+ global_color_palette.colors[i] = value;
+ }
}
for (u32 i = 0; i < ARRAY_SIZE(normal_colors); i++) {
object = json_object_get(colors, normal_colors[i]);
if (!object) return false;
color = json_string_value(object);
- global_color_palette.colors[i + 2] = (u32)al_str_to_long(al_str_w((char *)color, 1, 6), 16);
+ value = (u32)al_str_to_long(&al_str_w((char *)color, 1, 6), 16, &to_long_error);
+ if (!to_long_error) {
+ global_color_palette.colors[i + 2] = value;
+ }
}
return true;
}
diff --git a/src/util/queue.h b/src/util/queue.h
index bd91342..d103831 100644
--- a/src/util/queue.h
+++ b/src/util/queue.h
@@ -11,59 +11,60 @@
#define camu_queue_lock(q) \
AL_MACRO_WRAP \
-({ \
+{ \
nn_mutex_lock(&(q).mutex); \
-})
+} AL_MACRO_END
#define camu_queue_unlock(q) \
AL_MACRO_WRAP \
-({ \
+{ \
nn_mutex_unlock(&(q).mutex); \
-})
+} AL_MACRO_END
-#define camu_queue_size(q, r) \
+#define camu_queue_count(q, r) \
AL_MACRO_WRAP \
-({ \
+{ \
nn_mutex_lock(&(q).mutex); \
- r = (q).a.size; \
+ r = (q).a.count; \
nn_mutex_unlock(&(q).mutex); \
-})
+} AL_MACRO_END
#define camu_queue_init(q) \
AL_MACRO_WRAP \
-({ \
+{ \
al_array_init((q).a); \
nn_mutex_init(&(q).mutex); \
-})
+} AL_MACRO_END
#define camu_queue_push(q, item) \
AL_MACRO_WRAP \
-({ \
+{ \
nn_mutex_lock(&(q).mutex); \
al_array_push((q).a, item); \
nn_mutex_unlock(&(q).mutex); \
-})
+} AL_MACRO_END
#define camu_queue_pop(q, r) \
AL_MACRO_WRAP \
-({ \
+{ \
nn_mutex_lock(&(q).mutex); \
al_array_pop_at((q).a, 0, r); \
nn_mutex_unlock(&(q).mutex); \
-})
+} AL_MACRO_END
#define camu_queue_try_pop(q, s, r) \
-AL_MACRO_WRAP \
-({ \
- nn_mutex_lock(&(q).mutex); \
- if ((s = (q).a.size) > 0) \
+AL_MACRO_WRAP \
+{ \
+ nn_mutex_lock(&(q).mutex); \
+ if ((s = (q).a.count) > 0) { \
al_array_pop_at((q).a, 0, r); \
- nn_mutex_unlock(&(q).mutex); \
-})
+ } \
+ nn_mutex_unlock(&(q).mutex); \
+} AL_MACRO_END
#define camu_queue_free(q) \
AL_MACRO_WRAP \
-({ \
+{ \
nn_mutex_destroy(&(q).mutex); \
al_array_free((q).a); \
-})
+} AL_MACRO_END