From 28f56a9e1324fbde6854c72d6b234c2f00748d03 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Wed, 27 Nov 2024 11:32:17 -0500 Subject: Sink fixes, update for dependency changes Signed-off-by: Andrew Opalach --- src/buffer/audio.c | 6 ++-- src/buffer/frame_queue.h | 2 +- src/buffer/video.c | 4 +-- src/buffer/video.h | 2 +- src/buffer/volume.h | 12 ++++---- src/cache/backings/file.c | 4 +-- src/cache/backings/file_mapped.c | 4 +-- src/cache/backings/memory.c | 4 +-- src/cache/range.h | 2 +- src/fruits/cmsrv/ui.c | 8 ++--- src/fruits/cmsrv/ui.h | 2 +- src/liana/handlers.c | 2 +- src/liana/list.c | 13 ++++---- src/liana/server.c | 8 +++-- src/liana/server.h | 1 + src/liana/vcr.c | 2 +- src/libclient/client.c | 2 +- src/libsink/sink.c | 66 +++++++++++++++++++++------------------- src/mixer/audio_miniaudio.c | 2 +- src/mixer/audio_miniaudio.h | 1 + src/mixer/mixer.c | 2 +- src/render/queue_libplacebo.c | 61 ++++++++++++++++++++++++------------- src/render/queue_libplacebo.h | 10 +++--- src/render/renderer_libplacebo.c | 3 +- src/render/renderer_libplacebo.h | 3 +- src/server/server.c | 2 +- src/util/color_palette.c | 4 +-- 27 files changed, 130 insertions(+), 102 deletions(-) (limited to 'src') 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 #include #include +#include #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(¤t->name)); + al_log_info("list", "Now playing: %ls.", AL_WSTR_PRINTF(¤t->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 before . #include +#include #include #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 #include -#include +#include + +#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 #include #include -#include +#include #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); -- cgit v1.2.3-101-g0448