summaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-09-08 14:30:49 -0400
committerAndrew Opalach <andrew@akon.city> 2025-09-08 14:30:49 -0400
commit3294789c8712a3cb984ae1bc732934f3e2670a81 (patch)
treec292eb8caba9fcc616624332f4bdc26e197422ea /src/render
parentce955da36daa278d5b331b3c97e228e733a5125e (diff)
downloadcamu-3294789c8712a3cb984ae1bc732934f3e2670a81.tar.gz
camu-3294789c8712a3cb984ae1bc732934f3e2670a81.tar.bz2
camu-3294789c8712a3cb984ae1bc732934f3e2670a81.zip
Optimize subtitle allocations, subtitle toggle
- Cleanup renderers. Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/render')
-rw-r--r--src/render/common.c18
-rw-r--r--src/render/impl_libplacebo.c4
-rw-r--r--src/render/meson.build4
-rw-r--r--src/render/queue_libplacebo.c203
-rw-r--r--src/render/queue_libplacebo.h23
-rw-r--r--src/render/renderer.h14
-rw-r--r--src/render/renderer_libplacebo.c50
-rw-r--r--src/render/renderer_libplacebo.h14
-rw-r--r--src/render/renderer_momo.c6
9 files changed, 208 insertions, 128 deletions
diff --git a/src/render/common.c b/src/render/common.c
new file mode 100644
index 0000000..8b82a14
--- /dev/null
+++ b/src/render/common.c
@@ -0,0 +1,18 @@
+#include "renderer.h"
+
+struct camu_overlay *camu_overlay_alloc(struct camu_overlay *prev, u32 count, size_t item_size)
+{
+ if (prev) {
+ if (count > prev->alloc) {
+ prev = al_realloc(prev, sizeof(struct camu_overlay) + count * item_size);
+ prev->alloc = count;
+ }
+ } else {
+ prev = al_malloc(sizeof(struct camu_overlay) + count * item_size);
+ prev->ref = 0;
+ prev->alloc = count;
+ prev->num = 0;
+ prev->lock = NULL;
+ }
+ return prev;
+}
diff --git a/src/render/impl_libplacebo.c b/src/render/impl_libplacebo.c
new file mode 100644
index 0000000..c688d65
--- /dev/null
+++ b/src/render/impl_libplacebo.c
@@ -0,0 +1,4 @@
+#ifdef CAMU_HAVE_FFMPEG
+#define PL_LIBAV_IMPLEMENTATION 1
+#include "queue_libplacebo.h"
+#endif
diff --git a/src/render/meson.build b/src/render/meson.build
index 4274758..748d9e4 100644
--- a/src/render/meson.build
+++ b/src/render/meson.build
@@ -1,4 +1,4 @@
-render_src = []
+render_src = ['common.c']
render_deps = []
render_args = []
@@ -129,7 +129,7 @@ elif get_option('renderer') == 'libplacebo'
libplacebo = dependency('libplacebo', default_options: libplacebo_opts)
endif
- render_src += ['renderer_libplacebo.c', 'queue_libplacebo.c']
+ render_src += ['renderer_libplacebo.c', 'queue_libplacebo.c', 'impl_libplacebo.c']
render_deps += [libplacebo]
render_args += ['-DCAMU_RENDERER_LIBPLACEBO']
endif
diff --git a/src/render/queue_libplacebo.c b/src/render/queue_libplacebo.c
index 90e7239..5c2ceaf 100644
--- a/src/render/queue_libplacebo.c
+++ b/src/render/queue_libplacebo.c
@@ -1,14 +1,11 @@
#define AL_LOG_SECTION "frame_queue_libplacebo"
-#include <al/lib.h>
#include <al/log.h>
+#include <al/lib.h>
+
#ifdef CAMU_HAVE_FFMPEG
-#define PL_LIBAV_IMPLEMENTATION 1
-#include <libplacebo/utils/libav.h>
#include "../codec/ffmpeg/common.h"
#endif
-#include "../buffer/video.h"
-
#include "queue_libplacebo.h"
static bool queue_lp_configure_subtitles(struct camu_frame_queue *queue, u32 width, u32 height,
@@ -140,72 +137,109 @@ static void queue_lp_push(struct camu_frame_queue *queue, struct camu_codec_fram
#ifdef CAMU_HAVE_FFMPEG
#ifdef CAMU_HAVE_SUBTITLES
-static struct camu_overlay_lp *create_subtitle_overlay(pl_gpu gpu, ASS_Image *ass_frame)
+static void free_overlay(pl_gpu gpu, struct camu_overlay *overlay)
+{
+ al_assert(!overlay->ref);
+ struct pl_overlay *current = CAMU_OVERLAY_OFFSET(overlay, 0);
+ for (u32 i = 0; i < overlay->alloc; i++) {
+ if (current->tex) {
+ pl_tex_destroy(gpu, &current->tex);
+ }
+ current++;
+ }
+ al_free(overlay);
+}
+
+static struct camu_overlay *first_nonref_overlay(struct camu_frame_queue_lp *lq, u32 *index)
+{
+ struct camu_overlay *overlay;
+ al_array_foreach(lq->subtitles, i, overlay) {
+ if (!overlay->ref) {
+ *index = i;
+ return overlay;
+ }
+ }
+ return NULL;
+}
+
+static struct camu_overlay *create_subtitle_overlay(struct camu_overlay *prev, pl_gpu gpu, ASS_Image *ass_frame)
{
- struct camu_overlay_lp *overlay = al_alloc_object(struct camu_overlay_lp);
+ u32 frame_count = 1;
+ ASS_Image *head_ass_frame = ass_frame;
+ while (ass_frame->next) { frame_count++; ass_frame = ass_frame->next; }
+ ass_frame = head_ass_frame;
+
+ u32 prev_alloc = prev ? prev->alloc : 0;
+ struct camu_overlay *overlay = camu_overlay_alloc(prev, frame_count,
+ sizeof(struct pl_overlay) + sizeof(struct pl_overlay_part));
+ if (frame_count > prev_alloc) {
+ // Zero any newly allocated pl_overlays.
+ al_memset(CAMU_OVERLAY_OFFSET(overlay, prev_alloc * sizeof(struct pl_overlay)), 0,
+ (frame_count - prev_alloc) * sizeof(struct pl_overlay));
+ }
+
+ // The list of pl_overlay's need to be contiguous in memory.
+ struct pl_overlay *current = CAMU_OVERLAY_OFFSET(overlay, 0);
+ struct pl_overlay_part *current_part = CAMU_OVERLAY_OFFSET(overlay,
+ sizeof(struct pl_overlay) * overlay->alloc);
+ overlay->num = 0;
+
for (; ass_frame; ass_frame = ass_frame->next) {
- pl_tex tex = pl_tex_create(gpu, pl_tex_params(
+ bool ok = pl_tex_recreate(gpu, &current->tex, pl_tex_params(
.w = ass_frame->w,
.h = ass_frame->h,
.format = pl_find_named_fmt(gpu, "r8"),
.sampleable = true,
.host_writable = true
));
-
- bool ok = pl_tex_upload(gpu, pl_tex_transfer_params(
- .tex = tex,
- .row_pitch = ass_frame->stride,
- .ptr = ass_frame->bitmap
- ));
+ if (ok) {
+ ok = pl_tex_upload(gpu, pl_tex_transfer_params(
+ .tex = current->tex,
+ .row_pitch = ass_frame->stride,
+ .ptr = ass_frame->bitmap
+ ));
+ }
if (!ok) {
+ frame_count--;
log_error("Failed to upload subtitle bitmap.");
continue;
}
- struct pl_overlay *current = NULL;
- if (overlay->num >= overlay->alloc) {
- s32 old_alloc = overlay->alloc;
- overlay->alloc = old_alloc ? al_next_power_of_two(overlay->alloc + 1) : 8;
- overlay->overlays = (struct pl_overlay *)al_realloc(overlay->overlays,
- sizeof(struct pl_overlay) * overlay->alloc);
- for (s32 i = old_alloc; i < overlay->alloc; i++) {
- current = (struct pl_overlay *)&overlay->overlays[i];
- current->parts = (struct pl_overlay_part *)al_malloc(sizeof(struct pl_overlay_part));
- current->num_parts = 0;
- }
- }
-
// https://github.com/mpv-player/mpv/blob/70aaba71d6e3071a732069a1d222d1eb4293faf2/video/out/vo_gpu_next.c#L289
// https://github.com/mpv-player/mpv/blob/70aaba71d6e3071a732069a1d222d1eb4293faf2/sub/ass_mp.c#L195
- current = (struct pl_overlay *)&overlay->overlays[overlay->num++];
- struct pl_overlay_part *part = (struct pl_overlay_part *)&current->parts[0];
- part->src = (pl_rect2df){ 0.f, 0.f, ass_frame->w, ass_frame->h };
- part->dst = (pl_rect2df){
- ass_frame->dst_x,
- ass_frame->dst_y,
- ass_frame->dst_x + ass_frame->w,
- ass_frame->dst_y + ass_frame->h
- };
- u32 c = ass_frame->color;
- part->color[0] = (c >> 24) / 255.0;
- part->color[1] = ((c >> 16) & 0xFF) / 255.0;
- part->color[2] = ((c >> 8) & 0xFF) / 255.0;
- part->color[3] = 1.0 - (c & 0xFF) / 255.0;
-
- current->tex = tex;
- //pl_color_space_from_avframe(&current->color, frame);
current->color = *pl_color_space(
.primaries = PL_COLOR_PRIM_BT_709,
.transfer = PL_COLOR_TRC_SRGB
);
current->mode = PL_OVERLAY_MONOCHROME;
current->repr = pl_color_repr_unknown;
- //current->repr.sys = pl_system_from_av(frame->colorspace);
- //current->repr.levels = pl_levels_from_av(frame->color_range);
current->repr.alpha = PL_ALPHA_INDEPENDENT;
+
current->coords = PL_OVERLAY_COORDS_SRC_FRAME;
+ current_part->src = (pl_rect2df){ 0.f, 0.f, ass_frame->w, ass_frame->h };
+ current_part->dst = (pl_rect2df){
+ ass_frame->dst_x,
+ ass_frame->dst_y,
+ ass_frame->dst_x + ass_frame->w,
+ ass_frame->dst_y + ass_frame->h
+ };
+ u32 c = ass_frame->color;
+ current_part->color[0] = (c >> 24) / 255.0;
+ current_part->color[1] = ((c >> 16) & 0xFF) / 255.0;
+ current_part->color[2] = ((c >> 8) & 0xFF) / 255.0;
+ current_part->color[3] = 1.0 - (c & 0xFF) / 255.0;
+
+ current->parts = current_part;
current->num_parts = 1;
+
+ overlay->num++;
+
+ current++;
+ current_part++;
}
+
+ al_assert((u32)overlay->num == frame_count);
+
return overlay;
}
#endif
@@ -228,6 +262,7 @@ static bool map_av_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *
// https://github.com/streetpea/chiaki-ng/blob/dd145ec2c802814e98fb833d3a9692169aa67315/gui/src/qmlmainwindow.cpp#L860
// https://github.com/streetpea/chiaki-ng/blob/dd145ec2c802814e98fb833d3a9692169aa67315/gui/src/qmlbackend.cpp#L786
+ // pl_map_avframe_derived() will fail under Xwayland because of a lack of EGL_EXT_image_dma_buf_import.
if (!ok && frame->hw_frames_ctx) {
if (!lq->copy_frame_fallback) {
log_warn("Falling back to software copy.");
@@ -256,23 +291,35 @@ static bool map_av_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *
#ifdef CAMU_HAVE_SUBTITLES
if (ok && lq->has_subtitles) {
- s64 pts = av_rescale_q(frame->best_effort_timestamp, stream->time_base, (AVRational){ 1, 1000 });
+ s64 now = av_rescale_q(frame->best_effort_timestamp, stream->time_base, (AVRational){ 1, 1000 });
+ s32 change = -1; // 1 = different position, 2 = different content.
nn_mutex_lock(&lq->subtitle_lock);
- s32 change; // 1 = different position, 2 = different content.
+ ASS_Image *ass_frame = ass_render_frame(lq->ass_renderer, lq->ass_track, now, &change);
+ al_assert(change >= 0);
// ass_frame = NULL and lq->ass_track->n_events = 0 can also mean parsing completely failed.
- ASS_Image *ass_frame = ass_render_frame(lq->ass_renderer, lq->ass_track, pts, &change);
if (ass_frame) {
- struct camu_overlay_lp *overlay = NULL;
- if (lq->overlays.count > 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 camu_overlay *overlay = lq->last_subtitle;
+ if (change != 0) {
+ u32 reused = AL_ARRAY_NO_INDEX;
+ overlay = create_subtitle_overlay(first_nonref_overlay(lq, &reused), gpu, ass_frame);
+ // If all texture uploads failed, overlay->num will be 0.
+ lq->last_subtitle = overlay;
+ if (overlay) {
+ if (reused != AL_ARRAY_NO_INDEX) {
+ // Pointer may have changed due to reallocation.
+ al_array_at(lq->subtitles, reused) = overlay;
+ } else { // New overlay object.
+ overlay->lock = &lq->subtitle_lock;
+ al_array_push(lq->subtitles, overlay);
+ }
+ }
+ }
+ if (overlay) {
+ overlay->ref++;
+ out_frame->overlays = CAMU_OVERLAY_OFFSET(overlay, 0);
+ 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;
}
nn_mutex_unlock(&lq->subtitle_lock);
}
@@ -293,20 +340,10 @@ static bool map_av_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *
static void unmap_av_frame(pl_gpu gpu, struct pl_frame *frame, const struct pl_source_frame *src)
{
if (src->frame_data) {
- struct camu_overlay_lp *overlay = (struct camu_overlay_lp *)src->frame_data;
- struct camu_frame_queue_lp *lq = overlay->lq;
- if (!--overlay->ref) {
- for (s32 i = 0; i < overlay->alloc; i++) {
- struct pl_overlay *current = &overlay->overlays[i];
- if (current->num_parts > 0) {
- pl_tex_destroy(gpu, &current->tex);
- }
- al_free((struct pl_overlay_part *)current->parts);
- }
- al_free(overlay->overlays);
- al_array_remove(lq->overlays, overlay);
- al_free(overlay);
- }
+ struct camu_overlay *overlay = (struct camu_overlay *)src->frame_data;
+ nn_mutex_lock(overlay->lock);
+ overlay->ref--;
+ nn_mutex_unlock(overlay->lock);
}
pl_unmap_avframe(gpu, frame);
}
@@ -391,19 +428,24 @@ 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;
+ pl_queue_destroy(&lq->queue);
+#ifdef CAMU_HAVE_FFMPEG
+ if (lq->copy_frame_fallback) {
+ av_frame_free(&lq->swframe);
+ }
+#endif
#ifdef CAMU_HAVE_SUBTITLES
if (lq->has_subtitles) {
+ struct camu_overlay *overlay;
+ al_array_foreach_rev(lq->subtitles, i, overlay) {
+ free_overlay(lq->gpu, overlay);
+ }
+ al_array_free(lq->subtitles);
ass_free_track(lq->ass_track);
ass_renderer_done(lq->ass_renderer);
nn_mutex_destroy(&lq->subtitle_lock);
}
#endif
-#ifdef CAMU_HAVE_FFMPEG
- if (lq->copy_frame_fallback) {
- av_frame_free(&lq->swframe);
- }
-#endif
- pl_queue_destroy(&lq->queue);
al_free(lq);
*queue = NULL;
}
@@ -411,8 +453,9 @@ static void queue_lp_free(struct camu_frame_queue **queue)
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);
#ifdef CAMU_HAVE_SUBTITLES
+ lq->last_subtitle = NULL;
+ al_array_init(lq->subtitles);
lq->has_subtitles = false;
#endif
lq->q.configure_subtitles = queue_lp_configure_subtitles;
diff --git a/src/render/queue_libplacebo.h b/src/render/queue_libplacebo.h
index 2766447..0d49000 100644
--- a/src/render/queue_libplacebo.h
+++ b/src/render/queue_libplacebo.h
@@ -1,35 +1,36 @@
#pragma once
#include <libplacebo/utils/frame_queue.h>
-#include <libplacebo/utils/upload.h>
+#ifdef CAMU_HAVE_FFMPEG
+#include <al/lib.h>
+AL_IGNORE_WARNING("-Wswitch")
+AL_IGNORE_WARNING("-Wunused-parameter")
+// PL_LIBAV_IMPLEMENTATION defined in queue_libplacebo.c.
+#include <libplacebo/utils/libav.h>
+AL_IGNORE_WARNING_END
+#endif
#ifdef CAMU_HAVE_SUBTITLES
#include <ass/ass.h>
#endif
#include "../buffer/frame_queue.h"
-struct camu_overlay_lp {
- struct pl_overlay *overlays;
- s32 alloc;
- s32 num;
- s16 ref;
- struct camu_frame_queue_lp *lq;
-};
-
struct camu_frame_queue_lp {
struct camu_frame_queue q;
+ pl_gpu gpu;
pl_queue queue;
struct pl_queue_params params;
- bool copy_frame_fallback;
#ifdef CAMU_HAVE_FFMPEG
+ bool copy_frame_fallback;
AVFrame *swframe;
#endif
- array(struct camu_overlay_lp *) overlays;
#ifdef CAMU_HAVE_SUBTITLES
ASS_Library *ass;
ASS_Renderer *ass_renderer;
ASS_Track *ass_track;
struct nn_mutex subtitle_lock;
+ struct camu_overlay *last_subtitle;
+ array(struct camu_overlay *) subtitles;
bool has_subtitles;
#endif
};
diff --git a/src/render/renderer.h b/src/render/renderer.h
index bbb7b70..3331baa 100644
--- a/src/render/renderer.h
+++ b/src/render/renderer.h
@@ -12,8 +12,6 @@
#endif
#endif
-#include "../codec/codec.h"
-
enum {
CAMU_RENDERER_FULLSCREEN = 0,
CAMU_RENDERER_SCALING,
@@ -30,7 +28,17 @@ enum {
CAMU_BACKGROUND_TRANSPARENT
};
+struct camu_overlay {
+ u16 ref;
+ u32 alloc;
+ s32 num;
+ struct nn_mutex *lock;
+};
+
+#define CAMU_OVERLAY_OFFSET(overlay, n) ((void *)(((u8 *)(overlay)) + sizeof(struct camu_overlay) + (n)))
+
struct camu_frame_queue;
+struct camu_codec_stream;
struct camu_screen;
struct camu_renderer {
bool (*create_renderer)(
@@ -66,3 +74,5 @@ struct camu_renderer {
#endif
void (*free)(struct camu_renderer **);
};
+
+struct camu_overlay *camu_overlay_alloc(struct camu_overlay *prev, u32 count, size_t item_size);
diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c
index 6ddca70..47b9ab4 100644
--- a/src/render/renderer_libplacebo.c
+++ b/src/render/renderer_libplacebo.c
@@ -1,20 +1,12 @@
#define AL_LOG_SECTION "renderer_libplacebo"
+//#define AL_LOG_ENABLE_TRACE
#include <al/log.h>
#include <al/lib.h>
#include <nnwt/file.h>
-#ifdef CAMU_HAVE_FFMPEG
-#include <libplacebo/utils/libav.h>
-#endif
#include "../screen/screen.h"
#include "../util/color_palette.h"
-#ifdef STELA_API_DX11
-#include <nnwt/windows.h>
-#define COBJMACROS
-#include <libplacebo/d3d11.h>
-#endif
-
#include "shaders/vr_video.h"
#include "renderer_libplacebo.h"
@@ -59,8 +51,8 @@ static void renderer_lp_set(struct camu_renderer *renderer, u8 option, u8 value)
case CAMU_RENDERER_FULLSCREEN:
#ifdef STELA_API_DX11
IDXGISwapChain *d3d_swapchain = pl_d3d11_swapchain_unwrap(lr->swapchain);
- IDXGISwapChain1_SetFullscreenState(d3d_swapchain, value, NULL);
- IDXGISwapChain1_Release(d3d_swapchain);
+ IDXGISwapChain_SetFullscreenState(d3d_swapchain, value, NULL);
+ IDXGISwapChain_Release(d3d_swapchain);
#endif
break;
case CAMU_RENDERER_SCALING:
@@ -96,6 +88,8 @@ static void log_callback(void *userdata, enum pl_log_level level, const char *me
{
(void)userdata;
if (level < PL_LOG_INFO) {
+ // Console spam of unsupported format kills Windows performance, but the performance
+ // will be shot anyway so allow it.
log_info(message);
} else {
log_debug(message);
@@ -111,10 +105,14 @@ static void ass_log_callback(s32 level, const char *fmt, va_list args, void *use
al_logv(AL_LOG_ERROR, "ass", fmt, args);
} else if (level <= 3) {
al_logv(AL_LOG_WARN, "ass", fmt, args);
- } else {
+ } else if (level <= 6) {
#ifdef AL_DEBUG
al_logv(AL_LOG_DEBUG, "ass", fmt, args);
#endif
+ } else {
+#ifdef AL_LOG_ENABLE_TRACE
+ al_logv(AL_LOG_TRACE, "ass", fmt, args);
+#endif
}
}
#endif
@@ -146,17 +144,10 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid
clear_color[1] = ((global_color_palette.colors[0] >> 8) & 0xff) / 255.f;
clear_color[2] = ((global_color_palette.colors[0]) & 0xff) / 255.f;
- /*
- clear_color[0] = 255.f;
- clear_color[1] = 255.f;
- clear_color[2] = 255.f;
- */
-
-//#define LIBPLACEBO_LOG_TRACE
lr->logger = pl_log_create(PL_API_VER, pl_log_params(
.log_cb = log_callback,
.log_priv = NULL,
-#ifdef LIBPLACEBO_LOG_TRACE
+#ifdef AL_LOG_ENABLE_TRACE
.log_level = PL_LOG_TRACE
#else
.log_level = PL_LOG_INFO
@@ -326,12 +317,15 @@ static struct camu_frame_queue *renderer_lp_create_queue(struct camu_renderer *r
struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer;
struct camu_frame_queue *queue = camu_frame_queue_lp_create();
struct camu_frame_queue_lp *lq = (struct camu_frame_queue_lp *)queue;
+ lq->gpu = lr->gpu;
lq->queue = pl_queue_create(lr->gpu);
al_memset(&lq->params, 0, sizeof(struct pl_queue_params));
lq->params.interpolation_threshold = 0.01f;
lq->params.radius = pl_frame_mix_radius(&lr->params);
lq->params.timeout = 0;
+#ifdef CAMU_HAVE_FFMPEG
lq->copy_frame_fallback = false;
+#endif
#ifdef CAMU_HAVE_SUBTITLES
lq->ass = lr->ass;
#endif
@@ -363,8 +357,7 @@ static u32 renderer_lp_get_latency(struct camu_renderer *renderer)
// https://www.virtualdub.org/blog2/entry_259.html
static inline intptr_t float_64_hash(f64 value)
{
- union { f64 f; u64 u; } fv;
- fv.f = value;
+ union { f64 f; u64 u; } fv = { .f = value };
intptr_t hash = (intptr_t)fv.u;
#ifdef AL_WE_32BIT
hash += (intptr_t)(fv.u >> 32);
@@ -440,6 +433,13 @@ static void renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
}
lr->params.info_priv = (void *)hash;
target->crop = mix.frames[0]->crop;
+ if (!scr->subtitles_enabled) {
+ // This basically discards the subtitles of each frame before it's rendered.
+ // So, toggling the subtitles of a single frame (paused) won't work.
+ for (s32 j = 0; j < mix.num_frames; j++) {
+ ((struct pl_frame *)mix.frames[j])->num_overlays = 0;
+ }
+ }
target->crop.x1 *= video->view.zoom / video->view.stretch;
target->crop.y1 *= video->view.zoom * video->view.stretch;
target->crop.x0 += video->view.x_offset;
@@ -503,8 +503,10 @@ void renderer_lp_free(struct camu_renderer **renderer)
if (lr->swapchain) pl_swapchain_destroy(&lr->swapchain);
#if defined STELA_API_VULKAN
if (lr->vk) pl_vulkan_destroy(&lr->vk);
- lr->vk_destroy_surface(lr->vk_inst->instance, lr->surface);
- if (lr->vk_inst) pl_vk_inst_destroy(&lr->vk_inst);
+ if (lr->vk_inst) {
+ lr->vk_destroy_surface(lr->vk_inst->instance, lr->surface);
+ pl_vk_inst_destroy(&lr->vk_inst);
+ }
#elif defined STELA_API_DX11
if (lr->d3d11) pl_d3d11_destroy(&lr->d3d11);
#elif defined STELA_API_OPENGL
diff --git a/src/render/renderer_libplacebo.h b/src/render/renderer_libplacebo.h
index fd34f7a..5d5cf9b 100644
--- a/src/render/renderer_libplacebo.h
+++ b/src/render/renderer_libplacebo.h
@@ -1,22 +1,20 @@
#pragma once
-#include <libplacebo/common.h>
-#include <libplacebo/renderer.h>
-#include <libplacebo/shaders/lut.h>
-#include <libplacebo/colorspace.h>
-#ifdef CAMU_HAVE_SUBTITLES
-#include <ass/ass.h>
-#endif
-
#include "renderer.h"
+#include <libplacebo/renderer.h>
#if defined STELA_API_VULKAN
#include <libplacebo/vulkan.h>
#elif defined STELA_API_DX11
+#include <nnwt/windows.h>
+#define COBJMACROS
#include <libplacebo/d3d11.h>
#elif defined STELA_API_OPENGL
#include <libplacebo/opengl.h>
#endif
+#ifdef CAMU_HAVE_SUBTITLES
+#include <ass/ass.h>
+#endif
struct camu_renderer_lp {
struct camu_renderer r;
diff --git a/src/render/renderer_momo.c b/src/render/renderer_momo.c
index 3cc8bc1..3a0e7ed 100644
--- a/src/render/renderer_momo.c
+++ b/src/render/renderer_momo.c
@@ -51,12 +51,13 @@ static bool renderer_momo_create_renderer(struct camu_renderer *renderer, u32 *w
// Just to keep these linked in the exe for platform testing.
ASS_Renderer *ar = ass_renderer_init(mr->ass);
ASS_Track *at = ass_new_track(mr->ass);
- (void)at;
u32 w = *width, h = *height;
ass_set_frame_size(ar, w, h);
ass_set_storage_size(ar, w, h);
ass_set_fonts(ar, NULL, NULL, ASS_FONTPROVIDER_AUTODETECT, NULL, 0);
ass_set_hinting(ar, ASS_HINTING_NONE);
+ ass_free_track(at);
+ ass_renderer_done(ar);
#endif
return true;
}
@@ -95,6 +96,9 @@ static void renderer_momo_render(struct camu_renderer *renderer, struct camu_scr
static void renderer_momo_free(struct camu_renderer **renderer)
{
struct camu_renderer_momo *mr = (struct camu_renderer_momo *)*renderer;
+#ifdef CAMU_HAVE_SUBTITLES
+ if (mr->ass) ass_library_done(mr->ass);
+#endif
al_free(mr);
*renderer = NULL;
}