summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buffer/audio.c6
-rw-r--r--src/buffer/frame_queue.h2
-rw-r--r--src/buffer/video.c4
-rw-r--r--src/buffer/video.h2
-rw-r--r--src/buffer/volume.h12
-rw-r--r--src/cache/backings/file.c4
-rw-r--r--src/cache/backings/file_mapped.c4
-rw-r--r--src/cache/backings/memory.c4
-rw-r--r--src/cache/range.h2
-rw-r--r--src/fruits/cmsrv/ui.c8
-rw-r--r--src/fruits/cmsrv/ui.h2
-rw-r--r--src/liana/handlers.c2
-rw-r--r--src/liana/list.c13
-rw-r--r--src/liana/server.c8
-rw-r--r--src/liana/server.h1
-rw-r--r--src/liana/vcr.c2
-rw-r--r--src/libclient/client.c2
-rw-r--r--src/libsink/sink.c66
-rw-r--r--src/mixer/audio_miniaudio.c2
-rw-r--r--src/mixer/audio_miniaudio.h1
-rw-r--r--src/mixer/mixer.c2
-rw-r--r--src/render/queue_libplacebo.c61
-rw-r--r--src/render/queue_libplacebo.h10
-rw-r--r--src/render/renderer_libplacebo.c3
-rw-r--r--src/render/renderer_libplacebo.h3
-rw-r--r--src/server/server.c2
-rw-r--r--src/util/color_palette.c4
27 files changed, 130 insertions, 102 deletions
diff --git a/src/buffer/audio.c b/src/buffer/audio.c
index 5058154..ac698bb 100644
--- a/src/buffer/audio.c
+++ b/src/buffer/audio.c
@@ -310,7 +310,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re
if (UNLIKELY(!buf->ignore_desync && buf->pause == PAUSE_PAUSED)) {
if (pts > 0.0) { // Skip.
ret = camu_audio_format_sec_to_bytes(&buf->fmt.req, pts);
- ret = AL_MIN(ret, have);
+ ret = MIN(ret, have);
al_log_info("audio_buffer", "Skipping %fs of audio (%zu bytes).", pts, ret);
ret = al_ring_buffer_discard(&buf->rb, ret);
have -= ret;
@@ -319,7 +319,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re
} else if (pts < 0.0) { // Delay.
pts = -pts;
ret = camu_audio_format_sec_to_bytes(&buf->fmt.req, pts);
- ret = AL_MIN(ret, req);
+ ret = MIN(ret, req);
al_log_info("audio_buffer", "Delaying audio by %fs (%zu bytes).", pts, ret);
al_memset(data, 0, ret);
data += ret;
@@ -369,7 +369,7 @@ size_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, size_t re
// If flow = SIGNALED, we are waiting to be removed or reset.
}
// The amount of available data could've increased in the flow = FLUSHED case.
- req = AL_MIN(req, have);
+ req = MIN(req, have);
}
if (req > 0) {
diff --git a/src/buffer/frame_queue.h b/src/buffer/frame_queue.h
index f670ded..e3044f1 100644
--- a/src/buffer/frame_queue.h
+++ b/src/buffer/frame_queue.h
@@ -19,7 +19,7 @@ struct camu_frame_queue {
void (*push)(struct camu_frame_queue *, struct camu_codec_frame *, f64);
#ifdef CAMU_HAVE_FFMPEG
void (*push_av_frame)(struct camu_frame_queue *, AVFrame *, f64);
- void (*configure_subtitles)(struct camu_frame_queue *, s32, s32, AVCodecParameters *);
+ bool (*configure_subtitles)(struct camu_frame_queue *, s32, s32, AVCodecParameters *);
void (*push_subtitle)(struct camu_frame_queue *, AVPacket *);
#endif
void (*flush)(struct camu_frame_queue *);
diff --git a/src/buffer/video.c b/src/buffer/video.c
index b528141..30e19c7 100644
--- a/src/buffer/video.c
+++ b/src/buffer/video.c
@@ -187,10 +187,10 @@ void camu_video_buffer_push(struct camu_video_buffer *buf, struct camu_codec_fra
}
#ifdef CAMU_HAVE_FFMPEG
-void camu_video_buffer_configure_subtitles(struct camu_video_buffer *buf, AVCodecParameters *codecpar)
+bool camu_video_buffer_configure_subtitles(struct camu_video_buffer *buf, AVCodecParameters *codecpar)
{
struct camu_video_format *fmt = &buf->stream->video.fmt;
- buf->queue->configure_subtitles(buf->queue, fmt->width, fmt->height, codecpar);
+ return buf->queue->configure_subtitles(buf->queue, fmt->width, fmt->height, codecpar);
}
void camu_video_buffer_push_subtitle(struct camu_video_buffer *buf, AVPacket *pkt)
diff --git a/src/buffer/video.h b/src/buffer/video.h
index fd7ec9f..3953fc1 100644
--- a/src/buffer/video.h
+++ b/src/buffer/video.h
@@ -48,7 +48,7 @@ void camu_video_buffer_set_latency(struct camu_video_buffer *buf, s32 frames);
bool camu_video_buffer_is_single_frame(struct camu_video_buffer *buf);
void camu_video_buffer_push(struct camu_video_buffer *buf, struct camu_codec_frame *frame);
#ifdef CAMU_HAVE_FFMPEG
-void camu_video_buffer_configure_subtitles(struct camu_video_buffer *buf, AVCodecParameters *codecpar);
+bool camu_video_buffer_configure_subtitles(struct camu_video_buffer *buf, AVCodecParameters *codecpar);
void camu_video_buffer_push_subtitle(struct camu_video_buffer *buf, AVPacket *pkt);
#endif
void camu_video_buffer_flush(struct camu_video_buffer *buf);
diff --git a/src/buffer/volume.h b/src/buffer/volume.h
index d39affc..6a8cf0a 100644
--- a/src/buffer/volume.h
+++ b/src/buffer/volume.h
@@ -6,11 +6,11 @@ static inline f32 apply_volume_f32(f32 *data, size_t sample_count, s32 channel_c
{
for (u32 i = 0; i < sample_count; i++) {
if (step != 0.f && i % channel_count == 0) {
- volume = AL_CLAMP(volume + step, 0.f, user);
+ volume = CLAMP(volume + step, 0.f, user);
}
f64 sample = (f64)data[i];
sample *= volume;
- data[i] = (f32)AL_CLAMP(sample, -1.0, 1.0);
+ data[i] = (f32)CLAMP(sample, -1.0, 1.0);
}
return volume;
}
@@ -19,11 +19,11 @@ static inline f32 apply_volume_s32(s32 *data, size_t sample_count, s32 channel_c
{
for (u32 i = 0; i < sample_count; i++) {
if (step != 0.f && i % channel_count == 0) {
- volume = AL_CLAMP(volume + step, 0.f, user);
+ volume = CLAMP(volume + step, 0.f, user);
}
f64 sample = (f64)data[i];
sample *= volume;
- data[i] = (s32)AL_CLAMP(sample, INT32_MIN, INT32_MAX);
+ data[i] = (s32)CLAMP(sample, (f64)INT32_MIN, (f64)INT32_MAX);
}
return volume;
}
@@ -32,11 +32,11 @@ static inline f32 apply_volume_s16(s16 *data, size_t sample_count, s32 channel_c
{
for (u32 i = 0; i < sample_count; i++) {
if (step != 0.f && i % channel_count == 0) {
- volume = AL_CLAMP(volume + step, 0.f, user);
+ volume = CLAMP(volume + step, 0.f, user);
}
f64 sample = (f64)data[i];
sample *= volume;
- data[i] = (s16)AL_CLAMP(sample, INT16_MIN, INT16_MAX);
+ data[i] = (s16)CLAMP(sample, (f64)INT16_MIN, (f64)INT16_MAX);
}
return volume;
}
diff --git a/src/cache/backings/file.c b/src/cache/backings/file.c
index 153b1e4..a09d535 100644
--- a/src/cache/backings/file.c
+++ b/src/cache/backings/file.c
@@ -18,7 +18,7 @@ static void file_backing_write(struct cch_backing *backing, u8 *buf, off_t index
al_assert(file->u.pointer == index);
}
if (file->size >= 0 && index + ((off_t)*size) >= file->size) {
- *size = AL_MAX(file->size - index, 0);
+ *size = MAX(file->size - index, 0L);
}
aki_file_write(&file->file, buf, *size);
file->u.pointer += *size;
@@ -35,7 +35,7 @@ static void file_backing_read(struct cch_backing *backing, u8 *buf, off_t index,
al_assert(file->u.pointer == index);
}
if (file->size >= 0 && index + ((off_t)*size) >= file->size) {
- *size = AL_MAX(file->size - index, 0);
+ *size = MAX(file->size - index, 0L);
}
aki_file_read(&file->file, buf, *size);
file->u.pointer += *size;
diff --git a/src/cache/backings/file_mapped.c b/src/cache/backings/file_mapped.c
index 6c6fc94..22f9ae5 100644
--- a/src/cache/backings/file_mapped.c
+++ b/src/cache/backings/file_mapped.c
@@ -14,7 +14,7 @@ static void file_backing_write(struct cch_backing *backing, u8 *buf, off_t index
struct cch_backing_file *file = (struct cch_backing_file *)backing;
aki_mutex_lock(&file->mutex);
if (file->size >= 0 && index + (off_t)*size >= file->size) {
- *size = AL_MAX(file->size - index, 0);
+ *size = MAX(file->size - index, 0L);
}
al_memcpy(file->u.map + index, buf, *size);
cch_backing_fill_range(&file->backing, index, *size);
@@ -26,7 +26,7 @@ static u8 *file_backing_get_ptr(struct cch_backing *backing, off_t index, size_t
struct cch_backing_file *file = (struct cch_backing_file *)backing;
aki_mutex_lock(&file->mutex);
if (file->size >= 0 && index + (off_t)*size >= file->size) {
- *size = AL_MAX(file->size - index, 0);
+ *size = MAX(file->size - index, 0L);
}
return (u8 *)(file->u.map + index);
}
diff --git a/src/cache/backings/memory.c b/src/cache/backings/memory.c
index 1dca8f9..5db2063 100644
--- a/src/cache/backings/memory.c
+++ b/src/cache/backings/memory.c
@@ -21,7 +21,7 @@ static void memory_backing_write(struct cch_backing *backing, u8 *buf, off_t ind
struct cch_backing_memory *mem = (struct cch_backing_memory *)backing;
aki_mutex_lock(&mem->mutex);
if (mem->size >= 0 && index + (off_t)*size >= mem->size) {
- *size = AL_MAX(mem->size - index, 0);
+ *size = MAX(mem->size - index, 0L);
}
ensure_alloced(mem, index + *size);
al_memcpy(mem->data + index, buf, *size);
@@ -34,7 +34,7 @@ static u8 *memory_backing_get_ptr(struct cch_backing *backing, off_t index, size
struct cch_backing_memory *mem = (struct cch_backing_memory *)backing;
aki_mutex_lock(&mem->mutex);
if (mem->size >= 0 && index + (off_t)*size >= mem->size) {
- *size = AL_MAX(mem->size - index, 0);
+ *size = MAX(mem->size - index, 0L);
}
return (u8 *)(mem->data + index);
}
diff --git a/src/cache/range.h b/src/cache/range.h
index 598b655..603117e 100644
--- a/src/cache/range.h
+++ b/src/cache/range.h
@@ -13,7 +13,7 @@ static void cch_backing_fill_range(struct cch_backing *backing, off_t index, off
struct cch_range *range;
al_array_foreach_ptr(backing->available, i, range) {
if (index >= range->start && index <= range->end) {
- range->end = AL_MAX(index + size, range->end);
+ range->end = MAX(index + size, range->end);
return;
}
}
diff --git a/src/fruits/cmsrv/ui.c b/src/fruits/cmsrv/ui.c
index e10db5e..e1e686f 100644
--- a/src/fruits/cmsrv/ui.c
+++ b/src/fruits/cmsrv/ui.c
@@ -109,7 +109,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 = AL_MIN(w->len, maxwidth);
+ u32 end = MIN(w->len, maxwidth);
for (u32 i = 0; i < end; i++) {
ncplane_putwc(n, al_wstr_at(w, i));
}
@@ -127,10 +127,10 @@ 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;
- ncplane_putnstr_yx(n, i, 0, AL_MIN(max_width, list->name.len), &al_str_at(&list->name, 0));
- s32 index = AL_MAX(list->current - (entries_per_list / 2), 0);
+ ncplane_putnstr_yx(n, i, 0, MIN(max_width, list->name.len), &al_str_at(&list->name, 0));
+ s32 index = MAX(list->current - (entries_per_list / 2), 0);
s32 size = (s32)list->entries.size;
- s32 end = AL_MIN(index + entries_per_list, size);
+ 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);
u32 y = i + (j - index) + 1;
diff --git a/src/fruits/cmsrv/ui.h b/src/fruits/cmsrv/ui.h
index 45fdd85..ebf7c1a 100644
--- a/src/fruits/cmsrv/ui.h
+++ b/src/fruits/cmsrv/ui.h
@@ -1,6 +1,6 @@
-#include <notcurses/notcurses.h>
#include <al/types.h>
#include <al/array.h>
+#include <notcurses/notcurses.h>
#include "../../server/server.h"
diff --git a/src/liana/handlers.c b/src/liana/handlers.c
index e67250a..936f801 100644
--- a/src/liana/handlers.c
+++ b/src/liana/handlers.c
@@ -28,7 +28,7 @@ struct lia_handler_entry liana_handlers[] = {
struct lia_handler_entry *lia_handler_by_name(str *name)
{
- for (u32 i = 0; i < AL_ARRAY_SIZE(liana_handlers); i++) {
+ for (u32 i = 0; i < ARRAY_SIZE(liana_handlers); i++) {
if (al_str_eq(liana_handlers[i].name, name)) {
return &liana_handlers[i];
}
diff --git a/src/liana/list.c b/src/liana/list.c
index 09720b6..94e3fa2 100644
--- a/src/liana/list.c
+++ b/src/liana/list.c
@@ -12,7 +12,7 @@ static void buffer_ahead(struct lia_list *list)
s32 size = (s32)list->entries.size;
if (list->queued >= 0 && list->queued + 1 < size) {
s32 ahead = list->queued + 1;
- for (s32 i = ahead; i < AL_MIN(ahead + LIANA_BUFFER_AHEAD, size); i++) {
+ for (s32 i = ahead; i < MIN(ahead + LIANA_BUFFER_AHEAD, size); i++) {
struct lia_list_entry *buffered = al_array_at(list->entries, i);
struct lia_list_sink *sink;
al_array_foreach(list->sinks, i, sink) {
@@ -151,7 +151,7 @@ static bool handle_add(struct lia_list *list, struct lia_list_entry *entry)
sink->set = list->current;
sink->callback(sink->userdata, LIANA_SINK_SET, entry, list->current, &time);
}
- al_log_info("list", "Now playing: %ls.\n", AL_WSTR_PRINTF(&entry->name));
+ al_log_info("list", "Now playing: %ls.", AL_WSTR_PRINTF(&entry->name));
} else {
/*
if (list->queued == -1) {
@@ -270,6 +270,7 @@ static bool handle_skipto(struct lia_list *list, s32 sequence, s32 index)
bool ended = assume_ended(current, now);
bool target_ended = assume_ended(target, now);
+ al_log_info("list", "ended: %d, target_ended: %d", ended, target_ended);
if (ended || current->paused_at == LIANA_TIMESTAMP_INVALID) {
if (!ended) {
current->paused_at = at;
@@ -309,7 +310,7 @@ static bool handle_skipto(struct lia_list *list, s32 sequence, s32 index)
sink->callback(sink->userdata, LIANA_SINK_SET, target, index, &time);
}
- al_log_info("list", "Now playing: %ls.\n", AL_WSTR_PRINTF(&target->name));
+ al_log_info("list", "Now playing: %ls.", AL_WSTR_PRINTF(&target->name));
return true;
}
@@ -403,7 +404,7 @@ static void handle_end(struct lia_list *list, s32 sequence)
al_array_foreach(list->sinks, i, sink) {
sink->queued = -1;
}
- al_log_info("list", "Now playing: %ls.\n", AL_WSTR_PRINTF(&current->name));
+ al_log_info("list", "Now playing: %ls.", AL_WSTR_PRINTF(&current->name));
} else if (next < size) {
struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
cmd->op = SKIPTO;
@@ -426,7 +427,7 @@ static void handle_reverse(struct lia_list *list)
for (u32 i = 0; i < size; i++) {
u32 tail = size - (i + 1);
if (tail <= i) break;
- AL_SWAP(al_array_at(list->entries, i), al_array_at(list->entries, tail), struct lia_list_entry *);
+ SWAP(al_array_at(list->entries, i), al_array_at(list->entries, tail));
}
unset_all(list, previous);
}
@@ -445,7 +446,7 @@ static void handle_shuffle(struct lia_list *list)
if (size == 0) return;
for (u32 i = 0; i < size - 1; i++) {
u32 j = i + al_rand() / (AL_RAND_MAX / (size - i) + 1);
- AL_SWAP(al_array_at(list->entries, i), al_array_at(list->entries, j), struct lia_list_entry *);
+ SWAP(al_array_at(list->entries, i), al_array_at(list->entries, j));
}
unset_all(list, previous);
}
diff --git a/src/liana/server.c b/src/liana/server.c
index ccca0fd..93ee643 100644
--- a/src/liana/server.c
+++ b/src/liana/server.c
@@ -3,11 +3,11 @@
#include "server.h"
#include "handler.h"
#include "handlers.h"
-#include "list.h"
bool lia_server_init(struct lia_server *server, struct aki_event_loop *loop)
{
server->loop = loop;
+ server->increment = 1;
al_array_init(server->nodes);
al_array_init(server->zombies);
return true;
@@ -163,7 +163,8 @@ static void signal_callback(void *userdata)
return;
}
if (!conn->errored) {
- conn->id = al_inc_u16();
+ conn->id = server->increment;
+ server->increment = al_u16_inc_wrap(server->increment);
aki_packet_pool_init(&conn->pool, 96, server->loop, packet_pool_callback, conn);
al_array_push(node->connections, conn);
handle_connection(conn, packet);
@@ -281,7 +282,8 @@ void lia_server_add_socket(struct lia_server *server, struct aki_socket *sock)
struct lia_node *lia_server_create_node(struct lia_server *server, struct cch_entry *entry)
{
struct lia_node *node = al_alloc_object(struct lia_node);
- node->id = al_inc_u16();
+ node->id = server->increment;
+ server->increment = al_u16_inc_wrap(server->increment);
node->entry = entry;
al_array_init(node->connections);
node->server = server;
diff --git a/src/liana/server.h b/src/liana/server.h
index 2ed7c12..11fdfa9 100644
--- a/src/liana/server.h
+++ b/src/liana/server.h
@@ -44,6 +44,7 @@ struct lia_node {
struct lia_server {
struct aki_event_loop *loop;
+ u16 increment;
array(struct lia_node *) nodes;
array(struct aki_packet_stream *) zombies;
};
diff --git a/src/liana/vcr.c b/src/liana/vcr.c
index c9e7975..571fe4e 100644
--- a/src/liana/vcr.c
+++ b/src/liana/vcr.c
@@ -3,7 +3,7 @@
#include "vcr.h"
#include "handler.h"
-#define VCR_BUFFER_BUFFERED MB(24)
+#define VCR_BUFFER_BUFFERED MB(12)
enum {
VCR_EXPAND_UNTOUCHED = 0,
diff --git a/src/libclient/client.c b/src/libclient/client.c
index d7a2325..c43a7dd 100644
--- a/src/libclient/client.c
+++ b/src/libclient/client.c
@@ -61,7 +61,7 @@ bool camu_client_login(struct camu_client *client, struct aki_event_loop *loop,
al_str_clone(&client->username, username);
client->conn = NULL;
aki_rpc_init(&client->client, client->loop, connection_callback, connection_closed_callback, client);
- for (u32 i = 0; i < AL_ARRAY_SIZE(commands); i++) {
+ for (u32 i = 0; i < ARRAY_SIZE(commands); i++) {
commands[i].userdata = client;
aki_rpc_add_command(&client->client, &commands[i]);
}
diff --git a/src/libsink/sink.c b/src/libsink/sink.c
index 2caa973..80414fd 100644
--- a/src/libsink/sink.c
+++ b/src/libsink/sink.c
@@ -43,11 +43,11 @@ enum {
#define BUFFER_EMPTY(buf) ((buf)->state == BUFFER_INIT || (buf)->state == BUFFER_QUEUED)
#ifdef CAMU_SINK_NO_VIDEO
-#define VIDEO_READY_OR_EMPTY(entry) true
+#define VIDEO_ADDED_OR_EMPTY(entry) true
#else
-#define VIDEO_READY_OR_EMPTY(entry) (BUFFER_EMPTY(&(entry)->video) || (entry)->video.state == BUFFER_ADDED)
+#define VIDEO_ADDED_OR_EMPTY(entry) (BUFFER_EMPTY(&(entry)->video) || (entry)->video.state == BUFFER_ADDED)
#endif
-#define AUDIO_READY_OR_EMPTY(entry) (BUFFER_EMPTY(&(entry)->audio) || (entry)->audio.state == BUFFER_ADDED)
+#define AUDIO_ADDED_OR_EMPTY(entry) (BUFFER_EMPTY(&(entry)->audio) || (entry)->audio.state == BUFFER_ADDED)
#ifdef CAMU_SINK_NO_VIDEO
#define VIDEO_REMOVED_OR_EMPTY(entry) true
@@ -354,7 +354,7 @@ void add_audio_if_set_and_buffered(struct camu_sink_entry *entry)
// It's possible for this entry's video buffer to have been added and removed by EOF
// before this point. This needs to be a consideration for keeping sync.
// Same but reversed in add_video_if_set_and_buffered().
- if (VIDEO_READY_OR_EMPTY(entry)) {
+ if (VIDEO_ADDED_OR_EMPTY(entry)) {
maybe_remove_previous(entry->sink);
}
#ifndef CAMU_SINK_LOCAL
@@ -376,7 +376,7 @@ void add_video_if_set_and_buffered(struct camu_sink_entry *entry)
} else if (entry->video.state == BUFFER_SET_OR_BUFFERED) {
entry->video.state = BUFFER_ADDED;
entry->sink->callback(entry->sink->userdata, CAMU_SINK_ADD_BUFFER, CAMU_SINK_VIDEO, &entry->video.buf);
- if (AUDIO_READY_OR_EMPTY(entry)) {
+ if (AUDIO_ADDED_OR_EMPTY(entry)) {
maybe_remove_previous(entry->sink);
}
bool single_frame = camu_video_buffer_is_single_frame(&entry->video.buf);
@@ -388,28 +388,18 @@ void add_video_if_set_and_buffered(struct camu_sink_entry *entry)
}
#endif
-static void switch_to(struct camu_sink *sink, struct camu_sink_entry *entry)
-{
- if (sink->current) {
- if (camu_clock_is_ended(&entry->clock)) {
- remove_entry_buffers(sink, sink->current);
- } else {
- maybe_add_to_previous(sink, sink->current, entry);
- }
- }
- set_or_queue_entry(entry);
- sink->current = entry;
-}
-
static bool end_entry_and_advance_queue(struct camu_sink *sink, struct camu_sink_entry *entry)
{
al_log_info("sink", "Entry ended.");
camu_clock_end(&entry->clock);
if (sink->target) {
- switch_to(sink, sink->target);
+ set_or_queue_entry(sink->target);
+ sink->current = sink->target;
sink->target = NULL;
- }
- if (sink->queued) {
+ return true;
+ } else if (sink->queued) {
+ // TODO: What is the right behavior if sink->queued
+ // and sink->target are both set.
set_or_queue_entry(sink->queued);
sink->current = sink->queued;
sink->queued = NULL;
@@ -519,6 +509,19 @@ static void video_buffer_callback(void *userdata, u8 op)
}
#endif
+static void switch_to(struct camu_sink *sink, struct camu_sink_entry *entry)
+{
+ if (sink->current) {
+ if (camu_clock_is_ended(&entry->clock)) {
+ remove_entry_buffers(sink, sink->current);
+ } else {
+ maybe_add_to_previous(sink, sink->current, entry);
+ }
+ }
+ set_or_queue_entry(entry);
+ sink->current = entry;
+}
+
static void evaluate_latency(struct camu_sink *sink, struct camu_sink_entry *entry)
{
#ifdef CAMU_SINK_LOCAL
@@ -568,7 +571,7 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
} else {
entry->audio.state = BUFFER_CONFIGURED;
}
- if (VIDEO_READY_OR_EMPTY(entry)) {
+ if (VIDEO_ADDED_OR_EMPTY(entry)) {
evaluate_latency(sink, entry);
}
aki_mutex_unlock(&sink->mutex);
@@ -585,14 +588,16 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
} else {
entry->video.state = BUFFER_CONFIGURED;
}
- if (AUDIO_READY_OR_EMPTY(entry)) {
+ if (AUDIO_ADDED_OR_EMPTY(entry)) {
evaluate_latency(sink, entry);
}
aki_mutex_unlock(&sink->mutex);
break;
case CAMU_STREAM_SUBTITLE:
#ifdef CAMU_HAVE_FFMPEG
- camu_video_buffer_configure_subtitles(&entry->video.buf, stream->av.stream->codecpar);
+ if (!camu_video_buffer_configure_subtitles(&entry->video.buf, stream->av.stream->codecpar)) {
+ // TODO
+ }
#endif
break;
case CAMU_STREAM_ATTACHMENT: {
@@ -943,10 +948,9 @@ static bool set_command_callback(void *userdata, struct aki_rpc_connection *conn
al_log_warn("sink", "Ignoring target on NONE.");
sink->target = NULL;
}
- if (entry == sink->current) {
- break;
+ if (entry != sink->current) {
+ switch_to(sink, entry);
}
- switch_to(sink, entry);
break;
case LIANA_PAUSE_RESUME:
if (sink->target) {
@@ -954,11 +958,11 @@ static bool set_command_callback(void *userdata, struct aki_rpc_connection *conn
sink->target = NULL;
}
camu_clock_resume(&entry->clock, at);
- if (entry == sink->current) {
+ if (entry != sink->current) {
+ switch_to(sink, entry);
+ } else {
camu_audio_buffer_unpause(&entry->audio.buf);
- break;
}
- switch_to(sink, entry);
break;
case LIANA_PAUSE_PAUSE: {
// For target to be set that must mean that current is set and armed to pause.
@@ -1135,7 +1139,7 @@ bool camu_sink_connect(struct camu_sink *sink, u8 type, str *addr, u16 port, str
aki_timer_init(&sink->reconnect_timer, sink->loop, reconnect_timer_callback, sink);
aki_timer_set_repeat(&sink->reconnect_timer, AKI_TS_FROM_USEC(1000000));
aki_rpc_init(&sink->client, sink->loop, connection_callback, connection_closed_callback, sink);
- for (u32 i = 0; i < AL_ARRAY_SIZE(commands); i++) {
+ for (u32 i = 0; i < ARRAY_SIZE(commands); i++) {
commands[i].userdata = sink;
al_assert(sink->callback);
aki_rpc_add_command(&sink->client, &commands[i]);
diff --git a/src/mixer/audio_miniaudio.c b/src/mixer/audio_miniaudio.c
index beda5f1..526e464 100644
--- a/src/mixer/audio_miniaudio.c
+++ b/src/mixer/audio_miniaudio.c
@@ -85,7 +85,7 @@ static bool audio_miniaudio_init(struct camu_audio *audio, str *name)
#else
(void)name;
#endif
- s32 ret = ma_context_init(backends, AL_ARRAY_SIZE(backends), &ma->context_config, &ma->context);
+ s32 ret = ma_context_init(backends, ARRAY_SIZE(backends), &ma->context_config, &ma->context);
if (ret != MA_SUCCESS) {
al_log_error("audio_miniaudio", "Failed to initialize context (%d).", ret);
return false;
diff --git a/src/mixer/audio_miniaudio.h b/src/mixer/audio_miniaudio.h
index d93c69c..5bae185 100644
--- a/src/mixer/audio_miniaudio.h
+++ b/src/mixer/audio_miniaudio.h
@@ -4,6 +4,7 @@
// get included the way we want.
// Specifically, on Windows we want to include <winsock2.h> before <windows.h>.
#include <aki/thread.h>
+#include <al/macros.h>
#include <miniaudio.h>
#include "audio.h"
diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c
index 7608efc..c144c69 100644
--- a/src/mixer/mixer.c
+++ b/src/mixer/mixer.c
@@ -109,7 +109,7 @@ void camu_mixer_offset_volume(struct camu_mixer *mixer, f32 amount)
if (FLT_MAX - mixer->volume < amount) {
mixer->volume = FLT_MAX;
} else {
- mixer->volume = AL_MAX(0.f, mixer->volume + amount);
+ mixer->volume = MAX(0.f, mixer->volume + amount);
}
struct camu_audio_buffer *buf;
al_array_foreach(mixer->buffers, i, buf) {
diff --git a/src/render/queue_libplacebo.c b/src/render/queue_libplacebo.c
index a95afc4..b830bb2 100644
--- a/src/render/queue_libplacebo.c
+++ b/src/render/queue_libplacebo.c
@@ -186,25 +186,27 @@ static bool map_av_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *
.map_dovi = false
));
- s64 now = av_rescale_q(frame->best_effort_timestamp, stream->time_base, (AVRational){ 1, 1000 });
- s32 change;
- 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) {
- overlay = al_array_last(lq->overlays);
- }
- if (!overlay || change > 0) {
- overlay = create_subtitle_overlay(gpu, ass_frame);
- overlay->lq = lq;
- al_array_push(lq->overlays, overlay);
+ ((struct pl_source_frame *)src)->frame_data = NULL;
+
+ if (lq->has_subtitles) {
+ s64 now = av_rescale_q(frame->best_effort_timestamp, stream->time_base, (AVRational){ 1, 1000 });
+ s32 change;
+ 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) {
+ overlay = al_array_last(lq->overlays);
+ }
+ if (!overlay || change > 0) {
+ overlay = create_subtitle_overlay(gpu, ass_frame);
+ overlay->lq = lq;
+ al_array_push(lq->overlays, overlay);
+ }
+ overlay->ref++;
+ out_frame->overlays = overlay->overlays;
+ out_frame->num_overlays = overlay->num;
+ ((struct pl_source_frame *)src)->frame_data = overlay;
}
- overlay->ref++;
- out_frame->overlays = overlay->overlays;
- out_frame->num_overlays = overlay->num;
- ((struct pl_source_frame *)src)->frame_data = overlay;
- } else {
- ((struct pl_source_frame *)src)->frame_data = NULL;
}
av_frame_free(&frame);
@@ -267,19 +269,33 @@ static void queue_lp_push_av_frame(struct camu_frame_queue *queue, AVFrame *fram
});
}
-static void queue_lp_configure_subtitiles(struct camu_frame_queue *queue, s32 width, s32 height, AVCodecParameters *codecpar)
+static bool queue_lp_configure_subtitiles(struct camu_frame_queue *queue, s32 width, s32 height, AVCodecParameters *codecpar)
{
struct camu_frame_queue_lp *lq = (struct camu_frame_queue_lp *)queue;
+ if (!lq->ass) return false;
+ lq->ass_renderer = ass_renderer_init(lq->ass);
+ if (!lq->ass_renderer) {
+ al_log_error("frame_queue_libplacebo", "Failed to initialize ass renderer.");
+ return false;
+ }
+ lq->ass_track = ass_new_track(lq->ass);
+ if (!lq->ass_track) {
+ al_log_error("frame_queue_libplacebo", "Failed to create ass track.");
+ return false;
+ }
ass_set_frame_size(lq->ass_renderer, width, height);
ass_set_storage_size(lq->ass_renderer, width, height);
ass_set_fonts(lq->ass_renderer, NULL, NULL, ASS_FONTPROVIDER_AUTODETECT, NULL, 0);
ass_process_codec_private(lq->ass_track, (const char *)codecpar->extradata,
codecpar->extradata_size);
+ lq->has_subtitles = true;
+ return true;
}
static void queue_lp_push_subtitle(struct camu_frame_queue *queue, AVPacket *pkt)
{
struct camu_frame_queue_lp *lq = (struct camu_frame_queue_lp *)queue;
+ al_assert(lq->ass_track && lq->ass_renderer);
ass_process_chunk(lq->ass_track, (const char *)pkt->data, pkt->size, pkt->pts, pkt->duration);
}
#endif
@@ -325,8 +341,10 @@ static void queue_lp_reset(struct camu_frame_queue *queue)
static void queue_lp_free(struct camu_frame_queue **queue)
{
struct camu_frame_queue_lp *lq = (struct camu_frame_queue_lp *)*queue;
- ass_free_track(lq->ass_track);
- ass_renderer_done(lq->ass_renderer);
+ if (lq->has_subtitles) {
+ ass_free_track(lq->ass_track);
+ ass_renderer_done(lq->ass_renderer);
+ }
pl_queue_destroy(&lq->queue);
al_free(lq);
*queue = NULL;
@@ -336,6 +354,7 @@ struct camu_frame_queue *camu_frame_queue_lp_create(void)
{
struct camu_frame_queue_lp *lq = al_alloc_object(struct camu_frame_queue_lp);
al_array_init(lq->overlays);
+ lq->has_subtitles = false;
lq->q.push = queue_lp_push;
#ifdef CAMU_HAVE_FFMPEG
lq->q.push_av_frame = queue_lp_push_av_frame;
diff --git a/src/render/queue_libplacebo.h b/src/render/queue_libplacebo.h
index 3b403e5..4879cdd 100644
--- a/src/render/queue_libplacebo.h
+++ b/src/render/queue_libplacebo.h
@@ -1,10 +1,10 @@
#pragma once
-#include "../buffer/frame_queue.h"
-
#include <libplacebo/utils/frame_queue.h>
#include <libplacebo/utils/upload.h>
-#include <libass/ass.h>
+#include <ass/ass.h>
+
+#include "../buffer/frame_queue.h"
struct camu_overlay_lp {
struct pl_overlay *overlays;
@@ -18,9 +18,11 @@ struct camu_frame_queue_lp {
struct camu_frame_queue q;
pl_queue queue;
struct pl_queue_params params;
+ array(struct camu_overlay_lp *) overlays;
+ ASS_Library *ass;
ASS_Renderer *ass_renderer;
ASS_Track *ass_track;
- array(struct camu_overlay_lp *) overlays;
+ bool has_subtitles;
};
struct camu_frame_queue *camu_frame_queue_lp_create(void);
diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c
index 480da0b..797dbd0 100644
--- a/src/render/renderer_libplacebo.c
+++ b/src/render/renderer_libplacebo.c
@@ -179,8 +179,7 @@ static struct camu_frame_queue *renderer_lp_create_queue(struct camu_renderer *r
lq->params.interpolation_threshold = 0.01f;
lq->params.radius = pl_frame_mix_radius(&lr->params);
lq->params.timeout = 0uL; // vsync
- lq->ass_renderer = ass_renderer_init(lr->ass);
- lq->ass_track = ass_new_track(lr->ass);
+ lq->ass = lr->ass;
return queue;
}
diff --git a/src/render/renderer_libplacebo.h b/src/render/renderer_libplacebo.h
index 5b206c6..eff7a34 100644
--- a/src/render/renderer_libplacebo.h
+++ b/src/render/renderer_libplacebo.h
@@ -4,7 +4,7 @@
#include <libplacebo/renderer.h>
#include <libplacebo/shaders/lut.h>
#include <libplacebo/colorspace.h>
-#include <libass/ass.h>
+#include <ass/ass.h>
#include "renderer.h"
@@ -29,7 +29,6 @@ struct camu_renderer_lp {
pl_renderer renderer;
struct pl_render_params params;
ASS_Library *ass;
- ASS_Renderer *ass_renderer;
};
struct camu_renderer *camu_renderer_lp_create(void);
diff --git a/src/server/server.c b/src/server/server.c
index 6fc2892..e43a57f 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -518,7 +518,7 @@ bool camu_server_init(struct camu_server *server, u8 type, struct aki_event_loop
al_array_push(server->lists, list);
aki_rpc_init(&server->server, server->loop, connection_callback, connection_closed_callback, server);
- for (u32 i = 0; i < AL_ARRAY_SIZE(commands); i++) {
+ for (u32 i = 0; i < ARRAY_SIZE(commands); i++) {
commands[i].userdata = server;
aki_rpc_add_command(&server->server, &commands[i]);
}
diff --git a/src/util/color_palette.c b/src/util/color_palette.c
index 3bc7f3e..cc7f5b5 100644
--- a/src/util/color_palette.c
+++ b/src/util/color_palette.c
@@ -49,13 +49,13 @@ bool camu_color_palette_init(str *path)
if (!special || !colors) return false;
json_t *object;
const char *color;
- for (u32 i = 0; i < AL_ARRAY_SIZE(special_colors); i++) {
+ 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);
}
- for (u32 i = 0; i < AL_ARRAY_SIZE(normal_colors); i++) {
+ 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);