mirror of
https://github.com/mpv-player/mpv
synced 2024-12-19 13:21:13 +00:00
options: add --secondary-sub-pos
The default value is 0 (on the top of the screen)
This commit is contained in:
parent
b690531f30
commit
3250f6e447
@ -2338,8 +2338,8 @@ Subtitles
|
||||
``--secondary-sid=<ID|auto|no>``
|
||||
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
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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"},
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -17,7 +17,6 @@ struct sd;
|
||||
enum sd_ctrl {
|
||||
SD_CTRL_SUB_STEP,
|
||||
SD_CTRL_SET_VIDEO_PARAMS,
|
||||
SD_CTRL_SET_TOP,
|
||||
SD_CTRL_SET_VIDEO_DEF_FPS,
|
||||
SD_CTRL_UPDATE_OPTS,
|
||||
};
|
||||
|
2
sub/sd.h
2
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);
|
||||
};
|
||||
|
13
sub/sd_ass.c
13
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);
|
||||
@ -852,9 +852,6 @@ static int control(struct sd *sd, enum sd_ctrl cmd, void *arg)
|
||||
case SD_CTRL_SET_VIDEO_PARAMS:
|
||||
ctx->video_params = *(struct mp_image_params *)arg;
|
||||
return CONTROL_OK;
|
||||
case SD_CTRL_SET_TOP:
|
||||
ctx->on_top = *(bool *)arg;
|
||||
return CONTROL_OK;
|
||||
case SD_CTRL_UPDATE_OPTS: {
|
||||
int flags = (uintptr_t)arg;
|
||||
if (flags & UPDATE_SUB_FILT) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user