Commit 34908ab5e1 for ffmpeg
commit 34908ab5e11b93f650dd17f598f3dcf9149f1750
Author: Ruk Doe <info@doany.io>
Date: Sat Oct 10 18:39:40 2026 +0900
avcodec/libaribcaption: seed the bitmap CLUT once per caption
The CLUT seed is built from every region that may be drawn, so it is
the same for every image of a caption, but it was rebuilt for each one.
Build it once instead. Converting an image only appends colors past the
seed and never changes the alpha table, so restoring the CLUT size at
the start of each image restores the seed.
The output is unchanged: the encoded bitmaps of both aribcaption FATE
samples are identical, with and without ignore_ruby.
Reported-by: Forgejo_Fairy
Reference: #24992
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DdDiDRusmi6eD7qSrKBjHb
diff --git a/libavcodec/libaribcaption.c b/libavcodec/libaribcaption.c
index 4246681bb3..2f63640e8f 100644
--- a/libavcodec/libaribcaption.c
+++ b/libavcodec/libaribcaption.c
@@ -310,7 +310,7 @@ static int aribcaption_trans_bitmap_subtitle(ARIBCaptionContext *ctx)
{
int ret = 0;
AVSubtitle *sub = ctx->sub;
- int status, rect_idx, image_count = 0;
+ int status, rect_idx, image_count = 0, seed_idx, seed_overflow;
int old_width = ctx->frame_width;
int old_height = ctx->frame_height;
@@ -398,18 +398,24 @@ static int aribcaption_trans_bitmap_subtitle(ARIBCaptionContext *ctx)
}
}
+ /* The renderer drops ruby regions with ignore_ruby and regions too small
+ to draw, without telling which region an image comes from. Seed the
+ CLUT with the colors of every region that may be drawn, once. Each
+ image only appends colors past the seed, so dropping them restores it. */
+ clut_reset(ctx);
+ for (int i = 0; i < ctx->caption.region_count; i++)
+ if (!region_skipped(ctx, &ctx->caption.regions[i]))
+ clut_add_region(ctx, &ctx->caption.regions[i]);
+ seed_idx = ctx->clut_idx;
+ seed_overflow = ctx->clut_overflow;
+
for (rect_idx = 0; rect_idx < image_count; rect_idx++) {
AVSubtitleRect *rect = sub->rects[rect_idx];
aribcc_image_t *image = &ctx->render_result.images[rect_idx];
int w, h, shrink_height, dst_idx;
- /* The renderer drops ruby regions with ignore_ruby and regions too
- small to draw, without telling which region an image comes from.
- Seed the CLUT with the colors of every region that may be drawn. */
- clut_reset(ctx);
- for (int i = 0; i < ctx->caption.region_count; i++)
- if (!region_skipped(ctx, &ctx->caption.regions[i]))
- clut_add_region(ctx, &ctx->caption.regions[i]);
+ ctx->clut_idx = seed_idx;
+ ctx->clut_overflow = seed_overflow;
rect->w = image->width * ctx->bitmap_plane_width / ctx->frame_width;
rect->h = image->height * ctx->bitmap_plane_height / ctx->frame_height;