summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-12-29 17:19:25 +0100
committerKevin Mitchell <kevmitch@gmail.com>2018-01-02 14:27:37 -0800
commit6aad532aa39481a8100910612fad039dd75236b9 (patch)
tree53c790d6c66917e66039c25a13cdf27f90bbf0d9
parent3bf7df4a5e1f46248c78e9e596cd8dab6ff57356 (diff)
downloadmpv-6aad532aa39481a8100910612fad039dd75236b9.tar.bz2
mpv-6aad532aa39481a8100910612fad039dd75236b9.tar.xz
options: move most subtitle and OSD rendering options to sub structs
Remove them from the big MPOpts struct and move them to their sub structs. In the places where their fields are used, create a private copy of the structs, instead of accessing the semi-deprecated global option struct instance (mpv_global.opts) directly. This actually makes accessing these options finally thread-safe. They weren't even if they should have for years. (Including some potential for undefined behavior when e.g. the OSD font was changed at runtime.) This is mostly transparent. All options get moved around, but most users of the options just need to access a different struct (changing sd.opts to a different type changes a lot of uses, for example). One thing which has to be considered and could cause potential regressions is that the new option copies must be explicitly updated. sub_update_opts() takes care of this for example. Another thing is that writing to the option structs manually won't work, because the changes won't be propagated to other copies. Apparently the only affected case is the implementation of the sub-step command, which tries to change sub_delay. Handle this one explicitly (osd_changed() doesn't need to be called anymore, because changing the option triggers UPDATE_OSD, and updates the OSD as a consequence). The way the option value is propagated is rather hacky, but for now this will do.
-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;