options: add a mechanism to make sub-option replacement slightly easier

Instead of requiring each VO or AO to manually add members to MPOpts and
the global option table, make it possible to register them automatically
via vo_driver/ao_driver.global_opts members. This avoids modifying
options.c/options.h every time, including having to duplicate the exact
ifdeffery used to enable a driver.
This commit is contained in:
wm4 2016-09-05 21:04:17 +02:00
parent cc813647d5
commit 4ab860cddc
11 changed files with 33 additions and 16 deletions

View File

@ -16,6 +16,8 @@ normal driver parameters.
``--ao-defaults=<driver1[:parameter1:parameter2:...],driver2,...>``
Set defaults for each driver.
Deprecated. No replacement.
.. note::
See ``--ao=help`` for a list of compiled-in audio output drivers. The
@ -23,12 +25,6 @@ normal driver parameters.
where PulseAudio is used. On BSD systems, ``--ao=oss`` or ``--ao=sndio``
may work (the latter being experimental).
.. admonition:: Examples
- ``--ao=alsa,oss,`` Try the ALSA driver, then the OSS driver, then others.
- ``--ao=alsa:resample=yes:device=[plughw:0,3]`` Lets ALSA resample and
sets the device-name as first card, fourth device.
Available audio output drivers are:
``alsa`` (Linux only)

View File

@ -109,6 +109,7 @@ static bool get_desc(struct m_obj_desc *dst, int index)
.priv_size = ao->priv_size,
.priv_defaults = ao->priv_defaults,
.options = ao->options,
.global_opts = ao->global_opts,
.hidden = ao->encode,
.p = ao,
};

View File

@ -60,7 +60,7 @@ struct ao_alsa_opts {
};
#define OPT_BASE_STRUCT struct ao_alsa_opts
const struct m_sub_options ao_alsa_conf = {
static const struct m_sub_options ao_alsa_conf = {
.opts = (const struct m_option[]) {
OPT_STRING("alsa-device", device, 0),
OPT_FLAG("alsa-resample", resample, 0),
@ -1180,4 +1180,5 @@ const struct ao_driver audio_out_alsa = {
OPT_SUBOPT_LEGACY("ignore-chmap", "alsa-ignore-chmap"),
{0}
},
.global_opts = &ao_alsa_conf,
};

View File

@ -181,6 +181,7 @@ struct ao_driver {
int priv_size;
const void *priv_defaults;
const struct m_option *options;
const struct m_sub_options *global_opts;
};
// These functions can be called by AOs.

View File

@ -406,6 +406,18 @@ static void add_sub_options(struct m_config *config,
add_options(config, &next, new_optstruct, new_optstruct_def, subopts->opts);
}
static void add_global_subopts(struct m_config *config,
const struct m_obj_list *list)
{
struct m_obj_desc desc;
for (int n = 0; ; n++) {
if (!list->get_desc(&desc, n))
break;
if (desc.global_opts)
add_sub_options(config, NULL, desc.global_opts);
}
}
// Initialize a field with a given value. In case this is dynamic data, it has
// to be allocated and copied. src can alias dst, also can be NULL.
static void init_opt_inplace(const struct m_option *opt, void *dst,
@ -477,6 +489,10 @@ static void m_config_add_option(struct m_config *config,
init_opt_inplace(arg, co.data, co.default_data);
}
// (The deprecation_message check is a hack to exclude --vo-defaults etc.)
if (arg->type == &m_option_type_obj_settings_list && !arg->deprecation_message)
add_global_subopts(config, (const struct m_obj_list *)arg->priv);
if (arg->name[0]) // no own name -> hidden
MP_TARRAY_APPEND(config, config->opts, config->num_opts, co);
}

View File

@ -130,6 +130,8 @@ struct m_obj_desc {
// Set by m_obj_list_find(). If the requested name is an old alias, this
// is set to the old name (while the name field uses the new name).
const char *replaced_name;
// For convenience: these are added as global command-line options.
const struct m_sub_options *global_opts;
};
// Extra definition needed for \ref m_option_type_obj_settings_list options.

View File

@ -74,7 +74,6 @@ extern const struct m_sub_options input_config;
extern const struct m_sub_options encode_config;
extern const struct m_sub_options image_writer_conf;
extern const struct m_sub_options gl_video_conf;
extern const struct m_sub_options vo_opengl_conf;
extern const struct m_sub_options ao_alsa_conf;
extern const struct m_obj_list vf_obj_list;
@ -473,7 +472,8 @@ const m_option_t mp_opts[] = {
//---------------------- libao/libvo options ------------------------
OPT_SETTINGSLIST("ao", audio_driver_list, 0, &ao_obj_list, ),
OPT_SETTINGSLIST("ao-defaults", ao_defs, 0, &ao_obj_list, ),
OPT_SETTINGSLIST("ao-defaults", ao_defs, 0, &ao_obj_list,
.deprecation_message = "deprecated, use global options"),
OPT_STRING("audio-device", audio_device, 0),
OPT_STRING("audio-client-name", audio_client_name, 0),
OPT_FLAG("audio-fallback-to-null", ao_null_fallback, 0),
@ -648,10 +648,6 @@ const m_option_t mp_opts[] = {
#if HAVE_GL
OPT_SUBSTRUCT("", gl_video_opts, gl_video_conf, 0),
OPT_SUBSTRUCT("", vo_opengl_opts, vo_opengl_conf, 0),
#endif
#if HAVE_ALSA
OPT_SUBSTRUCT("", ao_alsa_opts, ao_alsa_conf, 0),
#endif
#if HAVE_ENCODING

View File

@ -334,8 +334,6 @@ typedef struct MPOpts {
char *input_file;
struct gl_video_opts *gl_video_opts;
struct vo_opengl_opts *vo_opengl_opts;
struct ao_alsa_opts *ao_alsa_opts;
} MPOpts;
extern const m_option_t mp_opts[];

View File

@ -174,6 +174,7 @@ static bool get_desc(struct m_obj_desc *dst, int index)
.priv_size = vo->priv_size,
.priv_defaults = vo->priv_defaults,
.options = vo->options,
.global_opts = vo->global_opts,
.hidden = vo->encode || !strcmp(vo->name, "opengl-cb"),
.p = vo,
};

View File

@ -296,6 +296,10 @@ struct vo_driver {
// List of options to parse into priv struct (requires priv_size to be set)
const struct m_option *options;
// Global options to register if the VO is compiled in.
// mp_get_config_group() or other function can be used to access them.
const struct m_sub_options *global_opts;
};
struct vo {

View File

@ -63,7 +63,7 @@ struct vo_opengl_opts {
};
#define OPT_BASE_STRUCT struct vo_opengl_opts
const struct m_sub_options vo_opengl_conf = {
static const struct m_sub_options vo_opengl_conf = {
.opts = (const m_option_t[]) {
OPT_FLAG("opengl-glfinish", use_glFinish, 0),
OPT_FLAG("opengl-waitvsync", waitvsync, 0),
@ -487,4 +487,5 @@ const struct vo_driver video_out_opengl = {
.uninit = uninit,
.priv_size = sizeof(struct gl_priv),
.options = legacy_options,
.global_opts = &vo_opengl_conf,
};