summaryrefslogtreecommitdiffstats
path: root/options
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--options/m_config.h2
-rw-r--r--options/m_config_frontend.c2
-rw-r--r--options/m_option.c40
-rw-r--r--options/m_option.h43
-rw-r--r--options/m_property.c7
-rw-r--r--options/m_property.h6
-rw-r--r--options/options.c91
-rw-r--r--options/options.h31
-rw-r--r--options/parse_commandline.c7
-rw-r--r--options/path.c193
-rw-r--r--options/path.h43
11 files changed, 166 insertions, 299 deletions
diff --git a/options/m_config.h b/options/m_config.h
index d2ce2b4..a6bade9 100644
--- a/options/m_config.h
+++ b/options/m_config.h
@@ -1 +1 @@
-#include "m_config_core.h" \ No newline at end of file
+#include "m_config_core.h"
diff --git a/options/m_config_frontend.c b/options/m_config_frontend.c
index 9b54389..d800cdb 100644
--- a/options/m_config_frontend.c
+++ b/options/m_config_frontend.c
@@ -871,7 +871,7 @@ void m_config_print_option_list(const struct m_config *config, const char *name)
if (!defptr)
defptr = &m_option_value_default;
if (defptr)
- def = m_option_pretty_print(opt, defptr);
+ def = m_option_pretty_print(opt, defptr, false);
if (def) {
MP_INFO(config, " (default: %s)", def);
talloc_free(def);
diff --git a/options/m_option.c b/options/m_option.c
index 1b1ac0a..4646510 100644
--- a/options/m_option.c
+++ b/options/m_option.c
@@ -1023,17 +1023,12 @@ static char *print_double(const m_option_t *opt, const void *val)
return talloc_asprintf(NULL, "%f", f);
}
-static char *print_double_7g(const m_option_t *opt, const void *val)
+static char *pretty_print_double(const m_option_t *opt, const void *val)
{
double f = VAL(val);
if (isnan(f))
return print_double(opt, val);
- // Truncate anything < 1e-4 to avoid switching to scientific notation
- if (fabs(f) < 1e-4) {
- return talloc_strdup(NULL, "0");
- } else {
- return talloc_asprintf(NULL, "%.7g", f);
- }
+ return mp_format_double(NULL, f, 4, false, false, !(opt->flags & M_OPT_FIXED_LEN_PRINT));
}
static void add_double(const m_option_t *opt, void *val, double add, bool wrap)
@@ -1105,7 +1100,7 @@ const m_option_type_t m_option_type_double = {
.size = sizeof(double),
.parse = parse_double,
.print = print_double,
- .pretty_print = print_double_7g,
+ .pretty_print = pretty_print_double,
.copy = copy_opt,
.add = add_double,
.multiply = multiply_double,
@@ -1131,7 +1126,7 @@ const m_option_type_t m_option_type_aspect = {
.flags = M_OPT_TYPE_CHOICE | M_OPT_TYPE_USES_RANGE,
.parse = parse_double_aspect,
.print = print_double,
- .pretty_print = print_double_7g,
+ .pretty_print = pretty_print_double,
.copy = copy_opt,
.add = add_double,
.multiply = multiply_double,
@@ -1159,10 +1154,10 @@ static char *print_float(const m_option_t *opt, const void *val)
return print_double(opt, &tmp);
}
-static char *print_float_f3(const m_option_t *opt, const void *val)
+static char *pretty_print_float(const m_option_t *opt, const void *val)
{
double tmp = VAL(val);
- return print_double_7g(opt, &tmp);
+ return pretty_print_double(opt, &tmp);
}
static void add_float(const m_option_t *opt, void *val, double add, bool wrap)
@@ -1207,7 +1202,7 @@ const m_option_type_t m_option_type_float = {
.size = sizeof(float),
.parse = parse_float,
.print = print_float,
- .pretty_print = print_float_f3,
+ .pretty_print = pretty_print_float,
.copy = copy_opt,
.add = add_float,
.multiply = multiply_float,
@@ -1517,6 +1512,7 @@ static char *print_str_list(const m_option_t *opt, const void *src)
{
char **lst = NULL;
char *ret = NULL;
+ const char sep = opt->priv ? *(char *)opt->priv : OPTION_LIST_SEPARATOR;
if (!(src && VAL(src)))
return talloc_strdup(NULL, "");
@@ -1524,7 +1520,7 @@ static char *print_str_list(const m_option_t *opt, const void *src)
for (int i = 0; lst[i]; i++) {
if (ret)
- ret = talloc_strdup_append_buffer(ret, ",");
+ ret = talloc_strndup_append_buffer(ret, &sep, 1);
ret = talloc_strdup_append_buffer(ret, lst[i]);
}
return ret;
@@ -2826,8 +2822,7 @@ static char *print_rel_time(const m_option_t *opt, const void *val)
case REL_TIME_ABSOLUTE:
return talloc_asprintf(NULL, "%g", t->pos);
case REL_TIME_RELATIVE:
- return talloc_asprintf(NULL, "%s%g",
- (t->pos >= 0) ? "+" : "-", fabs(t->pos));
+ return talloc_asprintf(NULL, "%+g", t->pos);
case REL_TIME_CHAPTER:
return talloc_asprintf(NULL, "#%g", t->pos);
case REL_TIME_PERCENT:
@@ -3398,15 +3393,21 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
if (r == 0) {
r = parse_obj_settings(log, name, op, &param, ol, dst ? &res : NULL);
}
- if (r < 0)
+ if (r < 0) {
+ free_obj_settings_list(&res);
return r;
+ }
if (param.len > 0) {
const char sep[2] = {OPTION_LIST_SEPARATOR, 0};
- if (!bstr_eatstart0(&param, sep))
+ if (!bstr_eatstart0(&param, sep)) {
+ free_obj_settings_list(&res);
return M_OPT_INVALID;
+ }
if (param.len == 0) {
- if (!ol->allow_trailer)
+ if (!ol->allow_trailer) {
+ free_obj_settings_list(&res);
return M_OPT_INVALID;
+ }
if (dst) {
m_obj_settings_t item = {
.name = talloc_strdup(NULL, ""),
@@ -3421,6 +3422,7 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
if (op == OP_APPEND) {
mp_err(log, "Option %.*s: -append takes only 1 filter (no ',').\n",
BSTR_P(name));
+ free_obj_settings_list(&res);
return M_OPT_INVALID;
}
mp_warn(log, "Passing more than 1 argument to %.*s is deprecated!\n",
@@ -3784,7 +3786,7 @@ static void dup_node(void *ta_parent, struct mpv_node *node)
static void copy_node(const m_option_t *opt, void *dst, const void *src)
{
- assert(sizeof(struct mpv_node) <= sizeof(union m_option_value));
+ static_assert(sizeof(struct mpv_node) <= sizeof(union m_option_value), "");
if (!(dst && src))
return;
diff --git a/options/m_option.h b/options/m_option.h
index e62fa0f..530c0a3 100644
--- a/options/m_option.h
+++ b/options/m_option.h
@@ -189,15 +189,20 @@ struct m_opt_choice_alternatives {
const char *m_opt_choice_str(const struct m_opt_choice_alternatives *choices,
int value);
-// Validator function signatures. Required to properly type the param value.
typedef int (*m_opt_generic_validate_fn)(struct mp_log *log, const m_option_t *opt,
struct bstr name, void *value);
-typedef int (*m_opt_string_validate_fn)(struct mp_log *log, const m_option_t *opt,
- struct bstr name, const char **value);
-typedef int (*m_opt_int_validate_fn)(struct mp_log *log, const m_option_t *opt,
- struct bstr name, const int *value);
-
+#define OPT_FUNC(name) name
+#define OPT_FUNC_IN(name, suffix) name ## _ ## suffix
+#define OPT_VALIDATE_FUNC(func, value_type, suffix) \
+int OPT_FUNC(func)(struct mp_log *log, const m_option_t *opt, \
+ struct bstr name, value_type value); \
+static inline int OPT_FUNC_IN(func, suffix)(struct mp_log *log, const m_option_t *opt, \
+ struct bstr name, void *value) { \
+ return OPT_FUNC(func)(log, opt, name, value); \
+} \
+int OPT_FUNC(func)(struct mp_log *log, const m_option_t *opt, \
+ struct bstr name, value_type value)
// m_option.priv points to this if OPT_SUBSTRUCT is used
struct m_sub_options {
@@ -442,7 +447,8 @@ char *format_file_size(int64_t size);
#define UPDATE_DVB_PROG (1 << 21) // some --dvbin-...
#define UPDATE_SUB_HARD (1 << 22) // subtitle opts. that need full reinit
#define UPDATE_SUB_EXTS (1 << 23) // update internal list of sub exts
-#define UPDATE_OPT_LAST (1 << 23)
+#define UPDATE_VIDEO (1 << 24) // force redraw if needed
+#define UPDATE_OPT_LAST (1 << 24)
// All bits between _FIRST and _LAST (inclusive)
#define UPDATE_OPTS_MASK \
@@ -457,6 +463,9 @@ char *format_file_size(int64_t size);
// type channels: disallow "auto" (still accept ""), limit list to at most 1 item.
#define M_OPT_CHANNELS_LIMITED (1 << 27)
+// type_float/type_double: controls if pretty print should trim trailing zeros
+#define M_OPT_FIXED_LEN_PRINT (1 << 28)
+
// Like M_OPT_TYPE_OPTIONAL_PARAM.
#define M_OPT_OPTIONAL_PARAM (1 << 30)
@@ -530,12 +539,16 @@ static inline char *m_option_print(const m_option_t *opt, const void *val_ptr)
}
static inline char *m_option_pretty_print(const m_option_t *opt,
- const void *val_ptr)
+ const void *val_ptr,
+ bool fixed_len)
{
+ m_option_t o = *opt;
+ if (fixed_len)
+ o.flags |= M_OPT_FIXED_LEN_PRINT;
if (opt->type->pretty_print)
- return opt->type->pretty_print(opt, val_ptr);
+ return opt->type->pretty_print(&o, val_ptr);
else
- return m_option_print(opt, val_ptr);
+ return m_option_print(&o, val_ptr);
}
// Helper around \ref m_option_type::copy.
@@ -684,15 +697,17 @@ extern const char m_option_path_separator;
#define OPT_CHANNELS(field) \
OPT_TYPED_FIELD(m_option_type_channels, struct m_channels, field)
+#define OPT_INT_VALIDATE_FUNC(func) OPT_VALIDATE_FUNC(func, const int *, int)
+
#define OPT_INT_VALIDATE(field, validate_fn) \
OPT_TYPED_FIELD(m_option_type_int, int, field), \
- .validate = (m_opt_generic_validate_fn) \
- MP_EXPECT_TYPE(m_opt_int_validate_fn, validate_fn)
+ .validate = OPT_FUNC_IN(validate_fn, int)
+
+#define OPT_STRING_VALIDATE_FUNC(func) OPT_VALIDATE_FUNC(func, const char **, str)
#define OPT_STRING_VALIDATE(field, validate_fn) \
OPT_TYPED_FIELD(m_option_type_string, char*, field), \
- .validate = (m_opt_generic_validate_fn) \
- MP_EXPECT_TYPE(m_opt_string_validate_fn, validate_fn)
+ .validate = OPT_FUNC_IN(validate_fn, str)
#define M_CHOICES(...) \
.priv = (void *)&(const struct m_opt_choice_alternatives[]){ __VA_ARGS__, {0}}
diff --git a/options/m_property.c b/options/m_property.c
index 1b76f05..eb3f78e 100644
--- a/options/m_property.c
+++ b/options/m_property.c
@@ -108,13 +108,14 @@ int m_property_do(struct mp_log *log, const struct m_property *prop_list,
assert(opt.type);
switch (action) {
+ case M_PROPERTY_FIXED_LEN_PRINT:
case M_PROPERTY_PRINT: {
- if ((r = do_action(prop_list, name, M_PROPERTY_PRINT, arg, ctx)) >= 0)
+ if ((r = do_action(prop_list, name, action, arg, ctx)) >= 0)
return r;
// Fallback to m_option
if ((r = do_action(prop_list, name, M_PROPERTY_GET, &val, ctx)) <= 0)
return r;
- char *str = m_option_pretty_print(&opt, &val);
+ char *str = m_option_pretty_print(&opt, &val, action == M_PROPERTY_FIXED_LEN_PRINT);
m_option_free(&opt, &val);
*(char **)arg = str;
return str != NULL;
@@ -258,11 +259,13 @@ static int expand_property(const struct m_property *prop_list, char **ret,
bool cond_no = !cond_yes && bstr_eatstart0(&prop, "!");
bool test = cond_yes || cond_no;
bool raw = bstr_eatstart0(&prop, "=");
+ bool fixed_len = !raw && bstr_eatstart0(&prop, ">");
bstr comp_with = {0};
bool comp = test && bstr_split_tok(prop, "==", &prop, &comp_with);
if (test && !comp)
raw = true;
int method = raw ? M_PROPERTY_GET_STRING : M_PROPERTY_PRINT;
+ method = fixed_len ? M_PROPERTY_FIXED_LEN_PRINT : method;
char *s = NULL;
int r = m_property_do_bstr(prop_list, prop, method, &s, ctx);
diff --git a/options/m_property.h b/options/m_property.h
index 0dce246..9fa01e0 100644
--- a/options/m_property.h
+++ b/options/m_property.h
@@ -48,6 +48,12 @@ enum mp_property_action {
// arg: char**
M_PROPERTY_PRINT,
+ // Get human readable fixed length string representing the current value.
+ // If unimplemented, the property wrapper uses the property type as
+ // fallback.
+ // arg: char**
+ M_PROPERTY_FIXED_LEN_PRINT,
+
// Like M_PROPERTY_GET_TYPE, but get a type that is compatible to the real
// type, but reflect practical limits, such as runtime-available values.
// This is mostly used for "UI" related things.
diff --git a/options/options.c b/options/options.c
index 7c6ffa5..8640ecb 100644
--- a/options/options.c
+++ b/options/options.c
@@ -42,6 +42,7 @@
#include "input/event.h"
#include "stream/stream.h"
#include "video/csputils.h"
+#include "video/filter/refqueue.h"
#include "video/hwdec.h"
#include "video/image_writer.h"
#include "sub/osd.h"
@@ -75,6 +76,7 @@ extern const struct m_sub_options input_config;
extern const struct m_sub_options encode_config;
extern const struct m_sub_options ra_ctx_conf;
extern const struct m_sub_options gl_video_conf;
+extern const struct m_sub_options gl_next_conf;
extern const struct m_sub_options ao_alsa_conf;
extern const struct m_sub_options demux_conf;
@@ -111,7 +113,9 @@ static const m_option_t mp_vo_opt_list[] = {
{"vo", OPT_SETTINGSLIST(video_driver_list, &vo_obj_list)},
{"taskbar-progress", OPT_BOOL(taskbar_progress)},
{"drag-and-drop", OPT_CHOICE(drag_and_drop, {"no", -2}, {"auto", -1},
- {"replace", DND_REPLACE}, {"append", DND_APPEND})},
+ {"replace", DND_REPLACE},
+ {"append", DND_APPEND},
+ {"insert-next", DND_INSERT_NEXT})},
{"snap-window", OPT_BOOL(snap_window)},
{"ontop", OPT_BOOL(ontop)},
{"ontop-level", OPT_CHOICE(ontop_level, {"window", -1}, {"system", -2},
@@ -127,7 +131,8 @@ static const m_option_t mp_vo_opt_list[] = {
{"window-scale", OPT_DOUBLE(window_scale), M_RANGE(0.001, 100)},
{"window-minimized", OPT_BOOL(window_minimized)},
{"window-maximized", OPT_BOOL(window_maximized)},
- {"focus-on-open", OPT_BOOL(focus_on_open)},
+ {"focus-on-open", OPT_REMOVED("Replaced by --focus-on")},
+ {"focus-on", OPT_CHOICE(focus_on, {"never", 0}, {"open", 1}, {"all", 2})},
{"force-render", OPT_BOOL(force_render)},
{"force-window-position", OPT_BOOL(force_window_position)},
{"x11-name", OPT_STRING(winname)},
@@ -236,7 +241,6 @@ const struct m_sub_options vo_sub_opts = {
.auto_window_resize = true,
.keepaspect = true,
.keepaspect_window = true,
- .hidpi_window_scale = true,
.native_fs = true,
.taskbar_progress = true,
.border = true,
@@ -251,7 +255,7 @@ const struct m_sub_options vo_sub_opts = {
.ontop_level = -1,
.timing_offset = 0.050,
.swapchain_depth = 3,
- .focus_on_open = true,
+ .focus_on = 1,
},
};
@@ -262,6 +266,7 @@ const struct m_sub_options mp_sub_filter_opts = {
.opts = (const struct m_option[]){
{"sub-filter-sdh", OPT_BOOL(sub_filter_SDH)},
{"sub-filter-sdh-harder", OPT_BOOL(sub_filter_SDH_harder)},
+ {"sub-filter-sdh-enclosures", OPT_STRING(sub_filter_SDH_enclosures)},
{"sub-filter-regex-enable", OPT_BOOL(rf_enable)},
{"sub-filter-regex-plain", OPT_BOOL(rf_plain)},
{"sub-filter-regex", OPT_STRINGLIST(rf_items)},
@@ -271,6 +276,7 @@ const struct m_sub_options mp_sub_filter_opts = {
},
.size = sizeof(OPT_BASE_STRUCT),
.defaults = &(OPT_BASE_STRUCT){
+ .sub_filter_SDH_enclosures = "([\uFF08",
.rf_enable = true,
},
.change_flags = UPDATE_SUB_FILT,
@@ -281,18 +287,14 @@ const struct m_sub_options mp_sub_filter_opts = {
const struct m_sub_options mp_subtitle_sub_opts = {
.opts = (const struct m_option[]){
- {"sub-delay", OPT_FLOAT(sub_delay)},
{"sub-fps", OPT_FLOAT(sub_fps)},
{"sub-speed", OPT_FLOAT(sub_speed)},
- {"sub-visibility", OPT_BOOL(sub_visibility)},
- {"secondary-sub-visibility", OPT_BOOL(sec_sub_visibility)},
{"sub-forced-events-only", OPT_BOOL(sub_forced_events_only)},
{"stretch-dvd-subs", OPT_BOOL(stretch_dvd_subs)},
{"stretch-image-subs-to-screen", OPT_BOOL(stretch_image_subs)},
{"image-subs-video-resolution", OPT_BOOL(image_subs_video_res)},
{"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)},
{"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},
@@ -315,35 +317,29 @@ const struct m_sub_options mp_subtitle_sub_opts = {
{"sub-ass-shaper", OPT_CHOICE(ass_shaper,
{"simple", 0}, {"complex", 1})},
{"sub-ass-justify", OPT_BOOL(ass_justify)},
- {"sub-ass-override", OPT_CHOICE(ass_style_override,
- {"no", 0}, {"yes", 1}, {"force", 3}, {"scale", 4}, {"strip", 5}),
- .flags = UPDATE_SUB_HARD},
{"sub-scale-by-window", OPT_BOOL(sub_scale_by_window)},
{"sub-scale-with-window", OPT_BOOL(sub_scale_with_window)},
{"sub-ass-scale-with-window", OPT_BOOL(ass_scale_with_window)},
{"sub", OPT_SUBSTRUCT(sub_style, sub_style_conf)},
{"sub-clear-on-seek", OPT_BOOL(sub_clear_on_seek)},
- {"teletext-page", OPT_INT(teletext_page), M_RANGE(1, 999)},
+ {"teletext-page", OPT_INT(teletext_page), M_RANGE(-1, 999)},
{"sub-past-video-end", OPT_BOOL(sub_past_video_end)},
{"sub-ass-force-style", OPT_REPLACED("sub-ass-style-overrides")},
+ {"sub-lavc-o", OPT_KEYVALUELIST(sub_avopts)},
{0}
},
.size = sizeof(OPT_BASE_STRUCT),
.defaults = &(OPT_BASE_STRUCT){
- .sub_visibility = true,
- .sec_sub_visibility = true,
- .sub_pos = 100,
.sub_speed = 1.0,
.ass_enabled = true,
.sub_scale_by_window = true,
.sub_use_margins = true,
.sub_scale_with_window = true,
- .teletext_page = 100,
+ .teletext_page = 0,
.sub_scale = 1,
.ass_vsfilter_aspect_compat = true,
.ass_vsfilter_color_compat = 1,
.ass_vsfilter_blur_compat = true,
- .ass_style_override = 1,
.ass_shaper = 1,
.use_embedded_fonts = true,
},
@@ -351,6 +347,36 @@ const struct m_sub_options mp_subtitle_sub_opts = {
};
#undef OPT_BASE_STRUCT
+#define OPT_BASE_STRUCT struct mp_subtitle_shared_opts
+
+const struct m_sub_options mp_subtitle_shared_sub_opts = {
+ .opts = (const struct m_option[]){
+ {"sub-delay", OPT_FLOAT(sub_delay[0])},
+ {"secondary-sub-delay", OPT_FLOAT(sub_delay[1])},
+ {"sub-pos", OPT_FLOAT(sub_pos[0]), M_RANGE(0.0, 150.0)},
+ {"secondary-sub-pos", OPT_FLOAT(sub_pos[1]), M_RANGE(0.0, 150.0)},
+ {"sub-visibility", OPT_BOOL(sub_visibility[0])},
+ {"secondary-sub-visibility", OPT_BOOL(sub_visibility[1])},
+ {"sub-ass-override", OPT_CHOICE(ass_style_override[0],
+ {"no", 0}, {"yes", 1}, {"force", 3}, {"scale", 4}, {"strip", 5}),
+ .flags = UPDATE_SUB_HARD},
+ {"secondary-sub-ass-override", OPT_CHOICE(ass_style_override[1],
+ {"no", 0}, {"yes", 1}, {"force", 3}, {"scale", 4}, {"strip", 5}),
+ .flags = UPDATE_SUB_HARD},
+ {0}
+ },
+ .size = sizeof(OPT_BASE_STRUCT),
+ .defaults = &(OPT_BASE_STRUCT){
+ .sub_visibility[0] = true,
+ .sub_visibility[1] = true,
+ .sub_pos[0] = 100,
+ .ass_style_override[0] = 1,
+ .ass_style_override[1] = 5,
+ },
+ .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 = {
@@ -359,6 +385,7 @@ const struct m_sub_options mp_osd_render_sub_opts = {
{"osd-bar-align-y", OPT_FLOAT(osd_bar_align_y), M_RANGE(-1.0, +1.0)},
{"osd-bar-w", OPT_FLOAT(osd_bar_w), M_RANGE(1, 100)},
{"osd-bar-h", OPT_FLOAT(osd_bar_h), M_RANGE(0.1, 50)},
+ {"osd-bar-border-size", OPT_FLOAT(osd_bar_border_size), M_RANGE(0, 1000.0)},
{"osd", OPT_SUBSTRUCT(osd_style, osd_style_conf)},
{"osd-scale", OPT_FLOAT(osd_scale), M_RANGE(0, 100)},
{"osd-scale-by-window", OPT_BOOL(osd_scale_by_window)},
@@ -370,6 +397,7 @@ const struct m_sub_options mp_osd_render_sub_opts = {
.osd_bar_align_y = 0.5,
.osd_bar_w = 75.0,
.osd_bar_h = 3.125,
+ .osd_bar_border_size = 0.5,
.osd_scale = 1,
.osd_scale_by_window = true,
},
@@ -412,10 +440,18 @@ const struct m_sub_options dvd_conf = {
const struct m_sub_options filter_conf = {
.opts = (const struct m_option[]){
- {"deinterlace", OPT_BOOL(deinterlace)},
+ {"deinterlace", OPT_CHOICE(deinterlace,
+ {"no", 0}, {"yes", 1}, {"auto", -1})},
+ {"deinterlace-field-parity", OPT_CHOICE(field_parity,
+ {"tff", MP_FIELD_PARITY_TFF},
+ {"bff", MP_FIELD_PARITY_BFF},
+ {"auto", MP_FIELD_PARITY_AUTO})},
{0}
},
.size = sizeof(OPT_BASE_STRUCT),
+ .defaults = &(const struct filter_opts){
+ .field_parity = MP_FIELD_PARITY_AUTO,
+ },
.change_flags = UPDATE_IMGPAR,
};
@@ -562,7 +598,8 @@ static const m_option_t mp_opts[] = {
{"slang", OPT_STRINGLIST(stream_lang[STREAM_SUB])},
{"vlang", OPT_STRINGLIST(stream_lang[STREAM_VIDEO])},
{"track-auto-selection", OPT_BOOL(stream_auto_sel)},
- {"subs-with-matching-audio", OPT_BOOL(subs_with_matching_audio)},
+ {"subs-with-matching-audio", OPT_CHOICE(subs_with_matching_audio, {"no", 0},
+ {"forced", 1}, {"yes", 2})},
{"subs-match-os-language", OPT_BOOL(subs_match_os_language)},
{"subs-fallback", OPT_CHOICE(subs_fallback, {"no", 0}, {"default", 1}, {"yes", 2})},
{"subs-fallback-forced", OPT_CHOICE(subs_fallback_forced, {"no", 0},
@@ -662,6 +699,7 @@ static const m_option_t mp_opts[] = {
{"cover-art-whitelist", OPT_BOOL(coverart_whitelist)},
{"", OPT_SUBSTRUCT(subs_rend, mp_subtitle_sub_opts)},
+ {"", OPT_SUBSTRUCT(subs_shared, mp_subtitle_shared_sub_opts)},
{"", OPT_SUBSTRUCT(subs_filt, mp_sub_filter_opts)},
{"", OPT_SUBSTRUCT(osd_rend, mp_osd_render_sub_opts)},
@@ -680,6 +718,10 @@ static const m_option_t mp_opts[] = {
// values <0 for volume and mute are legacy and ignored
{"volume", OPT_FLOAT(softvol_volume), .flags = UPDATE_VOL,
M_RANGE(-1, 1000)},
+ {"volume-gain-max", OPT_FLOAT(softvol_gain_max), M_RANGE(0, 150)},
+ {"volume-gain-min", OPT_FLOAT(softvol_gain_min), M_RANGE(-150, 0)},
+ {"volume-gain", OPT_FLOAT(softvol_gain), .flags = UPDATE_VOL,
+ M_RANGE(-150, 150)},
{"mute", OPT_CHOICE(softvol_mute,
{"no", 0},
{"auto", 0},
@@ -794,7 +836,6 @@ static const m_option_t mp_opts[] = {
{"term-osd-bar", OPT_BOOL(term_osd_bar), .flags = UPDATE_OSD},
{"term-osd-bar-chars", OPT_STRING(term_osd_bar_chars), .flags = UPDATE_OSD},
- {"term-remaining-playtime", OPT_BOOL(term_remaining_playtime), .flags = UPDATE_OSD},
{"term-title", OPT_STRING(term_title), .flags = UPDATE_OSD},
{"term-playing-msg", OPT_STRING(playing_msg)},
@@ -812,6 +853,7 @@ static const m_option_t mp_opts[] = {
{"idle", OPT_CHOICE(player_idle_mode,
{"no", 0}, {"once", 1}, {"yes", 2})},
+ {"input-commands", OPT_STRINGLIST(input_commands)},
{"input-terminal", OPT_BOOL(consolecontrols), .flags = UPDATE_TERM},
{"input-ipc-server", OPT_STRING(ipc_path), .flags = M_OPT_FILE},
@@ -837,6 +879,7 @@ static const m_option_t mp_opts[] = {
{"", OPT_SUBSTRUCT(ra_ctx_opts, ra_ctx_conf)},
{"", OPT_SUBSTRUCT(gl_video_opts, gl_video_conf)},
+ {"", OPT_SUBSTRUCT(gl_next_opts, gl_next_conf)},
{"", OPT_SUBSTRUCT(spirv_opts, spirv_conf)},
#if HAVE_GL
@@ -903,6 +946,9 @@ static const struct MPOpts mp_default_opts = {
.msg_color = true,
.softvol_max = 130,
.softvol_volume = 100,
+ .softvol_gain_max = 12,
+ .softvol_gain_min = -96,
+ .softvol_gain = 0,
.gapless_audio = -1,
.wintitle = "${?media-title:${media-title}}${!media-title:No file} - mpv",
.stop_screensaver = 1,
@@ -946,7 +992,6 @@ static const struct MPOpts mp_default_opts = {
.frame_dropping = 1,
.term_osd = 2,
.term_osd_bar_chars = "[-+-]",
- .term_remaining_playtime = true,
.consolecontrols = true,
.playlist_pos = -1,
.play_frames = -1,
@@ -960,7 +1005,7 @@ static const struct MPOpts mp_default_opts = {
[STREAM_VIDEO] = -2,
[STREAM_SUB] = -2, }, },
.stream_auto_sel = true,
- .subs_with_matching_audio = true,
+ .subs_with_matching_audio = 2,
.subs_match_os_language = true,
.subs_fallback = 1,
.subs_fallback_forced = 1,
@@ -1063,12 +1108,14 @@ static const struct MPOpts mp_default_opts = {
"sub-delay",
"sub-speed",
"sub-pos",
+ "secondary-sub-pos",
"sub-visibility",
"sub-scale",
"sub-use-margins",
"sub-ass-force-margins",
"sub-ass-vsfilter-aspect-compat",
"sub-ass-override",
+ "secondary-sub-ass-override",
"secondary-sub-visibility",
"ab-loop-a",
"ab-loop-b",
diff --git a/options/options.h b/options/options.h
index aa071b2..69a50b3 100644
--- a/options/options.h
+++ b/options/options.h
@@ -20,7 +20,7 @@ typedef struct mp_vo_opts {
bool all_workspaces;
bool window_minimized;
bool window_maximized;
- bool focus_on_open;
+ int focus_on;
int screen_id;
char *screen_name;
@@ -82,10 +82,6 @@ typedef struct mp_vo_opts {
// Subtitle options needed by the subtitle decoders/renderers.
struct mp_subtitle_opts {
- bool sub_visibility;
- bool sec_sub_visibility;
- float sub_pos;
- float sub_delay;
float sub_fps;
float sub_speed;
bool sub_forced_events_only;
@@ -111,18 +107,27 @@ struct mp_subtitle_opts {
bool use_embedded_fonts;
char **ass_style_override_list;
char *ass_styles_file;
- int ass_style_override;
int ass_hinting;
int ass_shaper;
bool ass_justify;
bool sub_clear_on_seek;
int teletext_page;
bool sub_past_video_end;
+ char **sub_avopts;
+};
+
+// Options for both primary and secondary subs.
+struct mp_subtitle_shared_opts {
+ float sub_delay[2];
+ float sub_pos[2];
+ bool sub_visibility[2];
+ int ass_style_override[2];
};
struct mp_sub_filter_opts {
bool sub_filter_SDH;
bool sub_filter_SDH_harder;
+ char *sub_filter_SDH_enclosures;
bool rf_enable;
bool rf_plain;
char **rf_items;
@@ -135,6 +140,7 @@ struct mp_osd_render_opts {
float osd_bar_align_y;
float osd_bar_w;
float osd_bar_h;
+ float osd_bar_border_size;
float osd_scale;
bool osd_scale_by_window;
struct osd_style_opts *osd_style;
@@ -181,6 +187,9 @@ typedef struct MPOpts {
float rgain_fallback;
int softvol_mute;
float softvol_max;
+ float softvol_gain;
+ float softvol_gain_min;
+ float softvol_gain_max;
int gapless_audio;
mp_vo_opts *vo;
@@ -196,6 +205,7 @@ typedef struct MPOpts {
bool cursor_autohide_fs;
struct mp_subtitle_opts *subs_rend;
+ struct mp_subtitle_shared_opts *subs_shared;
struct mp_sub_filter_opts *subs_filt;
struct mp_osd_render_opts *osd_rend;
@@ -238,7 +248,6 @@ typedef struct MPOpts {
int term_osd;
bool term_osd_bar;
char *term_osd_bar_chars;
- bool term_remaining_playtime;
char *term_title;
char *playing_msg;
char *osd_playing_msg;
@@ -247,6 +256,7 @@ typedef struct MPOpts {
char *osd_status_msg;
char *osd_msg[3];
int player_idle_mode;
+ char **input_commands;
bool consolecontrols;
int playlist_pos;
struct m_rel_time play_start;
@@ -273,7 +283,7 @@ typedef struct MPOpts {
int stream_id[2][STREAM_TYPE_COUNT];
char **stream_lang[STREAM_TYPE_COUNT];
bool stream_auto_sel;
- bool subs_with_matching_audio;
+ int subs_with_matching_audio;
bool subs_match_os_language;
int subs_fallback;
int subs_fallback_forced;
@@ -357,6 +367,7 @@ typedef struct MPOpts {
struct ra_ctx_opts *ra_ctx_opts;
struct gl_video_opts *gl_video_opts;
+ struct gl_next_opts *gl_next_opts;
struct angle_opts *angle_opts;
struct opengl_opts *opengl_opts;
struct vulkan_opts *vulkan_opts;
@@ -388,13 +399,15 @@ struct dvd_opts {
};
struct filter_opts {
- bool deinterlace;
+ int deinterlace;
+ int field_parity;
};
extern const struct m_sub_options vo_sub_opts;
extern const struct m_sub_options cuda_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_subtitle_shared_sub_opts;
extern const struct m_sub_options mp_sub_filter_opts;
extern const struct m_sub_options mp_osd_render_sub_opts;
extern const struct m_sub_options filter_conf;
diff --git a/options/parse_commandline.c b/options/parse_commandline.c
index 93120d3..ded8531 100644
--- a/options/parse_commandline.c
+++ b/options/parse_commandline.c
@@ -103,10 +103,10 @@ static void process_non_option(struct playlist *files, const char *arg)
// Glob filenames on Windows (cmd.exe doesn't do this automatically)
if (glob(arg, 0, NULL, &gg)) {
- playlist_add_file(files, arg);
+ playlist_append_file(files, arg);
} else {
for (int i = 0; i < gg.gl_pathc; i++)
- playlist_add_file(files, gg.gl_pathv[i]);
+ playlist_append_file(files, gg.gl_pathv[i]);
globfree(&gg);
}
@@ -114,7 +114,7 @@ static void process_non_option(struct playlist *files, const char *arg)
#else
static void process_non_option(struct playlist *files, const char *arg)
{
- playlist_add_file(files, arg);
+ playlist_append_file(files, arg);
}
#endif
@@ -201,7 +201,6 @@ int m_config_parse_mp_command_line(m_config_t *config, struct playlist *files,
goto err_out;
}
playlist_transfer_entries(files, pl);
- playlist_populate_playlist_path(files, param0);
talloc_free(param0);
talloc_free(pl);
continue;
diff --git a/options/path.c b/options/path.c
index 52dc113..7c7d31c 100644
--- a/options/path.c
+++ b/options/path.c
@@ -29,6 +29,7 @@
#include "config.h"
+#include "misc/path_utils.h"
#include "common/common.h"
#include "common/global.h"
#include "common/msg.h"
@@ -42,7 +43,7 @@
// In order of decreasing priority: the first has highest priority.
static const mp_get_platform_path_cb path_resolvers[] = {
#if HAVE_COCOA
- mp_get_platform_path_osx,
+ mp_get_platform_path_mac,
#endif
#if HAVE_DARWIN
mp_get_platform_path_darwin,
@@ -75,10 +76,14 @@ static const char *mp_get_platform_path(void *talloc_ctx,
assert(talloc_ctx);
if (global->configdir) {
+ // Return NULL for all platform paths if --no-config is passed
+ if (!global->configdir[0])
+ return NULL;
+
// force all others to NULL, only first returns the path
for (int n = 0; n < MP_ARRAY_SIZE(config_dirs); n++) {
if (strcmp(config_dirs[n], type) == 0)
- return (n == 0 && global->configdir[0]) ? global->configdir : NULL;
+ return (n == 0) ? global->configdir : NULL;
}
}
@@ -217,190 +222,6 @@ char *mp_get_user_path(void *talloc_ctx, struct mpv_global *global,
return res;
}
-char *mp_basename(const char *path)
-{
- char *s;
-
-#if HAVE_DOS_PATHS
- if (!mp_is_url(bstr0(path))) {
- s = strrchr(path, '\\');
- if (s)
- path = s + 1;
- s = strrchr(path, ':');
- if (s)
- path = s + 1;
- }
-#endif
- s = strrchr(path, '/');
- return s ? s + 1 : (char *)path;
-}
-
-struct bstr mp_dirname(const char *path)
-{
- struct bstr ret = {
- (uint8_t *)path, mp_basename(path) - path
- };
- if (ret.len == 0)
- return bstr0(".");
- return ret;
-}
-
-
-#if HAVE_DOS_PATHS
-static const char mp_path_separators[] = "\\/";
-#else
-static const char mp_path_separators[] = "/";
-#endif
-
-// Mutates path and removes a trailing '/' (or '\' on Windows)
-void mp_path_strip_trailing_separator(char *path)
-{
- size_t len = strlen(path);
- if (len > 0 && strchr(mp_path_separators, path[len - 1]))
- path[len - 1] = '\0';
-}
-
-char *mp_splitext(const char *path, bstr *root)
-{
- assert(path);
- int skip = (*path == '.'); // skip leading dot for "hidden" unix files
- const char *split = strrchr(path + skip, '.');
- if (!split || !split[1] || strchr(split, '/'))
- return NULL;
- if (root)
- *root = (bstr){(char *)path, split - path};
- return (char *)split + 1;
-}
-
-bool mp_path_is_absolute(struct bstr path)
-{
- if (path.len && strchr(mp_path_separators, path.start[0]))
- return true;
-
-#if HAVE_DOS_PATHS
- // Note: "X:filename" is a path relative to the current working directory
- // of drive X, and thus is not an absolute path. It needs to be
- // followed by \ or /.
- if (path.len >= 3 && path.start[1] == ':' &&
- strchr(mp_path_separators, path.start[2]))
- return true;
-#endif
-
- return false;
-}
-
-char *mp_path_join_bstr(void *talloc_ctx, struct bstr p1, struct bstr p2)
-{
- if (p1.len == 0)
- return bstrdup0(talloc_ctx, p2);
- if (p2.len == 0)
- return bstrdup0(talloc_ctx, p1);
-
- if (mp_path_is_absolute(p2))
- return bstrdup0(talloc_ctx, p2);
-
- bool have_separator = strchr(mp_path_separators, p1.start[p1.len - 1]);
-#if HAVE_DOS_PATHS
- // "X:" only => path relative to "X:" current working directory.
- if (p1.len == 2 && p1.start[1] == ':')
- have_separator = true;
-#endif
-
- return talloc_asprintf(talloc_ctx, "%.*s%s%.*s", BSTR_P(p1),
- have_separator ? "" : "/", BSTR_P(p2));
-}
-
-char *mp_path_join(void *talloc_ctx, const char *p1, const char *p2)
-{
- return mp_path_join_bstr(talloc_ctx, bstr0(p1), bstr0(p2));
-}
-
-char *mp_getcwd(void *talloc_ctx)
-{
- char *e_wd = getenv("PWD");
- if (e_wd)
- return talloc_strdup(talloc_ctx, e_wd);
-
- char *wd = talloc_array(talloc_ctx, char, 20);
- while (getcwd(wd, talloc_get_size(wd)) == NULL) {
- if (errno != ERANGE) {
- talloc_free(wd);
- return NULL;
- }
- wd = talloc_realloc(talloc_ctx, wd, char, talloc_get_size(wd) * 2);
- }
- return wd;
-}
-
-char *mp_normalize_path(void *talloc_ctx, const char *path)
-{
- if (mp_is_url(bstr0(path)))
- return talloc_strdup(talloc_ctx, path);
-
- return mp_path_join(talloc_ctx, mp_getcwd(talloc_ctx), path);
-}
-
-bool mp_path_exists(const char *path)
-{
- struct stat st;
- return path && stat(path, &st) == 0;
-}
-
-bool mp_path_isdir(const char *path)
-{
- struct stat st;
- return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
-}
-
-// Return false if it's considered a normal local filesystem path.
-bool mp_is_url(bstr path)
-{
- int proto = bstr_find0(path, "://");
- if (proto < 1)
- return false;
- // Per RFC3986, the first character of the protocol must be alphabetic.
- // The rest must be alphanumeric plus -, + and .
- for (int i = 0; i < proto; i++) {
- unsigned char c = path.start[i];
- if ((i == 0 && !mp_isalpha(c)) ||
- (!mp_isalnum(c) && c != '.' && c != '-' && c != '+'))
- {
- return false;
- }
- }
- return true;
-}
-
-// Return the protocol part of path, e.g. "http" if path is "http://...".
-// On success, out_url (if not NULL) is set to the part after the "://".
-bstr mp_split_proto(bstr path, bstr *out_url)
-{
- if (!mp_is_url(path))
- return (bstr){0};
- bstr r;
- bstr_split_tok(path, "://", &r, out_url ? out_url : &(bstr){0});
- return r;
-}
-
-void mp_mkdirp(const char *dir)
-{
- char *path = talloc_strdup(NULL, dir);
- char *cdir = path + 1;
-
- while (cdir) {
- cdir = strchr(cdir, '/');
- if (cdir)
- *cdir = 0;
-
- mkdir(path, 0700);
-
- if (cdir)
- *cdir++ = '/';
- }
-
- talloc_free(path);
-}
-
void mp_mk_user_dir(struct mpv_global *global, const char *type, char *subdir)
{
char *dir = mp_find_user_file(NULL, global, type, subdir);
diff --git a/options/path.h b/options/path.h
index 7ec8f7b..a665e67 100644
--- a/options/path.h
+++ b/options/path.h
@@ -22,6 +22,7 @@
#include <stdbool.h>
#include "misc/bstr.h"
+#include "misc/path_utils.h"
struct mpv_global;
struct MPOpts;
@@ -30,7 +31,7 @@ void mp_init_paths(struct mpv_global *global, struct MPOpts *opts);
// Search for the input filename in several paths. These include user and global
// config locations by default. Some platforms may implement additional platform
-// related lookups (i.e.: OSX inside an application bundle).
+// related lookups (i.e.: macOS inside an application bundle).
char *mp_find_config_file(void *talloc_ctx, struct mpv_global *global,
const char *filename);
@@ -53,46 +54,6 @@ char **mp_find_all_config_files(void *talloc_ctx, struct mpv_global *global,
char *mp_get_user_path(void *talloc_ctx, struct mpv_global *global,
const char *path);
-// Return pointer to filename part of path
-
-char *mp_basename(const char *path);
-
-/* Return file extension, excluding the '.'. If root is not NULL, set it to the
- * part of the path without extension. So: path == root + "." + extension
- * Don't consider it a file extension if the only '.' is the first character.
- * Return NULL if no extension and don't set *root in this case.
- */
-char *mp_splitext(const char *path, bstr *root);
-
-/* Return struct bstr referencing directory part of path, or if that
- * would be empty, ".".
- */
-struct bstr mp_dirname(const char *path);
-
-void mp_path_strip_trailing_separator(char *path);
-
-/* Join two path components and return a newly allocated string
- * for the result. '/' is inserted between the components if needed.
- * If p2 is an absolute path then the value of p1 is ignored.
- */
-char *mp_path_join(void *talloc_ctx, const char *p1, const char *p2);
-char *mp_path_join_bstr(void *talloc_ctx, struct bstr p1, struct bstr p2);
-
-// Return whether the path is absolute.
-bool mp_path_is_absolute(struct bstr path);
-
-char *mp_getcwd(void *talloc_ctx);
-
-char *mp_normalize_path(void *talloc_ctx, const char *path);
-
-bool mp_path_exists(const char *path);
-bool mp_path_isdir(const char *path);
-
-bool mp_is_url(bstr path);
-
-bstr mp_split_proto(bstr path, bstr *out_url);
-
-void mp_mkdirp(const char *dir);
void mp_mk_user_dir(struct mpv_global *global, const char *type, char *subdir);
#endif /* MPLAYER_PATH_H */