summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--options/m_config.c14
-rw-r--r--options/m_config.h4
-rw-r--r--options/options.c171
-rw-r--r--options/options.h99
-rw-r--r--player/command.c16
-rw-r--r--player/misc.c2
-rw-r--r--sub/ass_mp.c1
-rw-r--r--sub/dec_sub.c28
-rw-r--r--sub/dec_sub.h2
-rw-r--r--sub/osd.c10
-rw-r--r--sub/osd_libass.c4
-rw-r--r--sub/osd_state.h3
-rw-r--r--sub/sd.h2
-rw-r--r--sub/sd_ass.c13
-rw-r--r--sub/sd_lavc.c6
15 files changed, 222 insertions, 153 deletions
diff --git a/options/m_config.c b/options/m_config.c
index 6f22fd50c5..8bf7e0ef91 100644
--- a/options/m_config.c
+++ b/options/m_config.c
@@ -1340,6 +1340,20 @@ void m_config_notify_change_co(struct m_config *config,
}
}
+void m_config_notify_change_opt_ptr(struct m_config *config, void *ptr)
+{
+ for (int n = 0; n < config->num_opts; n++) {
+ struct m_config_option *co = &config->opts[n];
+ if (co->data == ptr) {
+ m_config_notify_change_co(config, co);
+ return;
+ }
+ }
+ // ptr doesn't point to any config->optstruct field declared in the
+ // option list?
+ assert(false);
+}
+
void m_config_cache_set_wakeup_cb(struct m_config_cache *cache,
void (*cb)(void *ctx), void *cb_ctx)
{
diff --git a/options/m_config.h b/options/m_config.h
index fc32ca5bf0..6c4e9b759f 100644
--- a/options/m_config.h
+++ b/options/m_config.h
@@ -201,6 +201,10 @@ int m_config_option_requires_param(struct m_config *config, bstr name);
// Notify m_config_cache users that the option has (probably) changed its value.
void m_config_notify_change_co(struct m_config *config,
struct m_config_option *co);
+// Like m_config_notify_change_co(), but automatically find the option by its
+// pointer within the global option struct (config->optstruct). In practice,
+// it means it works only on fields in MPContext.opts.
+void m_config_notify_change_opt_ptr(struct m_config *config, void *ptr);
bool m_config_is_in_group(struct m_config *config,
const struct m_sub_options *group,
diff --git a/options/options.c b/options/options.c
index 5eb2cb525b..4e40d77a90 100644
--- a/options/options.c
+++ b/options/options.c
@@ -184,6 +184,101 @@ const struct m_sub_options vo_sub_opts = {
};
#undef OPT_BASE_STRUCT
+#define OPT_BASE_STRUCT struct mp_subtitle_opts
+
+const struct m_sub_options mp_subtitle_sub_opts = {
+ .opts = (const struct m_option[]){
+ OPT_FLOAT("sub-delay", sub_delay, 0),
+ OPT_FLOAT("sub-fps", sub_fps, 0),
+ OPT_FLOAT("sub-speed", sub_speed, 0),
+ OPT_FLAG("sub-visibility", sub_visibility, 0),
+ OPT_FLAG("sub-forced-only", forced_subs_only, 0),
+ OPT_FLAG("stretch-dvd-subs", stretch_dvd_subs, 0),
+ OPT_FLAG("stretch-image-subs-to-screen", stretch_image_subs, 0),
+ OPT_FLAG("image-subs-video-resolution", image_subs_video_res, 0),
+ OPT_FLAG("sub-fix-timing", sub_fix_timing, 0),
+ OPT_INTRANGE("sub-pos", sub_pos, 0, 0, 100),
+ OPT_FLOATRANGE("sub-gauss", sub_gauss, 0, 0.0, 3.0),
+ OPT_FLAG("sub-gray", sub_gray, 0),
+ OPT_FLAG("sub-ass", ass_enabled, 0),
+ OPT_FLAG("sub-filter-sdh", sub_filter_SDH, 0),
+ OPT_FLAG("sub-filter-sdh-harder", sub_filter_SDH_harder, 0),
+ OPT_FLOATRANGE("sub-scale", sub_scale, 0, 0, 100),
+ OPT_FLOATRANGE("sub-ass-line-spacing", ass_line_spacing, 0, -1000, 1000),
+ OPT_FLAG("sub-use-margins", sub_use_margins, 0),
+ OPT_FLAG("sub-ass-force-margins", ass_use_margins, 0),
+ OPT_FLAG("sub-ass-vsfilter-aspect-compat", ass_vsfilter_aspect_compat, 0),
+ OPT_CHOICE("sub-ass-vsfilter-color-compat", ass_vsfilter_color_compat, 0,
+ ({"no", 0}, {"basic", 1}, {"full", 2}, {"force-601", 3})),
+ OPT_FLAG("sub-ass-vsfilter-blur-compat", ass_vsfilter_blur_compat, 0),
+ OPT_FLAG("embeddedfonts", use_embedded_fonts, 0),
+ OPT_STRINGLIST("sub-ass-force-style", ass_force_style_list, 0),
+ OPT_STRING("sub-ass-styles", ass_styles_file, M_OPT_FILE),
+ OPT_CHOICE("sub-ass-hinting", ass_hinting, 0,
+ ({"none", 0}, {"light", 1}, {"normal", 2}, {"native", 3})),
+ OPT_CHOICE("sub-ass-shaper", ass_shaper, 0,
+ ({"simple", 0}, {"complex", 1})),
+ OPT_FLAG("sub-ass-justify", ass_justify, 0),
+ OPT_CHOICE("sub-ass-override", ass_style_override, 0,
+ ({"no", 0}, {"yes", 1}, {"force", 3}, {"scale", 4}, {"strip", 5})),
+ OPT_FLAG("sub-scale-by-window", sub_scale_by_window, 0),
+ OPT_FLAG("sub-scale-with-window", sub_scale_with_window, 0),
+ OPT_FLAG("sub-ass-scale-with-window", ass_scale_with_window, 0),
+ OPT_SUBSTRUCT("sub", sub_style, sub_style_conf, 0),
+ OPT_FLAG("sub-clear-on-seek", sub_clear_on_seek, 0),
+ OPT_INTRANGE("teletext-page", teletext_page, 0, 1, 999),
+ {0}
+ },
+ .size = sizeof(OPT_BASE_STRUCT),
+ .defaults = &(OPT_BASE_STRUCT){
+ .sub_visibility = 1,
+ .sub_pos = 100,
+ .sub_speed = 1.0,
+ .ass_enabled = 1,
+ .sub_scale_by_window = 1,
+ .ass_use_margins = 0,
+ .sub_use_margins = 1,
+ .ass_scale_with_window = 0,
+ .sub_scale_with_window = 1,
+ .teletext_page = 100,
+ .sub_scale = 1,
+ .ass_vsfilter_aspect_compat = 1,
+ .ass_vsfilter_color_compat = 1,
+ .ass_vsfilter_blur_compat = 1,
+ .ass_style_override = 1,
+ .ass_shaper = 1,
+ .use_embedded_fonts = 1,
+ },
+ .change_flags = UPDATE_OSD,
+};
+
+#undef OPT_BASE_STRUCT
+#define OPT_BASE_STRUCT struct mp_osd_render_opts
+
+const struct m_sub_options mp_osd_render_sub_opts = {
+ .opts = (const struct m_option[]){
+ OPT_FLOATRANGE("osd-bar-align-x", osd_bar_align_x, 0, -1.0, +1.0),
+ OPT_FLOATRANGE("osd-bar-align-y", osd_bar_align_y, 0, -1.0, +1.0),
+ OPT_FLOATRANGE("osd-bar-w", osd_bar_w, 0, 1, 100),
+ OPT_FLOATRANGE("osd-bar-h", osd_bar_h, 0, 0.1, 50),
+ OPT_SUBSTRUCT("osd", osd_style, osd_style_conf, 0),
+ OPT_FLOATRANGE("osd-scale", osd_scale, 0, 0, 100),
+ OPT_FLAG("osd-scale-by-window", osd_scale_by_window, 0),
+ OPT_FLAG("force-rgba-osd-rendering", force_rgba_osd, 0),
+ {0}
+ },
+ .size = sizeof(OPT_BASE_STRUCT),
+ .defaults = &(OPT_BASE_STRUCT){
+ .osd_bar_align_y = 0.5,
+ .osd_bar_w = 75.0,
+ .osd_bar_h = 3.125,
+ .osd_scale = 1,
+ .osd_scale_by_window = 1,
+ },
+ .change_flags = UPDATE_OSD,
+};
+
+#undef OPT_BASE_STRUCT
#define OPT_BASE_STRUCT struct dvd_opts
const struct m_sub_options dvd_conf = {
@@ -429,55 +524,15 @@ const m_option_t mp_opts[] = {
OPT_PATHLIST("external-files", external_files, 0),
OPT_CLI_ALIAS("external-file", "external-files-append"),
OPT_FLAG("autoload-files", autoload_files, 0),
- OPT_FLOAT("sub-delay", sub_delay, UPDATE_OSD),
- OPT_FLOAT("sub-fps", sub_fps, UPDATE_OSD),
- OPT_FLOAT("sub-speed", sub_speed, UPDATE_OSD),
- OPT_FLAG("sub-visibility", sub_visibility, UPDATE_OSD),
- OPT_FLAG("sub-forced-only", forced_subs_only, UPDATE_OSD),
- OPT_FLAG("stretch-dvd-subs", stretch_dvd_subs, UPDATE_OSD),
- OPT_FLAG("stretch-image-subs-to-screen", stretch_image_subs, UPDATE_OSD),
- OPT_FLAG("image-subs-video-resolution", image_subs_video_res, UPDATE_OSD),
- OPT_FLAG("sub-fix-timing", sub_fix_timing, 0),
OPT_CHOICE("sub-auto", sub_auto, 0,
({"no", -1}, {"exact", 0}, {"fuzzy", 1}, {"all", 2})),
OPT_CHOICE("audio-file-auto", audiofile_auto, 0,
({"no", -1}, {"exact", 0}, {"fuzzy", 1}, {"all", 2})),
- OPT_INTRANGE("sub-pos", sub_pos, UPDATE_OSD, 0, 100),
- OPT_FLOATRANGE("sub-gauss", sub_gauss, UPDATE_OSD, 0.0, 3.0),
- OPT_FLAG("sub-gray", sub_gray, UPDATE_OSD),
- OPT_FLAG("sub-ass", ass_enabled, 0),
- OPT_FLAG("sub-filter-sdh", sub_filter_SDH, 0),
- OPT_FLAG("sub-filter-sdh-harder", sub_filter_SDH_harder, 0),
- OPT_FLOATRANGE("sub-scale", sub_scale, UPDATE_OSD, 0, 100),
- OPT_FLOATRANGE("sub-ass-line-spacing", ass_line_spacing, UPDATE_OSD, -1000, 1000),
- OPT_FLAG("sub-use-margins", sub_use_margins, UPDATE_OSD),
- OPT_FLAG("sub-ass-force-margins", ass_use_margins, UPDATE_OSD),
- OPT_FLAG("sub-ass-vsfilter-aspect-compat", ass_vsfilter_aspect_compat, UPDATE_OSD),
- OPT_CHOICE("sub-ass-vsfilter-color-compat", ass_vsfilter_color_compat, UPDATE_OSD,
- ({"no", 0}, {"basic", 1}, {"full", 2}, {"force-601", 3})),
- OPT_FLAG("sub-ass-vsfilter-blur-compat", ass_vsfilter_blur_compat, UPDATE_OSD),
- OPT_FLAG("embeddedfonts", use_embedded_fonts, 0),
- OPT_STRINGLIST("sub-ass-force-style", ass_force_style_list, UPDATE_OSD),
- OPT_STRING("sub-ass-styles", ass_styles_file, M_OPT_FILE),
- OPT_CHOICE("sub-ass-hinting", ass_hinting, UPDATE_OSD,
- ({"none", 0}, {"light", 1}, {"normal", 2}, {"native", 3})),
- OPT_CHOICE("sub-ass-shaper", ass_shaper, UPDATE_OSD,
- ({"simple", 0}, {"complex", 1})),
- OPT_FLAG("sub-ass-justify", ass_justify, 0),
- OPT_CHOICE("sub-ass-override", ass_style_override, UPDATE_OSD,
- ({"no", 0}, {"yes", 1}, {"force", 3}, {"scale", 4}, {"strip", 5})),
- OPT_FLAG("sub-scale-by-window", sub_scale_by_window, UPDATE_OSD),
- OPT_FLAG("sub-scale-with-window", sub_scale_with_window, UPDATE_OSD),
- OPT_FLAG("sub-ass-scale-with-window", ass_scale_with_window, UPDATE_OSD),
+
+ OPT_SUBSTRUCT("", subs_rend, mp_subtitle_sub_opts, 0),
+ OPT_SUBSTRUCT("", osd_rend, mp_osd_render_sub_opts, 0),
+
OPT_FLAG("osd-bar", osd_bar_visible, UPDATE_OSD),
- OPT_FLOATRANGE("osd-bar-align-x", osd_bar_align_x, UPDATE_OSD, -1.0, +1.0),
- OPT_FLOATRANGE("osd-bar-align-y", osd_bar_align_y, UPDATE_OSD, -1.0, +1.0),
- OPT_FLOATRANGE("osd-bar-w", osd_bar_w, UPDATE_OSD, 1, 100),
- OPT_FLOATRANGE("osd-bar-h", osd_bar_h, UPDATE_OSD, 0.1, 50),
- OPT_SUBSTRUCT("osd", osd_style, osd_style_conf, 0),
- OPT_SUBSTRUCT("sub", sub_style, sub_style_conf, 0),
- OPT_FLAG("sub-clear-on-seek", sub_clear_on_seek, 0),
- OPT_INTRANGE("teletext-page", teletext_page, 0, 1, 999),
//---------------------- libao/libvo options ------------------------
OPT_SETTINGSLIST("ao", audio_driver_list, 0, &ao_obj_list, ),
@@ -513,8 +568,6 @@ const m_option_t mp_opts[] = {
OPT_STRING("title", wintitle, 0),
OPT_STRING("force-media-title", media_title, 0),
- // set aspect ratio of monitor - useful for 16:9 TV-out
- OPT_FLAG("force-rgba-osd-rendering", force_rgba_osd, 0),
OPT_CHOICE_OR_INT("video-rotate", video_rotate, UPDATE_IMGPAR, 0, 359,
({"no", -1})),
OPT_CHOICE_C("video-stereo-mode", video_stereo_mode, UPDATE_IMGPAR,
@@ -533,8 +586,6 @@ const m_option_t mp_opts[] = {
({"0", 0}, {"1", 1}, {"2", 2}, {"3", 3})),
OPT_INTRANGE("osd-duration", osd_duration, 0, 0, 3600000),
OPT_FLAG("osd-fractions", osd_fractions, 0),
- OPT_FLOATRANGE("osd-scale", osd_scale, UPDATE_OSD, 0, 100),
- OPT_FLAG("osd-scale-by-window", osd_scale_by_window, 0),
OPT_DOUBLE("sstep", step_sec, CONF_MIN, 0),
@@ -821,17 +872,6 @@ const struct MPOpts mp_default_opts = {
.video_osd = 1,
.osd_level = 1,
.osd_duration = 1000,
- .osd_bar_align_y = 0.5,
- .osd_bar_w = 75.0,
- .osd_bar_h = 3.125,
- .osd_scale = 1,
- .osd_scale_by_window = 1,
- .sub_scale_by_window = 1,
- .ass_use_margins = 0,
- .sub_use_margins = 1,
- .ass_scale_with_window = 0,
- .sub_scale_with_window = 1,
- .teletext_page = 100,
#if HAVE_LUA
.lua_load_osc = 1,
.lua_load_ytdl = 1,
@@ -878,9 +918,6 @@ const struct MPOpts mp_default_opts = {
[STREAM_SUB] = -2, }, },
.stream_auto_sel = 1,
.audio_display = 1,
- .sub_visibility = 1,
- .sub_pos = 100,
- .sub_speed = 1.0,
.audio_output_format = 0, // AF_FORMAT_UNKNOWN
.playback_speed = 1.,
.pitch_correction = 1,
@@ -889,16 +926,6 @@ const struct MPOpts mp_default_opts = {
.sub_auto = 0,
.audiofile_auto = -1,
.osd_bar_visible = 1,
-#if HAVE_LIBASS
- .ass_enabled = 1,
-#endif
- .sub_scale = 1,
- .ass_vsfilter_aspect_compat = 1,
- .ass_vsfilter_color_compat = 1,
- .ass_vsfilter_blur_compat = 1,
- .ass_style_override = 1,
- .ass_shaper = 1,
- .use_embedded_fonts = 1,
.screenshot_template = "mpv-shot%n",
.hwdec_api = HAVE_RPI ? "mmal" : "no",
diff --git a/options/options.h b/options/options.h
index 211284ff75..3f90a2b78f 100644
--- a/options/options.h
+++ b/options/options.h
@@ -66,6 +66,56 @@ struct mp_cache_opts {
int file_max;
};
+// Subtitle options needed by the subtitle decoders/renderers.
+struct mp_subtitle_opts {
+ int sub_visibility;
+ int sub_pos;
+ float sub_delay;
+ float sub_fps;
+ float sub_speed;
+ int forced_subs_only;
+ int stretch_dvd_subs;
+ int stretch_image_subs;
+ int image_subs_video_res;
+ int sub_fix_timing;
+ int sub_scale_by_window;
+ int sub_scale_with_window;
+ int ass_scale_with_window;
+ struct osd_style_opts *sub_style;
+ float sub_scale;
+ float sub_gauss;
+ int sub_gray;
+ int sub_filter_SDH;
+ int sub_filter_SDH_harder;
+ int ass_enabled;
+ float ass_line_spacing;
+ int ass_use_margins;
+ int sub_use_margins;
+ int ass_vsfilter_aspect_compat;
+ int ass_vsfilter_color_compat;
+ int ass_vsfilter_blur_compat;
+ int use_embedded_fonts;
+ char **ass_force_style_list;
+ char *ass_styles_file;
+ int ass_style_override;
+ int ass_hinting;
+ int ass_shaper;
+ int ass_justify;
+ int sub_clear_on_seek;
+ int teletext_page;
+};
+
+struct mp_osd_render_opts {
+ float osd_bar_align_x;
+ float osd_bar_align_y;
+ float osd_bar_w;
+ float osd_bar_h;
+ float osd_scale;
+ int osd_scale_by_window;
+ struct osd_style_opts *osd_style;
+ int force_rgba_osd;
+};
+
typedef struct MPOpts {
int property_print_help;
int use_terminal;
@@ -113,7 +163,6 @@ typedef struct MPOpts {
char *wintitle;
char *media_title;
- int force_rgba_osd;
struct mp_csp_equalizer_opts *video_equalizer;
@@ -128,6 +177,9 @@ typedef struct MPOpts {
char *video_decoders;
char *audio_spdif;
+ struct mp_subtitle_opts *subs_rend;
+ struct mp_osd_render_opts *osd_rend;
+
int osd_level;
int osd_duration;
int osd_fractions;
@@ -202,17 +254,6 @@ typedef struct MPOpts {
int stream_auto_sel;
int audio_display;
char **display_tags;
- int sub_visibility;
- int sub_pos;
- float sub_delay;
- float sub_fps;
- float sub_speed;
- int forced_subs_only;
- int stretch_dvd_subs;
- int stretch_image_subs;
- int image_subs_video_res;
-
- int sub_fix_timing;
char **audio_files;
char *demuxer_name;
@@ -249,38 +290,6 @@ typedef struct MPOpts {
int sub_auto;
int audiofile_auto;
int osd_bar_visible;
- float osd_bar_align_x;
- float osd_bar_align_y;
- float osd_bar_w;
- float osd_bar_h;
- float osd_scale;
- int osd_scale_by_window;
- int sub_scale_by_window;
- int sub_scale_with_window;
- int ass_scale_with_window;
- struct osd_style_opts *osd_style;
- struct osd_style_opts *sub_style;
- float sub_scale;
- float sub_gauss;
- int sub_gray;
- int sub_filter_SDH;
- int sub_filter_SDH_harder;
- int ass_enabled;
- float ass_line_spacing;
- int ass_use_margins;
- int sub_use_margins;
- int ass_vsfilter_aspect_compat;
- int ass_vsfilter_color_compat;
- int ass_vsfilter_blur_compat;
- int use_embedded_fonts;
- char **ass_force_style_list;
- char *ass_styles_file;
- int ass_style_override;
- int ass_hinting;
- int ass_shaper;
- int ass_justify;
- int sub_clear_on_seek;
- int teletext_page;
char *hwdec_api;
char *hwdec_codecs;
@@ -345,6 +354,8 @@ extern const struct MPOpts mp_default_opts;
extern const struct m_sub_options vo_sub_opts;
extern const struct m_sub_options stream_cache_conf;
extern const struct m_sub_options dvd_conf;
+extern const struct m_sub_options mp_subtitle_sub_opts;
+extern const struct m_sub_options mp_osd_render_sub_opts;
int hwdec_validate_opt(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param);
diff --git a/player/command.c b/player/command.c
index 61d47a2319..48206f527d 100644
--- a/player/command.c
+++ b/player/command.c
@@ -3040,7 +3040,7 @@ static int mp_property_sub_delay(void *ctx, struct m_property *prop,
struct MPOpts *opts = mpctx->opts;
switch (action) {
case M_PROPERTY_PRINT:
- *(char **)arg = format_delay(opts->sub_delay);
+ *(char **)arg = format_delay(opts->subs_rend->sub_delay);
return M_PROPERTY_OK;
}
return mp_property_generic_option(mpctx, prop, action, arg);
@@ -3053,7 +3053,8 @@ static int mp_property_sub_speed(void *ctx, struct m_property *prop,
MPContext *mpctx = ctx;
struct MPOpts *opts = mpctx->opts;
if (action == M_PROPERTY_PRINT) {
- *(char **)arg = talloc_asprintf(NULL, "%4.1f%%", 100 * opts->sub_speed);
+ *(char **)arg =
+ talloc_asprintf(NULL, "%4.1f%%", 100 * opts->subs_rend->sub_speed);
return M_PROPERTY_OK;
}
return mp_property_generic_option(mpctx, prop, action, arg);
@@ -3065,7 +3066,7 @@ static int mp_property_sub_pos(void *ctx, struct m_property *prop,
MPContext *mpctx = ctx;
struct MPOpts *opts = mpctx->opts;
if (action == M_PROPERTY_PRINT) {
- *(char **)arg = talloc_asprintf(NULL, "%d/100", opts->sub_pos);
+ *(char **)arg = talloc_asprintf(NULL, "%d/100", opts->subs_rend->sub_pos);
return M_PROPERTY_OK;
}
return mp_property_generic_option(mpctx, prop, action, arg);
@@ -5080,8 +5081,9 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re
a[1] = cmd->args[0].v.i;
if (sub_control(sub, SD_CTRL_SUB_STEP, a) > 0) {
if (cmd->id == MP_CMD_SUB_STEP) {
- opts->sub_delay -= a[0] - refpts;
- osd_changed(mpctx->osd);
+ opts->subs_rend->sub_delay -= a[0] - refpts;
+ m_config_notify_change_opt_ptr(mpctx->mconfig,
+ &opts->subs_rend->sub_delay);
show_property_osd(mpctx, "sub-delay", on_osd);
} else {
// We can easily get stuck by failing to seek to the video
@@ -5765,13 +5767,13 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags)
recreate_auto_filters(mpctx);
if (flags & UPDATE_OSD) {
- osd_changed(mpctx->osd);
for (int n = 0; n < NUM_PTRACKS; n++) {
struct track *track = mpctx->current_track[n][STREAM_SUB];
struct dec_sub *sub = track ? track->d_sub : NULL;
if (sub)
- sub_control(track->d_sub, SD_CTRL_UPDATE_SPEED, NULL);
+ sub_update_opts(track->d_sub);
}
+ osd_changed(mpctx->osd);
mp_wakeup_core(mpctx);
}
diff --git a/player/misc.c b/player/misc.c
index 0284479f49..88767ce2d0 100644
--- a/player/misc.c
+++ b/player/misc.c
@@ -182,7 +182,7 @@ double get_track_seek_offset(struct MPContext *mpctx, struct track *track)
if (track->type == STREAM_AUDIO)
return -opts->audio_delay;
if (track->type == STREAM_SUB)
- return -opts->sub_delay;
+ return -opts->subs_rend->sub_delay;
}
return 0;
}
diff --git a/sub/ass_mp.c b/sub/ass_mp.c
index 03cc55780a..34e05a230c 100644
--- a/sub/ass_mp.c
+++ b/sub/ass_mp.c
@@ -134,7 +134,6 @@ ASS_Library *mp_ass_init(struct mpv_global *global, struct mp_log *log)
ass_set_message_cb(priv, message_callback, log);
if (path)
ass_set_fonts_dir(priv, path);
- ass_set_extract_fonts(priv, global->opts->use_embedded_fonts);
talloc_free(path);
return priv;
}
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index b9fdc7adb9..99acab33f2 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -26,6 +26,7 @@
#include "demux/demux.h"
#include "sd.h"
#include "dec_sub.h"
+#include "options/m_config.h"
#include "options/options.h"
#include "common/global.h"
#include "common/msg.h"
@@ -48,7 +49,8 @@ struct dec_sub {
struct mp_log *log;
struct mpv_global *global;
- struct MPOpts *opts;
+ struct mp_subtitle_opts *opts;
+ struct m_config_cache *opts_cache;
struct mp_recorder_sink *recorder_sink;
@@ -71,7 +73,7 @@ struct dec_sub {
static void update_subtitle_speed(struct dec_sub *sub)
{
- struct MPOpts *opts = sub->opts;
+ struct mp_subtitle_opts *opts = sub->opts;
sub->sub_speed = 1.0;
if (sub->video_fps > 0 && sub->codec->frame_based > 0) {
@@ -89,7 +91,7 @@ static void update_subtitle_speed(struct dec_sub *sub)
// Return the subtitle PTS used for a given video PTS.
static double pts_to_subtitle(struct dec_sub *sub, double pts)
{
- struct MPOpts *opts = sub->opts;
+ struct mp_subtitle_opts *opts = sub->opts;
if (pts != MP_NOPTS_VALUE)
pts = (pts - opts->sub_delay) / sub->sub_speed;
@@ -99,7 +101,7 @@ static double pts_to_subtitle(struct dec_sub *sub, double pts)
static double pts_from_subtitle(struct dec_sub *sub, double pts)
{
- struct MPOpts *opts = sub->opts;
+ struct mp_subtitle_opts *opts = sub->opts;
if (pts != MP_NOPTS_VALUE)
pts = pts * sub->sub_speed + opts->sub_delay;
@@ -168,7 +170,7 @@ struct dec_sub *sub_create(struct mpv_global *global, struct sh_stream *sh,
*sub = (struct dec_sub){
.log = mp_log_new(sub, global->log, "sub"),
.global = global,
- .opts = global->opts,
+ .opts_cache = m_config_cache_alloc(sub, global, &mp_subtitle_sub_opts),
.sh = sh,
.codec = sh->codec,
.attachments = talloc_steal(sub, attachments),
@@ -177,6 +179,7 @@ struct dec_sub *sub_create(struct mpv_global *global, struct sh_stream *sh,
.start = MP_NOPTS_VALUE,
.end = MP_NOPTS_VALUE,
};
+ sub->opts = sub->opts_cache->opts;
mpthread_mutex_init_recursive(&sub->lock);
sub->sd = init_decoder(sub);
@@ -314,7 +317,7 @@ bool sub_read_packets(struct dec_sub *sub, double video_pts)
void sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, int format,
double pts, struct sub_bitmaps *res)
{
- struct MPOpts *opts = sub->opts;
+ struct mp_subtitle_opts *opts = sub->opts;
pts = pts_to_subtitle(sub, pts);
@@ -334,7 +337,7 @@ void sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, int format,
char *sub_get_text(struct dec_sub *sub, double pts)
{
pthread_mutex_lock(&sub->lock);
- struct MPOpts *opts = sub->opts;
+ struct mp_subtitle_opts *opts = sub->opts;
char *text = NULL;
pts = pts_to_subtitle(sub, pts);
@@ -377,9 +380,6 @@ int sub_control(struct dec_sub *sub, enum sd_ctrl cmd, void *arg)
sub->video_fps = *(double *)arg;
update_subtitle_speed(sub);
break;
- case SD_CTRL_UPDATE_SPEED:
- update_subtitle_speed(sub);
- break;
case SD_CTRL_SUB_STEP: {
double *a = arg;
double arg2[2] = {a[0], a[1]};
@@ -398,6 +398,14 @@ int sub_control(struct dec_sub *sub, enum sd_ctrl cmd, void *arg)
return r;
}
+void sub_update_opts(struct dec_sub *sub)
+{
+ pthread_mutex_lock(&sub->lock);
+ if (m_config_cache_update(sub->opts_cache))
+ update_subtitle_speed(sub);
+ pthread_mutex_unlock(&sub->lock);
+}
+
void sub_set_recorder_sink(struct dec_sub *sub, struct mp_recorder_sink *sink)
{
pthread_mutex_lock(&sub->lock);
diff --git a/sub/dec_sub.h b/sub/dec_sub.h
index 26781fd99f..3303cc9a5c 100644
--- a/sub/dec_sub.h
+++ b/sub/dec_sub.h
@@ -19,7 +19,6 @@ enum sd_ctrl {
SD_CTRL_SET_VIDEO_PARAMS,
SD_CTRL_SET_TOP,
SD_CTRL_SET_VIDEO_DEF_FPS,
- SD_CTRL_UPDATE_SPEED,
};
struct attachment_list {
@@ -41,6 +40,7 @@ void sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, int format,
char *sub_get_text(struct dec_sub *sub, double pts);
void sub_reset(struct dec_sub *sub);
void sub_select(struct dec_sub *sub, bool selected);
+void sub_update_opts(struct dec_sub *sub);
void sub_set_recorder_sink(struct dec_sub *sub, struct mp_recorder_sink *sink);
int sub_control(struct dec_sub *sub, enum sd_ctrl cmd, void *arg);
diff --git a/sub/osd.c b/sub/osd.c
index d2351b7213..eb924db561 100644
--- a/sub/osd.c
+++ b/sub/osd.c
@@ -28,6 +28,7 @@
#include "osdep/timer.h"
#include "mpv_talloc.h"
+#include "options/m_config.h"
#include "options/options.h"
#include "common/global.h"
#include "common/msg.h"
@@ -117,12 +118,13 @@ struct osd_state *osd_create(struct mpv_global *global)
struct osd_state *osd = talloc_zero(NULL, struct osd_state);
*osd = (struct osd_state) {
- .opts = global->opts,
+ .opts_cache = m_config_cache_alloc(osd, global, &mp_osd_render_sub_opts),
.global = global,
.log = mp_log_new(osd, global->log, "osd"),
.force_video_pts = MP_NOPTS_VALUE,
};
pthread_mutex_init(&osd->lock, NULL);
+ osd->opts = osd->opts_cache->opts;
for (int n = 0; n < MAX_OSD_PARTS; n++) {
struct osd_object *obj = talloc(osd, struct osd_object);
@@ -262,10 +264,8 @@ static void render_object(struct osd_state *osd, struct osd_object *obj,
const bool sub_formats[SUBBITMAP_COUNT],
struct sub_bitmaps *out_imgs)
{
- struct MPOpts *opts = osd->opts;
-
int format = SUBBITMAP_LIBASS;
- if (!sub_formats[format] || opts->force_rgba_osd)
+ if (!sub_formats[format] || osd->opts->force_rgba_osd)
format = SUBBITMAP_RGBA;
*out_imgs = (struct sub_bitmaps) {0};
@@ -406,6 +406,8 @@ void osd_changed(struct osd_state *osd)
pthread_mutex_lock(&osd->lock);
osd->objs[OSDTYPE_OSD]->osd_changed = true;
osd->want_redraw_notification = true;
+ // Done here for a lack of a better place.
+ m_config_cache_update(osd->opts_cache);
pthread_mutex_unlock(&osd->lock);
}
diff --git a/sub/osd_libass.c b/sub/osd_libass.c
index 28a16d6204..e51b7f4048 100644
--- a/sub/osd_libass.c
+++ b/sub/osd_libass.c
@@ -234,7 +234,7 @@ static ASS_Event *add_osd_ass_event_escaped(ASS_Track *track, const char *style,
static ASS_Style *prepare_osd_ass(struct osd_state *osd, struct osd_object *obj)
{
- struct MPOpts *opts = osd->opts;
+ struct mp_osd_render_opts *opts = osd->opts;
create_ass_track(osd, obj, &obj->ass);
@@ -349,7 +349,7 @@ static void get_osd_bar_box(struct osd_state *osd, struct osd_object *obj,
float *o_x, float *o_y, float *o_w, float *o_h,
float *o_border)
{
- struct MPOpts *opts = osd->opts;
+ struct mp_osd_render_opts *opts = osd->opts;
create_ass_track(osd, obj, &obj->ass);
ASS_Track *track = obj->ass.track;
diff --git a/sub/osd_state.h b/sub/osd_state.h
index 5cb0f1e07c..ac8befe3ba 100644
--- a/sub/osd_state.h
+++ b/sub/osd_state.h
@@ -73,7 +73,8 @@ struct osd_state {
bool want_redraw;
bool want_redraw_notification;
- struct MPOpts *opts;
+ struct m_config_cache *opts_cache;
+ struct mp_osd_render_opts *opts;
struct mpv_global *global;
struct mp_log *log;
diff --git a/sub/sd.h b/sub/sd.h
index dd1f26d721..8c975959a8 100644
--- a/sub/sd.h
+++ b/sub/sd.h
@@ -12,7 +12,7 @@
struct sd {
struct mpv_global *global;
struct mp_log *log;
- struct MPOpts *opts;
+ struct mp_subtitle_opts *opts;
const struct sd_functions *driver;
void *priv;
diff --git a/sub/sd_ass.c b/sub/sd_ass.c
index 74d500be8d..1cecfe3215 100644
--- a/sub/sd_ass.c
+++ b/sub/sd_ass.c
@@ -59,7 +59,7 @@ static void fill_plaintext(struct sd *sd, double pts);
// Add default styles, if the track does not have any styles yet.
// Apply style overrides if the user provides any.
-static void mp_ass_add_default_styles(ASS_Track *track, struct MPOpts *opts)
+static void mp_ass_add_default_styles(ASS_Track *track, struct mp_subtitle_opts *opts)
{
if (opts->ass_styles_file && opts->ass_style_override)
ass_read_styles(track, opts->ass_styles_file, NULL);
@@ -120,7 +120,7 @@ static bool attachment_is_font(struct mp_log *log, struct demux_attachment *f)
static void add_subtitle_fonts(struct sd *sd)
{
struct sd_ass_priv *ctx = sd->priv;
- struct MPOpts *opts = sd->opts;
+ struct mp_subtitle_opts *opts = sd->opts;
if (!opts->ass_enabled || !opts->use_embedded_fonts || !sd->attachments)
return;
for (int i = 0; i < sd->attachments->num_entries; i++) {
@@ -148,7 +148,7 @@ static void enable_output(struct sd *sd, bool enable)
static int init(struct sd *sd)
{
- struct MPOpts *opts = sd->opts;
+ struct mp_subtitle_opts *opts = sd->opts;
struct sd_ass_priv *ctx = talloc_zero(sd, struct sd_ass_priv);
sd->priv = ctx;
@@ -169,6 +169,7 @@ static int init(struct sd *sd)
}
ctx->ass_library = mp_ass_init(sd->global, sd->log);
+ ass_set_extract_fonts(ctx->ass_library, opts->use_embedded_fonts);
add_subtitle_fonts(sd);
@@ -279,7 +280,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)
{
- struct MPOpts *opts = sd->opts;
+ struct mp_subtitle_opts *opts = sd->opts;
struct sd_ass_priv *ctx = sd->priv;
ASS_Renderer *priv = ctx->ass_renderer;
@@ -428,7 +429,7 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res dim, int format,
double pts, struct sub_bitmaps *res)
{
struct sd_ass_priv *ctx = sd->priv;
- struct MPOpts *opts = sd->opts;
+ struct mp_subtitle_opts *opts = sd->opts;
bool no_ass = !opts->ass_enabled || ctx->on_top ||
opts->ass_style_override == 5;
bool converted = ctx->is_converted || no_ass;
@@ -689,7 +690,7 @@ const struct sd_functions sd_ass = {
// Disgusting hack for (xy-)vsfilter color compatibility.
static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts)
{
- struct MPOpts *opts = sd->opts;
+ struct mp_subtitle_opts *opts = sd->opts;
struct sd_ass_priv *ctx = sd->priv;
enum mp_csp csp = 0;
enum mp_csp_levels levels = 0;
diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c
index 81d8ccfa7d..71df4da36c 100644
--- a/sub/sd_lavc.c
+++ b/sub/sd_lavc.c
@@ -164,7 +164,7 @@ static void convert_pal(uint32_t *colors, size_t count, bool gray)
// Initialize sub from sub->avsub.
static void read_sub_bitmaps(struct sd *sd, struct sub *sub)
{
- struct MPOpts *opts = sd->opts;
+ struct mp_subtitle_opts *opts = sd->opts;
struct sd_lavc_priv *priv = sd->priv;
AVSubtitle *avsub = &sub->avsub;
@@ -288,7 +288,7 @@ static void read_sub_bitmaps(struct sd *sd, struct sub *sub)
static void decode(struct sd *sd, struct demux_packet *packet)
{
- struct MPOpts *opts = sd->opts;
+ struct mp_subtitle_opts *opts = sd->opts;
struct sd_lavc_priv *priv = sd->priv;
AVCodecContext *ctx = priv->avctx;
double pts = packet->pts;
@@ -387,7 +387,7 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res d, int format,
double pts, struct sub_bitmaps *res)
{
struct sd_lavc_priv *priv = sd->priv;
- struct MPOpts *opts = sd->opts;
+ struct mp_subtitle_opts *opts = sd->opts;
priv->current_pts = pts;