diff options
Diffstat (limited to 'options')
-rw-r--r-- | options/m_option.c | 104 | ||||
-rw-r--r-- | options/m_option.h | 18 | ||||
-rw-r--r-- | options/options.c | 3 | ||||
-rw-r--r-- | options/options.h | 2 |
4 files changed, 94 insertions, 33 deletions
diff --git a/options/m_option.c b/options/m_option.c index b7b76634f8..231b9aa5d2 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -2287,51 +2287,105 @@ const m_option_type_t m_option_type_afmt = { #include "audio/chmap.h" -static int parse_chmap(struct mp_log *log, const m_option_t *opt, - struct bstr name, struct bstr param, void *dst) +static int parse_channels(struct mp_log *log, const m_option_t *opt, + struct bstr name, struct bstr param, void *dst) { - // min>0: at least min channels, min=0: empty ok - int min_ch = (opt->flags & M_OPT_MIN) ? opt->min : 1; - assert(min_ch >= 0); + // see OPT_CHANNELS for semantics. + bool limited = opt->min; + + struct m_channels res = {0}; if (bstr_equals0(param, "help")) { mp_chmap_print_help(log); + if (!limited) { + mp_info(log, "\nOther values:\n" + " auto-safe\n"); + } return M_OPT_EXIT - 1; } - if (param.len == 0 && min_ch >= 1) - return M_OPT_MISSING_PARAM; - - struct mp_chmap res = {0}; - if (!mp_chmap_from_str(&res, param)) { - mp_err(log, "Error parsing channel layout: %.*s\n", BSTR_P(param)); - return M_OPT_INVALID; + bool auto_safe = bstr_equals0(param, "auto-safe"); + if (bstr_equals0(param, "auto") || bstr_equals0(param, "empty") || auto_safe) { + if (limited) { + mp_err(log, "Disallowed parameter.\n"); + return M_OPT_INVALID; + } + param.len = 0; + res.set = true; + res.auto_safe = auto_safe; } - if (!mp_chmap_is_valid(&res) && !(min_ch == 0 && mp_chmap_is_empty(&res))) { - mp_err(log, "Invalid channel layout: %.*s\n", BSTR_P(param)); - return M_OPT_INVALID; + while (param.len) { + bstr item; + if (limited) { + item = param; + param.len = 0; + } else { + bstr_split_tok(param, ",", &item, ¶m); + } + + struct mp_chmap map = {0}; + if (!mp_chmap_from_str(&map, item) || !mp_chmap_is_valid(&map)) { + mp_err(log, "Invalid channel layout: %.*s\n", BSTR_P(item)); + talloc_free(res.chmaps); + return M_OPT_INVALID; + } + + MP_TARRAY_APPEND(NULL, res.chmaps, res.num_chmaps, map); + res.set = true; } - if (dst) - *(struct mp_chmap *)dst = res; + if (dst) { + *(struct m_channels *)dst = res; + } else { + talloc_free(res.chmaps); + } return 1; } -static char *print_chmap(const m_option_t *opt, const void *val) +static char *print_channels(const m_option_t *opt, const void *val) { - const struct mp_chmap *chmap = val; - return talloc_strdup(NULL, mp_chmap_to_str(chmap)); + const struct m_channels *ch = val; + if (!ch->set) + return talloc_strdup(NULL, ""); + if (ch->auto_safe) + return talloc_strdup(NULL, "auto-safe"); + if (ch->num_chmaps > 0) { + char *res = talloc_strdup(NULL, ""); + for (int n = 0; n < ch->num_chmaps; n++) { + if (n > 0) + res = talloc_strdup_append(res, ","); + res = talloc_strdup_append(res, mp_chmap_to_str(&ch->chmaps[n])); + } + return res; + } + return talloc_strdup(NULL, "auto"); } +static void free_channels(void *src) +{ + struct m_channels *ch = src; + talloc_free(ch->chmaps); + *ch = (struct m_channels){0}; +} -const m_option_type_t m_option_type_chmap = { +static void copy_channels(const m_option_t *opt, void *dst, const void *src) +{ + struct m_channels *ch = dst; + free_channels(dst); + *ch = *(struct m_channels *)src; + ch->chmaps = + talloc_memdup(NULL, ch->chmaps, sizeof(ch->chmaps[0]) * ch->num_chmaps); +} + +const m_option_type_t m_option_type_channels = { .name = "Audio channels or channel map", - .size = sizeof(struct mp_chmap), - .parse = parse_chmap, - .print = print_chmap, - .copy = copy_opt, + .size = sizeof(struct m_channels), + .parse = parse_channels, + .print = print_channels, + .copy = copy_channels, + .free = free_channels, }; static int parse_timestring(struct bstr str, double *time, char endchar) diff --git a/options/m_option.h b/options/m_option.h index e77452af69..80be447c42 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -61,7 +61,7 @@ extern const m_option_type_t m_option_type_afmt; extern const m_option_type_t m_option_type_color; extern const m_option_type_t m_option_type_geometry; extern const m_option_type_t m_option_type_size_box; -extern const m_option_type_t m_option_type_chmap; +extern const m_option_type_t m_option_type_channels; extern const m_option_type_t m_option_type_node; // Used internally by m_config.c @@ -98,6 +98,13 @@ struct m_geometry { void m_geometry_apply(int *xpos, int *ypos, int *widw, int *widh, int scrw, int scrh, struct m_geometry *gm); +struct m_channels { + bool set : 1; + bool auto_safe : 1; + struct mp_chmap *chmaps; + int num_chmaps; +}; + struct m_obj_desc { // Name which will be used in the option string const char *name; @@ -218,7 +225,7 @@ union m_option_value { struct m_color color; struct m_geometry geometry; struct m_geometry size_box; - struct mp_chmap chmap; + struct m_channels channels; }; //////////////////////////////////////////////////////////////////////////// @@ -626,9 +633,10 @@ extern const char m_option_path_separator; #define OPT_AUDIOFORMAT(...) \ OPT_GENERAL(int, __VA_ARGS__, .type = &m_option_type_afmt) -#define OPT_CHMAP(...) \ - OPT_GENERAL(struct mp_chmap, __VA_ARGS__, .type = &m_option_type_chmap) - +// If .min==1, then passing auto is disallowed, but "" is still accepted, and +// limit channel list to 1 item. +#define OPT_CHANNELS(...) \ + OPT_GENERAL(struct m_channels, __VA_ARGS__, .type = &m_option_type_channels) #define M_CHOICES(choices) \ .priv = (void *)&(const struct m_opt_choice_alternatives[]){ \ diff --git a/options/options.c b/options/options.c index 0ad9d71b40..9fd853ffda 100644 --- a/options/options.c +++ b/options/options.c @@ -279,7 +279,7 @@ const m_option_t mp_opts[] = { // force video/audio rate: OPT_DOUBLE("fps", force_fps, CONF_MIN, .min = 0), OPT_INTRANGE("audio-samplerate", force_srate, 0, 1000, 16*48000), - OPT_CHMAP("audio-channels", audio_output_channels, CONF_MIN, .min = 0), + OPT_CHANNELS("audio-channels", audio_output_channels, 0), OPT_AUDIOFORMAT("audio-format", audio_output_format, 0), OPT_FLAG("audio-normalize-downmix", audio_normalize, 0), OPT_DOUBLE("speed", playback_speed, M_OPT_RANGE | M_OPT_FIXED, @@ -805,7 +805,6 @@ const struct MPOpts mp_default_opts = { .sub_visibility = 1, .sub_pos = 100, .sub_speed = 1.0, - .audio_output_channels = MP_CHMAP_INIT_STEREO, .audio_output_format = 0, // AF_FORMAT_UNKNOWN .playback_speed = 1., .pitch_correction = 1, diff --git a/options/options.h b/options/options.h index 7690823aab..ef72865f56 100644 --- a/options/options.h +++ b/options/options.h @@ -226,7 +226,7 @@ typedef struct MPOpts { double force_fps; int index_mode; - struct mp_chmap audio_output_channels; + struct m_channels audio_output_channels; int audio_output_format; int audio_normalize; int force_srate; |