sd_lavc: add support for DVD sub highlight

This is connected to standard DVD subs renderer, with additional state
passed for highlight color.
This commit is contained in:
Kacper Michajłow committed 2026-08-26 01:47:41 +02:00
1 parent fad4b3f321
commit 8b583e9a0d
2 files changed
+62 -2

No files matched your search

+8
View File
@@ -21,6 +21,14 @@ enum sd_ctrl {
SD_CTRL_SET_VIDEO_DEF_FPS,
SD_CTRL_RESET_SOFT,
SD_CTRL_UPDATE_OPTS,
SD_CTRL_APPLY_DVDNAV, // struct mp_dvdnav_hli *
};
struct mp_dvdnav_hli {
bool show;
int x, y, w, h; // button rect in SPU/source coords
uint32_t palette[4]; // 0xAARRGGBB, straight alpha
uint32_t change_id; // bumped on any visible change
};
enum sd_text_type {
+54 -2
View File
@@ -71,6 +71,10 @@ struct sd_lavc_priv {
struct seekpoint *seekpoints;
int num_seekpoints;
struct bitmap_packer *packer;
// DVD-nav per-pixel highlight overlay state.
struct mp_dvdnav_hli hli;
uint32_t hli_change_id;
};
static int init(struct sd *sd)
@@ -295,6 +299,23 @@ static void read_sub_bitmaps(struct sd *sd, struct sub *sub)
memcpy(pal, data[1], r->nb_colors * 4);
convert_pal(pal, 256, opts->sub_gray);
// DVD navigation highlight
bool hli_active = priv->hli.show &&
priv->hli.w > 0 && priv->hli.h > 0 &&
r->x < priv->hli.x + priv->hli.w &&
r->y < priv->hli.y + priv->hli.h &&
r->x + r->w > priv->hli.x &&
r->y + r->h > priv->hli.y;
uint32_t hli_pal[4] = {0};
if (hli_active) {
memcpy(hli_pal, priv->hli.palette, sizeof(hli_pal));
convert_pal(hli_pal, 4, opts->sub_gray);
}
int hli_x0 = priv->hli.x - r->x;
int hli_y0 = priv->hli.y - r->y;
int hli_x1 = hli_x0 + priv->hli.w;
int hli_y1 = hli_y0 + priv->hli.h;
for (int y = -padding; y < b->h + padding; y++) {
uint32_t *out = (uint32_t*)((char*)b->bitmap + y * b->stride);
int start = 0;
@@ -302,8 +323,14 @@ static void read_sub_bitmaps(struct sd *sd, struct sub *sub)
out[x] = 0;
if (y >= 0 && y < b->h) {
uint8_t *in = data[0] + y * linesize[0];
for (int x = 0; x < b->w; x++)
*out++ = pal[*in++];
bool y_in_hli = hli_active && y >= hli_y0 && y < hli_y1;
for (int x = 0; x < b->w; x++) {
uint8_t pv = *in++;
if (y_in_hli && x >= hli_x0 && x < hli_x1 && pv < 4)
*out++ = hli_pal[pv];
else
*out++ = pal[pv];
}
start = b->w;
}
for (int x = start; x < b->w + padding; x++)
@@ -323,6 +350,21 @@ static void read_sub_bitmaps(struct sd *sd, struct sub *sub)
}
}
static void rerender_queued_subs(struct sd *sd)
{
struct sd_lavc_priv *priv = sd->priv;
for (int n = 0; n < MAX_QUEUE; n++) {
struct sub *sub = &priv->subs[n];
if (!sub->valid)
continue;
sub->count = 0;
sub->src_w = 0;
sub->src_h = 0;
sub->id = priv->new_id++;
read_sub_bitmaps(sd, sub);
}
}
static void decode(struct sd *sd, struct demux_packet *packet)
{
struct mp_subtitle_opts *opts = sd->opts;
@@ -717,6 +759,16 @@ static int control(struct sd *sd, enum sd_ctrl cmd, void *arg)
case SD_CTRL_SET_VIDEO_PARAMS:
priv->video_params = *(struct mp_image_params *)arg;
return CONTROL_OK;
case SD_CTRL_APPLY_DVDNAV: {
struct mp_dvdnav_hli *hli = arg;
if (priv->hli_change_id == hli->change_id)
return CONTROL_OK;
priv->hli = *hli;
priv->hli_change_id = hli->change_id;
// Re-render any decoded subtitles, after style update.
rerender_queued_subs(sd);
return CONTROL_OK;
}
default:
return CONTROL_UNKNOWN;
}