diff options
-rw-r--r-- | options/m_config.c | 14 | ||||
-rw-r--r-- | options/m_config.h | 4 | ||||
-rw-r--r-- | options/options.c | 171 | ||||
-rw-r--r-- | options/options.h | 99 | ||||
-rw-r--r-- | player/command.c | 16 | ||||
-rw-r--r-- | player/misc.c | 2 | ||||
-rw-r--r-- | sub/ass_mp.c | 1 | ||||
-rw-r--r-- | sub/dec_sub.c | 28 | ||||
-rw-r--r-- | sub/dec_sub.h | 2 | ||||
-rw-r--r-- | sub/osd.c | 10 | ||||
-rw-r--r-- | sub/osd_libass.c | 4 | ||||
-rw-r--r-- | sub/osd_state.h | 3 | ||||
-rw-r--r-- | sub/sd.h | 2 | ||||
-rw-r--r-- | sub/sd_ass.c | 13 | ||||
-rw-r--r-- | sub/sd_lavc.c | 6 |
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); @@ -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; @@ -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 |