options: add --secondary-sub-ass-override

Default: strip. preserve the old behavior
This commit is contained in:
dyphire 2023-12-18 03:18:11 +08:00 committed by Dudemanguy
parent 702b3eb956
commit b563b2aed0
8 changed files with 45 additions and 28 deletions

View File

@ -2499,6 +2499,12 @@ Subtitles
This also controls some bitmap subtitle overrides, as well as HTML tags in This also controls some bitmap subtitle overrides, as well as HTML tags in
formats like SRT, despite the name of the option. formats like SRT, despite the name of the option.
``--secondary-sub-ass-override=<yes|no|force|scale|strip>``
Control whether user secondary substyle overrides should be applied. This
works exactly like ``--sub-ass-override``.
Default: strip.
``--sub-ass-force-margins`` ``--sub-ass-force-margins``
Enables placing toptitles and subtitles in black borders when they are Enables placing toptitles and subtitles in black borders when they are
available, if the subtitles are in the ASS format. available, if the subtitles are in the ASS format.

View File

@ -313,9 +313,6 @@ const struct m_sub_options mp_subtitle_sub_opts = {
{"sub-ass-shaper", OPT_CHOICE(ass_shaper, {"sub-ass-shaper", OPT_CHOICE(ass_shaper,
{"simple", 0}, {"complex", 1})}, {"simple", 0}, {"complex", 1})},
{"sub-ass-justify", OPT_BOOL(ass_justify)}, {"sub-ass-justify", OPT_BOOL(ass_justify)},
{"sub-ass-override", OPT_CHOICE(ass_style_override,
{"no", 0}, {"yes", 1}, {"force", 3}, {"scale", 4}, {"strip", 5}),
.flags = UPDATE_SUB_HARD},
{"sub-scale-by-window", OPT_BOOL(sub_scale_by_window)}, {"sub-scale-by-window", OPT_BOOL(sub_scale_by_window)},
{"sub-scale-with-window", OPT_BOOL(sub_scale_with_window)}, {"sub-scale-with-window", OPT_BOOL(sub_scale_with_window)},
{"sub-ass-scale-with-window", OPT_BOOL(ass_scale_with_window)}, {"sub-ass-scale-with-window", OPT_BOOL(ass_scale_with_window)},
@ -338,7 +335,6 @@ const struct m_sub_options mp_subtitle_sub_opts = {
.ass_vsfilter_aspect_compat = true, .ass_vsfilter_aspect_compat = true,
.ass_vsfilter_color_compat = 1, .ass_vsfilter_color_compat = 1,
.ass_vsfilter_blur_compat = true, .ass_vsfilter_blur_compat = true,
.ass_style_override = 1,
.ass_shaper = 1, .ass_shaper = 1,
.use_embedded_fonts = true, .use_embedded_fonts = true,
}, },
@ -356,6 +352,12 @@ const struct m_sub_options mp_subtitle_shared_sub_opts = {
{"secondary-sub-pos", OPT_FLOAT(sub_pos[1]), M_RANGE(0.0, 150.0)}, {"secondary-sub-pos", OPT_FLOAT(sub_pos[1]), M_RANGE(0.0, 150.0)},
{"sub-visibility", OPT_BOOL(sub_visibility[0])}, {"sub-visibility", OPT_BOOL(sub_visibility[0])},
{"secondary-sub-visibility", OPT_BOOL(sub_visibility[1])}, {"secondary-sub-visibility", OPT_BOOL(sub_visibility[1])},
{"sub-ass-override", OPT_CHOICE(ass_style_override[0],
{"no", 0}, {"yes", 1}, {"force", 3}, {"scale", 4}, {"strip", 5}),
.flags = UPDATE_SUB_HARD},
{"secondary-sub-ass-override", OPT_CHOICE(ass_style_override[1],
{"no", 0}, {"yes", 1}, {"force", 3}, {"scale", 4}, {"strip", 5}),
.flags = UPDATE_SUB_HARD},
{0} {0}
}, },
.size = sizeof(OPT_BASE_STRUCT), .size = sizeof(OPT_BASE_STRUCT),
@ -363,6 +365,8 @@ const struct m_sub_options mp_subtitle_shared_sub_opts = {
.sub_visibility[0] = true, .sub_visibility[0] = true,
.sub_visibility[1] = true, .sub_visibility[1] = true,
.sub_pos[0] = 100, .sub_pos[0] = 100,
.ass_style_override[0] = 1,
.ass_style_override[1] = 5,
}, },
.change_flags = UPDATE_OSD, .change_flags = UPDATE_OSD,
}; };
@ -1090,6 +1094,7 @@ static const struct MPOpts mp_default_opts = {
"sub-ass-force-margins", "sub-ass-force-margins",
"sub-ass-vsfilter-aspect-compat", "sub-ass-vsfilter-aspect-compat",
"sub-ass-override", "sub-ass-override",
"secondary-sub-ass-override",
"secondary-sub-visibility", "secondary-sub-visibility",
"ab-loop-a", "ab-loop-a",
"ab-loop-b", "ab-loop-b",

View File

@ -107,7 +107,6 @@ struct mp_subtitle_opts {
bool use_embedded_fonts; bool use_embedded_fonts;
char **ass_style_override_list; char **ass_style_override_list;
char *ass_styles_file; char *ass_styles_file;
int ass_style_override;
int ass_hinting; int ass_hinting;
int ass_shaper; int ass_shaper;
bool ass_justify; bool ass_justify;
@ -121,6 +120,7 @@ struct mp_subtitle_shared_opts {
float sub_delay[2]; float sub_delay[2];
float sub_pos[2]; float sub_pos[2];
bool sub_visibility[2]; bool sub_visibility[2];
int ass_style_override[2];
}; };
struct mp_sub_filter_opts { struct mp_sub_filter_opts {

View File

@ -4257,6 +4257,7 @@ static const struct property_osd_display {
{"sub-scale", "Sub Scale"}, {"sub-scale", "Sub Scale"},
{"sub-ass-vsfilter-aspect-compat", "Subtitle VSFilter aspect compat"}, {"sub-ass-vsfilter-aspect-compat", "Subtitle VSFilter aspect compat"},
{"sub-ass-override", "ASS subtitle style override"}, {"sub-ass-override", "ASS subtitle style override"},
{"secondary-sub-ass-override", "Secondary sub ASS subtitle style override"},
{"vf", "Video filters", .msg = "Video filters:\n${vf}"}, {"vf", "Video filters", .msg = "Video filters:\n${vf}"},
{"af", "Audio filters", .msg = "Audio filters:\n${af}"}, {"af", "Audio filters", .msg = "Audio filters:\n${af}"},
{"ab-loop-a", "A-B loop start"}, {"ab-loop-a", "A-B loop start"},

View File

@ -144,6 +144,7 @@ static struct sd *init_decoder(struct dec_sub *sub)
.opts = sub->opts, .opts = sub->opts,
.shared_opts = sub->shared_opts, .shared_opts = sub->shared_opts,
.driver = driver, .driver = driver,
.order = sub->order,
.attachments = sub->attachments, .attachments = sub->attachments,
.codec = sub->codec, .codec = sub->codec,
.preload_ok = true, .preload_ok = true,
@ -368,7 +369,7 @@ struct sub_bitmaps *sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim,
if (!(sub->end != MP_NOPTS_VALUE && pts >= sub->end) && if (!(sub->end != MP_NOPTS_VALUE && pts >= sub->end) &&
sub->sd->driver->get_bitmaps) sub->sd->driver->get_bitmaps)
res = sub->sd->driver->get_bitmaps(sub->sd, dim, format, pts, sub->order); res = sub->sd->driver->get_bitmaps(sub->sd, dim, format, pts);
mp_mutex_unlock(&sub->lock); mp_mutex_unlock(&sub->lock);
return res; return res;

View File

@ -20,6 +20,7 @@ struct sd {
const struct sd_functions *driver; const struct sd_functions *driver;
void *priv; void *priv;
int order;
struct attachment_list *attachments; struct attachment_list *attachments;
struct mp_codec_params *codec; struct mp_codec_params *codec;
@ -42,7 +43,7 @@ struct sd_functions {
int (*control)(struct sd *sd, enum sd_ctrl cmd, void *arg); int (*control)(struct sd *sd, enum sd_ctrl cmd, void *arg);
struct sub_bitmaps *(*get_bitmaps)(struct sd *sd, struct mp_osd_res dim, struct sub_bitmaps *(*get_bitmaps)(struct sd *sd, struct mp_osd_res dim,
int format, double pts, int order); int format, double pts);
char *(*get_text)(struct sd *sd, double pts, enum sd_text_type type); char *(*get_text)(struct sd *sd, double pts, enum sd_text_type type);
struct sd_times (*get_times)(struct sd *sd, double pts); struct sd_times (*get_times)(struct sd *sd, double pts);
}; };

View File

@ -77,9 +77,10 @@ static const struct sd_filter_functions *const filters[] = {
// Add default styles, if the track does not have any styles yet. // Add default styles, if the track does not have any styles yet.
// Apply style overrides if the user provides any. // Apply style overrides if the user provides any.
static void mp_ass_add_default_styles(ASS_Track *track, struct mp_subtitle_opts *opts) static void mp_ass_add_default_styles(ASS_Track *track, struct mp_subtitle_opts *opts,
struct mp_subtitle_shared_opts *shared_opts, int order)
{ {
if (opts->ass_styles_file && opts->ass_style_override) if (opts->ass_styles_file && shared_opts->ass_style_override[order])
ass_read_styles(track, opts->ass_styles_file, NULL); ass_read_styles(track, opts->ass_styles_file, NULL);
if (track->n_styles == 0) { if (track->n_styles == 0) {
@ -95,7 +96,7 @@ static void mp_ass_add_default_styles(ASS_Track *track, struct mp_subtitle_opts
mp_ass_set_style(style, track->PlayResY, opts->sub_style); mp_ass_set_style(style, track->PlayResY, opts->sub_style);
} }
if (opts->ass_style_override) if (shared_opts->ass_style_override[order])
ass_process_force_style(track); ass_process_force_style(track);
} }
@ -206,13 +207,14 @@ static void assobjects_init(struct sd *sd)
{ {
struct sd_ass_priv *ctx = sd->priv; struct sd_ass_priv *ctx = sd->priv;
struct mp_subtitle_opts *opts = sd->opts; struct mp_subtitle_opts *opts = sd->opts;
struct mp_subtitle_shared_opts *shared_opts = sd->shared_opts;
ctx->ass_library = mp_ass_init(sd->global, sd->opts->sub_style, sd->log); ctx->ass_library = mp_ass_init(sd->global, sd->opts->sub_style, sd->log);
ass_set_extract_fonts(ctx->ass_library, opts->use_embedded_fonts); ass_set_extract_fonts(ctx->ass_library, opts->use_embedded_fonts);
add_subtitle_fonts(sd); add_subtitle_fonts(sd);
if (opts->ass_style_override) if (shared_opts->ass_style_override[sd->order])
ass_set_style_overrides(ctx->ass_library, opts->ass_style_override_list); ass_set_style_overrides(ctx->ass_library, opts->ass_style_override_list);
ctx->ass_track = ass_new_track(ctx->ass_library); ctx->ass_track = ass_new_track(ctx->ass_library);
@ -221,7 +223,7 @@ static void assobjects_init(struct sd *sd)
ctx->shadow_track = ass_new_track(ctx->ass_library); ctx->shadow_track = ass_new_track(ctx->ass_library);
ctx->shadow_track->PlayResX = MP_ASS_FONT_PLAYRESX; ctx->shadow_track->PlayResX = MP_ASS_FONT_PLAYRESX;
ctx->shadow_track->PlayResY = MP_ASS_FONT_PLAYRESY; ctx->shadow_track->PlayResY = MP_ASS_FONT_PLAYRESY;
mp_ass_add_default_styles(ctx->shadow_track, opts); mp_ass_add_default_styles(ctx->shadow_track, opts, shared_opts, sd->order);
char *extradata = sd->codec->extradata; char *extradata = sd->codec->extradata;
int extradata_size = sd->codec->extradata_size; int extradata_size = sd->codec->extradata_size;
@ -232,7 +234,7 @@ static void assobjects_init(struct sd *sd)
if (extradata) if (extradata)
ass_process_codec_private(ctx->ass_track, extradata, extradata_size); ass_process_codec_private(ctx->ass_track, extradata, extradata_size);
mp_ass_add_default_styles(ctx->ass_track, opts); mp_ass_add_default_styles(ctx->ass_track, opts, shared_opts, sd->order);
#if LIBASS_VERSION >= 0x01302000 #if LIBASS_VERSION >= 0x01302000
ass_set_check_readorder(ctx->ass_track, sd->opts->sub_clear_on_seek ? 0 : 1); ass_set_check_readorder(ctx->ass_track, sd->opts->sub_clear_on_seek ? 0 : 1);
@ -378,7 +380,7 @@ static void decode(struct sd *sd, struct demux_packet *packet)
} }
static void configure_ass(struct sd *sd, struct mp_osd_res *dim, static void configure_ass(struct sd *sd, struct mp_osd_res *dim,
bool converted, ASS_Track *track, int order) bool converted, ASS_Track *track)
{ {
struct mp_subtitle_opts *opts = sd->opts; struct mp_subtitle_opts *opts = sd->opts;
struct mp_subtitle_shared_opts *shared_opts = sd->shared_opts; struct mp_subtitle_shared_opts *shared_opts = sd->shared_opts;
@ -397,7 +399,7 @@ static void configure_ass(struct sd *sd, struct mp_osd_res *dim,
bool set_scale_by_window = true; bool set_scale_by_window = true;
bool total_override = false; bool total_override = false;
// With forced overrides, apply the --sub-* specific options // With forced overrides, apply the --sub-* specific options
if (converted || opts->ass_style_override == 3) { // 'force' if (converted || shared_opts->ass_style_override[sd->order] == 3) { // 'force'
set_scale_with_window = opts->sub_scale_with_window; set_scale_with_window = opts->sub_scale_with_window;
set_use_margins = opts->sub_use_margins; set_use_margins = opts->sub_use_margins;
set_scale_by_window = opts->sub_scale_by_window; set_scale_by_window = opts->sub_scale_by_window;
@ -406,8 +408,8 @@ static void configure_ass(struct sd *sd, struct mp_osd_res *dim,
set_scale_with_window = opts->ass_scale_with_window; set_scale_with_window = opts->ass_scale_with_window;
set_use_margins = opts->ass_use_margins; set_use_margins = opts->ass_use_margins;
} }
if (converted || opts->ass_style_override) { if (converted || shared_opts->ass_style_override[sd->order]) {
set_sub_pos = 100.0f - shared_opts->sub_pos[order]; set_sub_pos = 100.0f - shared_opts->sub_pos[sd->order];
set_line_spacing = opts->ass_line_spacing; set_line_spacing = opts->ass_line_spacing;
set_hinting = opts->ass_hinting; set_hinting = opts->ass_hinting;
set_font_scale = opts->sub_scale; set_font_scale = opts->sub_scale;
@ -427,12 +429,12 @@ static void configure_ass(struct sd *sd, struct mp_osd_res *dim,
int set_force_flags = 0; int set_force_flags = 0;
if (total_override) if (total_override)
set_force_flags |= ASS_OVERRIDE_BIT_STYLE | ASS_OVERRIDE_BIT_SELECTIVE_FONT_SCALE; set_force_flags |= ASS_OVERRIDE_BIT_STYLE | ASS_OVERRIDE_BIT_SELECTIVE_FONT_SCALE;
if (opts->ass_style_override == 4) // 'scale' if (shared_opts->ass_style_override[sd->order] == 4) // 'scale'
set_force_flags |= ASS_OVERRIDE_BIT_SELECTIVE_FONT_SCALE; set_force_flags |= ASS_OVERRIDE_BIT_SELECTIVE_FONT_SCALE;
if (converted) if (converted)
set_force_flags |= ASS_OVERRIDE_BIT_ALIGNMENT; set_force_flags |= ASS_OVERRIDE_BIT_ALIGNMENT;
#ifdef ASS_JUSTIFY_AUTO #ifdef ASS_JUSTIFY_AUTO
if ((converted || opts->ass_style_override) && opts->ass_justify) if ((converted || shared_opts->ass_style_override[sd->order]) && opts->ass_justify)
set_force_flags |= ASS_OVERRIDE_BIT_JUSTIFY; set_force_flags |= ASS_OVERRIDE_BIT_JUSTIFY;
#endif #endif
ass_set_selective_style_override_enabled(priv, set_force_flags); ass_set_selective_style_override_enabled(priv, set_force_flags);
@ -499,7 +501,7 @@ static long long find_timestamp(struct sd *sd, double pts)
long long ts = llrint(pts * 1000); long long ts = llrint(pts * 1000);
if (!sd->opts->sub_fix_timing || sd->opts->ass_style_override == 0) if (!sd->opts->sub_fix_timing || sd->shared_opts->ass_style_override[sd->order] == 0)
return ts; return ts;
// Try to fix small gaps and overlaps. // Try to fix small gaps and overlaps.
@ -557,11 +559,12 @@ static long long find_timestamp(struct sd *sd, double pts)
#undef END #undef END
static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res dim, static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res dim,
int format, double pts, int order) int format, double pts)
{ {
struct sd_ass_priv *ctx = sd->priv; struct sd_ass_priv *ctx = sd->priv;
struct mp_subtitle_opts *opts = sd->opts; struct mp_subtitle_opts *opts = sd->opts;
bool no_ass = !opts->ass_enabled || opts->ass_style_override == 5 || order == 1; struct mp_subtitle_shared_opts *shared_opts = sd->shared_opts;
bool no_ass = !opts->ass_enabled || shared_opts->ass_style_override[sd->order] == 5;
bool converted = ctx->is_converted || no_ass; bool converted = ctx->is_converted || no_ass;
ASS_Track *track = no_ass ? ctx->shadow_track : ctx->ass_track; ASS_Track *track = no_ass ? ctx->shadow_track : ctx->ass_track;
ASS_Renderer *renderer = ctx->ass_renderer; ASS_Renderer *renderer = ctx->ass_renderer;
@ -581,7 +584,7 @@ static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res dim,
goto done; goto done;
double scale = dim.display_par; double scale = dim.display_par;
if (!converted && (!opts->ass_style_override || if (!converted && (!shared_opts->ass_style_override[sd->order] ||
opts->ass_vsfilter_aspect_compat)) opts->ass_vsfilter_aspect_compat))
{ {
// Let's use the original video PAR for vsfilter compatibility: // Let's use the original video PAR for vsfilter compatibility:
@ -590,11 +593,11 @@ static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res dim,
scale *= par; scale *= par;
} }
if (!ctx->ass_configured || !osd_res_equals(old_osd, ctx->osd)) { if (!ctx->ass_configured || !osd_res_equals(old_osd, ctx->osd)) {
configure_ass(sd, &dim, converted, track, order); configure_ass(sd, &dim, converted, track);
ctx->ass_configured = true; ctx->ass_configured = true;
} }
ass_set_pixel_aspect(renderer, scale); ass_set_pixel_aspect(renderer, scale);
if (!converted && (!opts->ass_style_override || if (!converted && (!shared_opts->ass_style_override[sd->order] ||
opts->ass_vsfilter_blur_compat)) opts->ass_vsfilter_blur_compat))
{ {
ass_set_storage_size(renderer, ctx->video_params.w, ctx->video_params.h); ass_set_storage_size(renderer, ctx->video_params.w, ctx->video_params.h);

View File

@ -399,7 +399,7 @@ static struct sub *get_current(struct sd_lavc_priv *priv, double pts)
} }
static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res d, static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res d,
int format, double pts, int order) int format, double pts)
{ {
struct sd_lavc_priv *priv = sd->priv; struct sd_lavc_priv *priv = sd->priv;
struct mp_subtitle_opts *opts = sd->opts; struct mp_subtitle_opts *opts = sd->opts;
@ -451,7 +451,7 @@ static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res d,
h = MPMAX(priv->video_params.h, current->src_h); h = MPMAX(priv->video_params.h, current->src_h);
} }
if (shared_opts->sub_pos[0] != 100.0f && opts->ass_style_override) { if (shared_opts->sub_pos[0] != 100.0f && shared_opts->ass_style_override[0]) {
float offset = (100.0f - shared_opts->sub_pos[0]) / 100.0f * h; float offset = (100.0f - shared_opts->sub_pos[0]) / 100.0f * h;
for (int n = 0; n < res->num_parts; n++) { for (int n = 0; n < res->num_parts; n++) {
@ -470,7 +470,7 @@ static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res d,
osd_rescale_bitmaps(res, w, h, d, video_par); osd_rescale_bitmaps(res, w, h, d, video_par);
if (opts->sub_scale != 1.0 && opts->ass_style_override) { if (opts->sub_scale != 1.0 && shared_opts->ass_style_override[0]) {
for (int n = 0; n < res->num_parts; n++) { for (int n = 0; n < res->num_parts; n++) {
struct sub_bitmap *sub = &res->parts[n]; struct sub_bitmap *sub = &res->parts[n];