From 77a04c375eb66bb60990a35a93cb43c6d5f4c27c Mon Sep 17 00:00:00 2001 From: karelrooted Date: Mon, 11 Dec 2023 17:43:36 +0800 Subject: [PATCH] options: add --secondary-sub-pos Closes #3022 . The default value is 0 (on the top of the screen) --- DOCS/man/options.rst | 8 ++++++-- options/options.c | 3 +++ options/options.h | 1 + player/command.c | 14 ++++++++++++++ player/sub.c | 1 - sub/dec_sub.c | 3 +-- sub/sd.h | 2 +- sub/sd_ass.c | 10 +++++----- sub/sd_lavc.c | 2 +- 9 files changed, 32 insertions(+), 12 deletions(-) diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index dc9c568fa3bba..c2536e23341df 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -2338,8 +2338,8 @@ Subtitles ``--secondary-sid=`` Select a secondary subtitle stream. This is similar to ``--sid``. If a secondary subtitle is selected, it will be rendered as toptitle (i.e. on - the top of the screen) alongside the normal subtitle, and provides a way - to render two subtitles at once. + the top of the screen) alongside the normal subtitle by default, and + provides a way to render two subtitles at once. There are some caveats associated with this feature. For example, bitmap subtitles will always be rendered in their usual position, so selecting a @@ -2416,6 +2416,10 @@ Subtitles Using ``--sub-margin-y`` can achieve this in a better way. +``--secondary-sub-pos=<0-150>`` + Specify the position of secondary subtitles on the screen. This is similar + to ``--sub-pos`` but for secondary subtitles. + ``--sub-speed=<0.1-10.0>`` Multiply the subtitle event timestamps with the given value. Can be used to fix the playback speed for frame-based subtitle formats. Affects text diff --git a/options/options.c b/options/options.c index 41cfce7fc0952..8fb566c6f6728 100644 --- a/options/options.c +++ b/options/options.c @@ -296,6 +296,7 @@ const struct m_sub_options mp_subtitle_sub_opts = { {"sub-fix-timing", OPT_BOOL(sub_fix_timing)}, {"sub-stretch-durations", OPT_BOOL(sub_stretch_durations)}, {"sub-pos", OPT_FLOAT(sub_pos), M_RANGE(0.0, 150.0)}, + {"secondary-sub-pos", OPT_FLOAT(sec_sub_pos), M_RANGE(0.0, 150.0)}, {"sub-gauss", OPT_FLOAT(sub_gauss), M_RANGE(0.0, 3.0)}, {"sub-gray", OPT_BOOL(sub_gray)}, {"sub-ass", OPT_BOOL(ass_enabled), .flags = UPDATE_SUB_HARD}, @@ -336,6 +337,7 @@ const struct m_sub_options mp_subtitle_sub_opts = { .sub_visibility = true, .sec_sub_visibility = true, .sub_pos = 100, + .sec_sub_pos = 0, .sub_speed = 1.0, .ass_enabled = true, .sub_scale_by_window = true, @@ -1068,6 +1070,7 @@ static const struct MPOpts mp_default_opts = { "sub-delay", "sub-speed", "sub-pos", + "secondary-sub-pos", "sub-visibility", "sub-scale", "sub-use-margins", diff --git a/options/options.h b/options/options.h index f1940266ca2a4..c0ffd2c3259dc 100644 --- a/options/options.h +++ b/options/options.h @@ -85,6 +85,7 @@ struct mp_subtitle_opts { bool sub_visibility; bool sec_sub_visibility; float sub_pos; + float sec_sub_pos; float sub_delay[2]; float sub_fps; float sub_speed; diff --git a/player/command.c b/player/command.c index 13de780a4dc68..ea78328c772ff 100644 --- a/player/command.c +++ b/player/command.c @@ -2910,6 +2910,18 @@ static int mp_property_sub_pos(void *ctx, struct m_property *prop, return mp_property_generic_option(mpctx, prop, action, arg); } +static int mp_property_secondary_sub_pos(void *ctx, struct m_property *prop, + int action, void *arg) +{ + MPContext *mpctx = ctx; + struct MPOpts *opts = mpctx->opts; + if (action == M_PROPERTY_PRINT) { + *(char **)arg = talloc_asprintf(NULL, "%4.2f%%/100", opts->subs_rend->sec_sub_pos); + return M_PROPERTY_OK; + } + return mp_property_generic_option(mpctx, prop, action, arg); +} + static int mp_property_sub_ass_extradata(void *ctx, struct m_property *prop, int action, void *arg) { @@ -3936,6 +3948,7 @@ static const struct m_property mp_properties_base[] = { .priv = (void *)&(const int){1}}, {"sub-speed", mp_property_sub_speed}, {"sub-pos", mp_property_sub_pos}, + {"secondary-sub-pos", mp_property_secondary_sub_pos}, {"sub-ass-extradata", mp_property_sub_ass_extradata}, {"sub-text", mp_property_sub_text, .priv = (void *)&(const int){SD_TEXT_TYPE_PLAIN}}, @@ -4249,6 +4262,7 @@ static const struct property_osd_display { {"sub", "Subtitles"}, {"secondary-sid", "Secondary subtitles"}, {"sub-pos", "Sub position"}, + {"secondary-sub-pos", "Secondary sub position"}, {"sub-delay", "Sub delay"}, {"secondary-sub-delay", "Secondary sub delay"}, {"sub-speed", "Sub speed"}, diff --git a/player/sub.c b/player/sub.c index f3e42fe13b41b..6422d0ae9d5c4 100644 --- a/player/sub.c +++ b/player/sub.c @@ -199,7 +199,6 @@ void reinit_sub(struct MPContext *mpctx, struct track *track) sub_select(track->d_sub, true); int order = get_order(mpctx, track); osd_set_sub(mpctx->osd, order, track->d_sub); - sub_control(track->d_sub, SD_CTRL_SET_TOP, &order); // When paused we have to wait for packets to be available. // So just retry until we get a packet in this case. diff --git a/sub/dec_sub.c b/sub/dec_sub.c index 195a14abea0dd..4cb2d9bb67237 100644 --- a/sub/dec_sub.c +++ b/sub/dec_sub.c @@ -213,7 +213,6 @@ static void update_segment(struct dec_sub *sub) talloc_free(sub->sd); sub->sd = new; update_subtitle_speed(sub); - sub_control(sub, SD_CTRL_SET_TOP, &sub->order); } else { // We'll just keep the current decoder, and feed it possibly // invalid data (not our fault if it crashes or something). @@ -364,7 +363,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) && sub->sd->driver->get_bitmaps) - res = sub->sd->driver->get_bitmaps(sub->sd, dim, format, pts); + res = sub->sd->driver->get_bitmaps(sub->sd, dim, format, pts, sub->order); mp_mutex_unlock(&sub->lock); return res; diff --git a/sub/sd.h b/sub/sd.h index 11a90fe2a8f57..969d1dcacaf65 100644 --- a/sub/sd.h +++ b/sub/sd.h @@ -41,7 +41,7 @@ struct sd_functions { int (*control)(struct sd *sd, enum sd_ctrl cmd, void *arg); struct sub_bitmaps *(*get_bitmaps)(struct sd *sd, struct mp_osd_res dim, - int format, double pts); + int format, double pts, int order); char *(*get_text)(struct sd *sd, double pts, enum sd_text_type type); struct sd_times (*get_times)(struct sd *sd, double pts); }; diff --git a/sub/sd_ass.c b/sub/sd_ass.c index 6742f6f658fdd..6c40534e36607 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -379,7 +379,7 @@ static void decode(struct sd *sd, struct demux_packet *packet) } static void configure_ass(struct sd *sd, struct mp_osd_res *dim, - bool converted, ASS_Track *track) + bool converted, ASS_Track *track, int order) { struct mp_subtitle_opts *opts = sd->opts; struct sd_ass_priv *ctx = sd->priv; @@ -407,7 +407,7 @@ static void configure_ass(struct sd *sd, struct mp_osd_res *dim, set_use_margins = opts->ass_use_margins; } if (converted || opts->ass_style_override) { - set_sub_pos = 100.0f - opts->sub_pos; + set_sub_pos = 100.0f - (order == 1 ? opts->sec_sub_pos : opts->sub_pos); set_line_spacing = opts->ass_line_spacing; set_hinting = opts->ass_hinting; set_font_scale = opts->sub_scale; @@ -557,12 +557,12 @@ static long long find_timestamp(struct sd *sd, double pts) #undef END static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res dim, - int format, double pts) + int format, double pts, int order) { struct sd_ass_priv *ctx = sd->priv; struct mp_subtitle_opts *opts = sd->opts; bool no_ass = !opts->ass_enabled || ctx->on_top || - opts->ass_style_override == 5; + opts->ass_style_override == 5 || order == 1; bool converted = ctx->is_converted || no_ass; ASS_Track *track = no_ass ? ctx->shadow_track : ctx->ass_track; ASS_Renderer *renderer = ctx->ass_renderer; @@ -591,7 +591,7 @@ static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res dim, scale *= par; } if (!ctx->ass_configured || !osd_res_equals(old_osd, ctx->osd)) { - configure_ass(sd, &dim, converted, track); + configure_ass(sd, &dim, converted, track, order); ctx->ass_configured = true; } ass_set_pixel_aspect(renderer, scale); diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c index 30aa64143785a..5bf887dad06c0 100644 --- a/sub/sd_lavc.c +++ b/sub/sd_lavc.c @@ -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, - int format, double pts) + int format, double pts, int order) { struct sd_lavc_priv *priv = sd->priv; struct mp_subtitle_opts *opts = sd->opts;