summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buffer/audio.c8
-rw-r--r--src/fruits/cmv/cmv.c22
-rw-r--r--src/libsink/desktop.c2
-rw-r--r--src/libsink/sink.c33
-rw-r--r--src/render/meson.build1
-rw-r--r--src/render/renderer_libplacebo.c30
-rw-r--r--src/screen/screen.c18
-rw-r--r--src/util/color_palette.c2
-rw-r--r--src/util/color_palette.h2
9 files changed, 63 insertions, 55 deletions
diff --git a/src/buffer/audio.c b/src/buffer/audio.c
index 7c10dda..a815c66 100644
--- a/src/buffer/audio.c
+++ b/src/buffer/audio.c
@@ -145,8 +145,8 @@ static bool push_internal(struct camu_audio_buffer *buf, f64 pts, u8 **data, s32
}
}
- if (base_pts == -1.0) {
- // We want this push() to set the pts even if sample_count = 0.
+ if (base_pts == -1.0) { // This push() has to set buf->pts even if sample_count = 0.
+ al_assert(!buf->buffered);
atomic_store(f64)(&buf->pts, pts, AL_ATOMIC_RELEASE);
}
@@ -478,8 +478,8 @@ ptrdiff_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, ptrdif
}
out:
- // We aren't safe to increment buf->pts from a different thread.
- // For that we could accumulate the difference and atomic_add here instead.
+ // Updating buf->pts from the read() thread has to be done in a single step.
+ // atomic_add() at the points where base_pts is incremented would be incorrect.
atomic_store(f64)(&buf->pts, base_pts, AL_ATOMIC_RELEASE);
// To signal EOF, return less then req.
diff --git a/src/fruits/cmv/cmv.c b/src/fruits/cmv/cmv.c
index 6fe0790..a525377 100644
--- a/src/fruits/cmv/cmv.c
+++ b/src/fruits/cmv/cmv.c
@@ -121,19 +121,12 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
camu_ff_common_init();
#endif
- char *home_env = getenv("HOME");
- if (home_env) {
- str color_palette;
- al_str_from(&color_palette, home_env);
- al_str_cat(&color_palette, &al_str_c("/.config/colors.json"));
- camu_color_palette_init(&color_palette);
- al_str_free(&color_palette);
- }
+ s32 ret = EXIT_SUCCESS;
nn_event_loop_init(&c.loop);
u8 type;
- str addr;
+ str addr = al_str_null();
if (local) {
#ifdef NAUNET_ON_WINDOWS
type = NNWT_SOCKET_TCP;
@@ -170,8 +163,6 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
prefs->language.audio = CAMU_LANG_JAPANESE;
prefs->language.subtitles = CAMU_LANG_ENGLISH;
- s32 ret = EXIT_SUCCESS;
-
#ifndef CAMU_SINK_ONLY
if (local) {
camu_server_init(&c.server, &c.loop);
@@ -186,6 +177,15 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
}
#endif
+ char *home_env = getenv("HOME");
+ if (home_env) {
+ str color_palette;
+ al_str_from(&color_palette, home_env);
+ al_str_cat(&color_palette, &al_str_c("/.config/colors.json"));
+ camu_colors_maybe_init(&color_palette);
+ al_str_free(&color_palette);
+ }
+
str window_name;
al_str_from(&window_name, "Sink (");
if (local) {
diff --git a/src/libsink/desktop.c b/src/libsink/desktop.c
index ccc34a3..e9ccedb 100644
--- a/src/libsink/desktop.c
+++ b/src/libsink/desktop.c
@@ -256,7 +256,7 @@ bool camu_desktop_connect(struct camu_desktop *c, str *name, struct nn_event_loo
bool camu_desktop_tick(struct camu_desktop *c)
{
bool force;
- if (camu_screen_tick(&c->scr, &force) && !c->should_quit) {
+ if (!c->should_quit && camu_screen_tick(&c->scr, &force)) {
if (!c->renderer->render(c->renderer, &c->scr, force)) {
log_error("render() failed, forcing exit.");
c->should_quit = 1;
diff --git a/src/libsink/sink.c b/src/libsink/sink.c
index 6c061a5..783f242 100644
--- a/src/libsink/sink.c
+++ b/src/libsink/sink.c
@@ -65,7 +65,7 @@ AL_STATIC_ASSERT(max_age_lt_lru, ENTRY_MAX_AGE, <, SINK_LRU_MAX);
// Store connection number in the upper 16 bits so IDs don't conflict after a server restart.
// If the sink disconnects but the server didn't restart, this will invalidate IDs that _do_ map
// to the same resource. That could be wasteful. It's also currently (ab)used by reseek().
-#define LOCAL_ENTRY_ID(sink, id) (((u64)(sink)->connection_number) << 48 | (u64)(id))
+#define LOCAL_ENTRY_ID(sink, id) (((u64)(sink)->connection_number) << 48 | (u64)(id)) // id is a u32.
#define REMOTE_ENTRY_ID(id) ((u32)(id & 0x7fffffff))
#define CONNECTION_NUMBER(id) ((id >> 48) & 0xffff)
@@ -73,13 +73,8 @@ AL_STATIC_ASSERT(max_age_lt_lru, ENTRY_MAX_AGE, <, SINK_LRU_MAX);
#define ENTRY_IS_VALID(entry) ((entry) && (entry) != (struct camu_sink_entry *)0xb00b)
// printf format for entries.
-#ifdef AL_DEBUG
-#define ENTRY_FMT "#%u(%p)" // @TODO: Put static and ended here at least.
-#define ENTRY_ARG(entry) (ENTRY_IS_VALID(entry) ? REMOTE_ENTRY_ID((entry)->id) : 0), ((entry) ? (entry) : 0x0)
-#else
-#define ENTRY_FMT "#%u"
-#define ENTRY_ARG(entry) (ENTRY_IS_VALID(entry) ? REMOTE_ENTRY_ID((entry)->id) : 0)
-#endif
+#define ENTRY_FMT "#%u(%p)"
+#define ENTRY_ARG(entry) (ENTRY_IS_VALID(entry) ? REMOTE_ENTRY_ID((entry)->id) : 0), (entry)
#define AUDIO_STATE(entry) ((entry)->audio.state)
#define VIDEO_STATE(entry) ((entry)->video.state)
@@ -100,6 +95,7 @@ AL_STATIC_ASSERT(max_age_lt_lru, ENTRY_MAX_AGE, <, SINK_LRU_MAX);
#define ENTRY_EVAL_ENDED(entry) \
((AUDIO_ENDED(entry) && (VIDEO_ENDED(entry) || VIDEO_EMPTY(entry) || VIDEO_IS_STATIC(entry))) || \
(AUDIO_EMPTY(entry) && VIDEO_ENDED(entry)))
+// This assert would fail if using ENTRY_ENDED() in end_entry_and_advance_queue() before setting entry->ended.
#define ENTRY_ENDED(entry) (al_assert(entry->ended == ENTRY_EVAL_ENDED(entry)), entry->ended)
// IGNORED = ENDED or EMPTY.
@@ -921,16 +917,18 @@ static void evaluate_and_set_buffer_params(struct camu_sink *sink, struct camu_s
camu_audio_buffer_set_latency(&entry->audio.buf, audio);
camu_audio_buffer_set_no_video(&entry->audio.buf, ignore_video);
camu_video_buffer_set_latency(&entry->video.buf, video);
- log_info("video_latency: %f (%u frames), audio_latency: %f.", video, frames, audio);
+ log_info("video_latency: %fs (%u frames), audio_latency: %fs.", video, frames, audio);
if (sink->local) {
camu_audio_buffer_set_ignore_desync(&entry->audio.buf, ignore_video);
// When the video buffer starts the clock, we have to consider the audio
- // buffer is treating the last period of silence sent during a paused clock
+ // buffer is treating the last period of silence sent while the clock was paused
// as part of the stream. This poses an issue for sync because it requires more
- // than a period-length offset to not skip data at the start. Combined with the
- // fact that the timing of a request for the next period doesn't have be uniform.
- // Could make a diagram of this. // @TODO
- camu_clock_offset(&entry->clock, MAX(audio, video));
+ // than a period-length offset to not skip audio data at the start of the stream.
+ // Combined with the fact that the timing of a request for the next period
+ // doesn't have to be uniform. Something that is expected behavior but becomes
+ // a consideration when thinking about "Has the clock started yet?".
+ // @TODO: Could make a diagram of this.
+ camu_clock_offset(&entry->clock, MAX(audio, video) * 1.25);
}
}
@@ -1053,10 +1051,11 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
case LIANA_CLIENT_REMOVE_BUFFERS: {
struct lia_reconnect_info *rec = (struct lia_reconnect_info *)opaque;
nn_mutex_lock(&sink->lock);
+
log_trace("remove_buffers("ENTRY_FMT", %s, %s), entry == current: %s, static: %s.",
- ENTRY_ARG(entry), BOOLSTR(rec->reconnect),
- BOOLSTR(rec->unconfigured), BOOLSTR(entry == sink->current),
- BOOLSTR(!VIDEO_EMPTY(entry) ? VIDEO_IS_STATIC(entry) : false));
+ ENTRY_ARG(entry), BOOLSTR(rec->reconnect), BOOLSTR(rec->unconfigured),
+ BOOLSTR(entry == sink->current),
+ BOOLSTR(!VIDEO_EMPTY(entry) && VIDEO_IS_STATIC(entry)));
if (entry == sink->current) {
if (rec->reconnect) {
diff --git a/src/render/meson.build b/src/render/meson.build
index 10cb98e..44d8255 100644
--- a/src/render/meson.build
+++ b/src/render/meson.build
@@ -179,6 +179,7 @@ if get_option('subtitles').enabled()
'chafa=disabled',
'icu=disabled',
'freetype=disabled',
+ 'gpu=disabled',
# This does not override yield, and yielding breaks the build if tests=enabled.
# https://github.com/mesonbuild/meson/issues/5214
'tests=disabled',
diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c
index 80a71a6..704aebe 100644
--- a/src/render/renderer_libplacebo.c
+++ b/src/render/renderer_libplacebo.c
@@ -15,7 +15,7 @@
#ifdef AL_DEBUG
// vkQueueSubmit2: VK_ERROR_VALIDATION_FAILED_EXT leads to an annoying deadlock.
-#define RENDERER_DEBUG 0
+#define RENDERER_DEBUG 1
#else
#define RENDERER_DEBUG 0
#endif
@@ -433,7 +433,7 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
enum {
RESULT_SUBMIT = 1,
- RESULT_SUBMIT_AND_WAIT = 1 << 1
+ RESULT_WAIT = 1 << 1
};
u8 result = 0;
@@ -447,8 +447,8 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
if (camu_video_buffer_read(video->buf, &mix, &weighted)) {
// If mix.frames is NULL, read() returned QUEUE_MORE.
if (mix.frames) {
- // weighted is only set when read() returns QUEUE_OK.
- result |= (1 | 1 << weighted);
+ // weighted can only be set when read() returns QUEUE_OK.
+ result |= (RESULT_SUBMIT | (RESULT_WAIT * weighted));
// Terrible hack. Lets us distinguish static video buffers with the same dimensions.
// Tied to a libplacebo patch to consider info_priv in the hash.
intptr_t hash = (intptr_t)video->buf;
@@ -493,9 +493,15 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
*/
#ifdef CRT_BACKGROUND
if (!lr->frame_cleared) {
- clear_color[0] = 0.03f;
- clear_color[1] = 0.03f;
- clear_color[2] = 0.03f;
+ if (lr->params.background != PL_CLEAR_SKIP) {
+ clear_color[0] = 0.025f;
+ clear_color[1] = 0.025f;
+ clear_color[2] = 0.025f;
+ } else {
+ clear_color[0] = 0.f;
+ clear_color[1] = 0.f;
+ clear_color[2] = 0.f;
+ }
pl_frame_clear_rgba(lr->gpu, &lr->target, clear_color);
lr->frame_cleared = true;
}
@@ -554,7 +560,7 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
log_trace("swap_buffers(), (interval: %f).", tick - lr->last_swap_tick);
lr->last_swap_tick = tick;
- if (result & RESULT_SUBMIT_AND_WAIT) {
+ if (result & RESULT_WAIT) {
pl_gpu_finish(lr->gpu);
}
@@ -564,6 +570,10 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
void renderer_lp_free(struct camu_renderer **renderer)
{
struct camu_renderer_lp *lr = (struct camu_renderer_lp *)*renderer;
+#ifdef CAMU_HAVE_SUBTITLES
+ if (lr->ass) ass_library_done(lr->ass);
+#endif
+ if (lr->vr_emulation_hook[0]) pl_mpv_user_shader_destroy(&lr->vr_emulation_hook[0]);
if (lr->renderer) pl_renderer_destroy(&lr->renderer);
if (lr->swapchain) pl_swapchain_destroy(&lr->swapchain);
#if defined STELA_API_VULKAN
@@ -578,10 +588,6 @@ void renderer_lp_free(struct camu_renderer **renderer)
if (lr->gl) pl_opengl_destroy(&lr->gl);
#endif
if (lr->logger) pl_log_destroy(&lr->logger);
- if (lr->vr_emulation_hook[0]) pl_mpv_user_shader_destroy(&lr->vr_emulation_hook[0]);
-#ifdef CAMU_HAVE_SUBTITLES
- if (lr->ass) ass_library_done(lr->ass);
-#endif
al_free(lr);
*renderer = NULL;
}
diff --git a/src/screen/screen.c b/src/screen/screen.c
index cdc42bf..ff36fe1 100644
--- a/src/screen/screen.c
+++ b/src/screen/screen.c
@@ -215,8 +215,12 @@ static bool touch_callback(void *userdata, s32 index, u8 phase, f64 x, f64 y)
if (x >= third && x <= third * 2.0) {
scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL);
} else {
- s32 n = (x >= third) ? 1 : -1;
- scr->callback(scr->userdata, CAMU_SCREEN_SKIP, &n);
+ if (scr->touch_mode) {
+ scr->subtitles_enabled = !scr->subtitles_enabled;
+ } else {
+ s32 n = (x >= third) ? 1 : -1;
+ scr->callback(scr->userdata, CAMU_SCREEN_SKIP, &n);
+ }
}
}
}
@@ -605,9 +609,8 @@ static nn_thread_result NNWT_THREADCALL event_thread(void *userdata)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
nn_thread_set_name("window_events");
- // If we decide to close within a poll, we must not expect any
- // window events after that point.
- while (scr->window->poll(scr->window, true)) {
+ while (!scr->window->closed) {
+ scr->window->poll(scr->window, true);
scr->window->process_events(scr->window);
}
return 0;
@@ -832,9 +835,8 @@ bool camu_screen_poll(struct camu_screen *scr, bool block)
}
stl_window_read_events(scr->window);
#else
- if (scr->window->poll(scr->window, block)) {
- scr->window->process_events(scr->window);
- }
+ scr->window->poll(scr->window, block);
+ scr->window->process_events(scr->window);
#endif
#ifdef STELA_PAUSE
return scr->window->should_refresh(scr->window);
diff --git a/src/util/color_palette.c b/src/util/color_palette.c
index bd923e8..f12d1f8 100644
--- a/src/util/color_palette.c
+++ b/src/util/color_palette.c
@@ -34,7 +34,7 @@ static char *normal_colors[16] = {
};
#endif
-bool camu_color_palette_init(str *path)
+bool camu_colors_maybe_init(str *path)
{
#ifdef NAUNET_HAS_JSON
struct nn_file file;
diff --git a/src/util/color_palette.h b/src/util/color_palette.h
index a71360c..7330135 100644
--- a/src/util/color_palette.h
+++ b/src/util/color_palette.h
@@ -32,4 +32,4 @@ struct camu_color_palette {
extern struct camu_color_palette global_color_palette;
-bool camu_color_palette_init(str *path);
+bool camu_colors_maybe_init(str *path);