diff options
Diffstat (limited to 'player')
-rw-r--r-- | player/command.c | 395 |
1 files changed, 225 insertions, 170 deletions
diff --git a/player/command.c b/player/command.c index ffe9683adb..9c6bce6aa1 100644 --- a/player/command.c +++ b/player/command.c @@ -5623,7 +5623,7 @@ static void cmd_rescan_external_files(void *p) } autoload_external_files(mpctx); - if (cmd->args[0].v.i && mpctx->playback_initialized) { + if (!cmd->args[0].v.i && mpctx->playback_initialized) { // somewhat fuzzy and not ideal struct track *a = select_default_track(mpctx, 0, STREAM_AUDIO); if (a && a->is_external) @@ -5752,7 +5752,7 @@ static void cmd_define_input_section(void *p) struct mp_cmd_ctx *cmd = p; struct MPContext *mpctx = cmd->mpctx; mp_input_define_section(mpctx->input, cmd->args[0].v.s, "<api>", - cmd->args[1].v.s, !!cmd->args[2].v.i, + cmd->args[1].v.s, !cmd->args[2].v.i, cmd->cmd->sender); } @@ -6005,263 +6005,318 @@ static void cmd_load_script(void *p) cmd->success = false; } -// This does not specify the real destination of the command parameter values, -// it just provides a dummy for the OPT_ macros. -#define OPT_BASE_STRUCT struct mp_cmd_arg -#define ARG(t) "", v. t - /* This array defines all known commands. - * The first field is an id used to recognize the command. - * The second is the command name used in slave mode and input.conf. - * Then comes the definition of each argument, first mandatory arguments - * (ARG_INT, ARG_FLOAT, ARG_STRING) if any, then optional arguments - * (OARG_INT(default), etc) if any. The command will be given the default - * argument value if the user didn't give enough arguments to specify it. - * A command can take a maximum of MP_CMD_DEF_MAX_ARGS arguments, or more - * if the command uses varargs. + * The first field the command name used in libmpv and input.conf. + * The second field is the handler function (see mp_cmd_def.handler and + * run_command()). + * Then comes the definition of each argument. They are defined like options, + * except that the result is parsed into mp_cmd.args[] (thus the option variable + * is a field in the mp_cmd_arg union field). Arguments are optional if either + * defval is set (usually via OPTDEF_ macros), or the MP_CMD_OPT_ARG flag is + * set, or if it's the last argument and .vararg is set. If .vararg is set, the + * command has an arbitrary number of arguments, all using the type indicated by + * the last argument (they are appended to mp_cmd.args[] starting at the last + * argument's index). + * Arguments have named, which can be used by named argument functions, e.g. in + * Lua with mp.command_native(). */ -#define ARG_INT OPT_INT(ARG(i), 0) -#define ARG_FLOAT OPT_FLOAT(ARG(f), 0) -#define ARG_DOUBLE OPT_DOUBLE(ARG(d), 0) -#define ARG_STRING OPT_STRING(ARG(s), 0) -#define ARG_CHOICE(c) OPT_CHOICE(ARG(i), 0, c) -#define ARG_CHOICE_OR_INT(...) OPT_CHOICE_OR_INT(ARG(i), 0, __VA_ARGS__) -#define ARG_TIME OPT_TIME(ARG(d), 0) -#define OARG_DOUBLE(def) OPT_DOUBLE(ARG(d), 0, OPTDEF_DOUBLE(def)) -#define OARG_INT(def) OPT_INT(ARG(i), 0, OPTDEF_INT(def)) -#define OARG_CHOICE(def, c) OPT_CHOICE(ARG(i), 0, c, OPTDEF_INT(def)) -#define OARG_FLAGS(def, c) OPT_FLAGS(ARG(i), 0, c, OPTDEF_INT(def)) -#define OARG_STRING(def) OPT_STRING(ARG(s), 0, OPTDEF_STR(def)) - -#define OARG_CYCLEDIR(def) OPT_CYCLEDIR(ARG(d), 0, OPTDEF_DOUBLE(def)) +// This does not specify the real destination of the command parameter values, +// it just provides a dummy for the OPT_ macros. The real destination is an +// array item in mp_cmd.args[], using the index of the option definition. +#define OPT_BASE_STRUCT struct mp_cmd_arg const struct mp_cmd_def mp_cmds[] = { { "ignore", cmd_ignore, .is_ignore = true }, - { "seek", cmd_seek, { - ARG_TIME, - OARG_FLAGS(4|0, ({"relative", 4|0}, {"-", 4|0}, - {"absolute-percent", 4|1}, - {"absolute", 4|2}, - {"relative-percent", 4|3}, - {"keyframes", 32|8}, - {"exact", 32|16})), - // backwards compatibility only - OARG_CHOICE(0, ({"unused", 0}, {"default-precise", 0}, + { "seek", cmd_seek, + { + OPT_TIME("target", v.d, 0), + OPT_FLAGS("flags", v.i, 0, + ({"relative", 4|0}, {"-", 4|0}, + {"absolute-percent", 4|1}, + {"absolute", 4|2}, + {"relative-percent", 4|3}, + {"keyframes", 32|8}, + {"exact", 32|16}), + OPTDEF_INT(4|0)), + // backwards compatibility only + OPT_CHOICE("legacy", v.i, MP_CMD_OPT_ARG, + ({"unused", 0}, {"default-precise", 0}, {"keyframes", 32|8}, {"exact", 32|16})), }, .allow_auto_repeat = true, .scalable = true, }, - { "revert-seek", cmd_revert_seek, { - OARG_FLAGS(0, ({"mark", 1})), - }}, - { "quit", cmd_quit, { OARG_INT(0) }, + { "revert-seek", cmd_revert_seek, + {OPT_FLAGS("flags", v.i, MP_CMD_OPT_ARG, ({"mark", 1}))}, + }, + { "quit", cmd_quit, { OPT_INT("code", v.i, MP_CMD_OPT_ARG) }, .priv = &(const bool){0}, .is_abort = true }, - { "quit-watch-later", cmd_quit, { OARG_INT(0) }, + { "quit-watch-later", cmd_quit, { OPT_INT("code", v.i, MP_CMD_OPT_ARG) }, .priv = &(const bool){1}, .is_abort = true }, { "stop", cmd_stop, .is_abort = true }, { "frame-step", cmd_frame_step, .allow_auto_repeat = true, .on_updown = true }, { "frame-back-step", cmd_frame_back_step, .allow_auto_repeat = true }, - { "playlist-next", cmd_playlist_next_prev, { - OARG_CHOICE(0, ({"weak", 0}, - {"force", 1})), + { "playlist-next", cmd_playlist_next_prev, + { + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, ({"weak", 0}, + {"force", 1})), }, .is_soft_abort = true, .priv = &(const int){1}, }, - { "playlist-prev", cmd_playlist_next_prev, { - OARG_CHOICE(0, ({"weak", 0}, - {"force", 1})), + { "playlist-prev", cmd_playlist_next_prev, + { + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, ({"weak", 0}, + {"force", 1})), }, .is_soft_abort = true, .priv = &(const int){-1}, }, { "playlist-shuffle", cmd_playlist_shuffle, }, - { "sub-step", cmd_sub_step_seek, { ARG_INT }, .allow_auto_repeat = true, - .priv = &(const bool){true} }, - { "sub-seek", cmd_sub_step_seek, { ARG_INT }, .allow_auto_repeat = true, - .priv = &(const bool){false} }, - { "print-text", cmd_print_text, { ARG_STRING }, .allow_auto_repeat = true }, - { "show-text", cmd_show_text, { ARG_STRING, OARG_INT(-1), OARG_INT(0) }, + { "sub-step", cmd_sub_step_seek, { OPT_INT("skip", v.i, 0) }, + .allow_auto_repeat = true, .priv = &(const bool){true} }, + { "sub-seek", cmd_sub_step_seek, { OPT_INT("skip", v.i, 0) }, + .allow_auto_repeat = true, .priv = &(const bool){false} }, + { "print-text", cmd_print_text, { OPT_STRING("text", v.s, 0) }, + .allow_auto_repeat = true }, + { "show-text", cmd_show_text, { OPT_STRING("text", v.s, 0), + OPT_INT("duration", v.i, 0, OPTDEF_INT(-1)), + OPT_INT("level", v.i, MP_CMD_OPT_ARG), }, .allow_auto_repeat = true}, - { "expand-text", cmd_expand_text, { ARG_STRING } }, + { "expand-text", cmd_expand_text, { OPT_STRING("text", v.s, 0) } }, { "show-progress", cmd_show_progress, .allow_auto_repeat = true}, - { "sub-add", cmd_track_add, { - ARG_STRING, - OARG_CHOICE(0, ({"select", 0}, {"auto", 1}, {"cached", 2})), - OARG_STRING(""), OARG_STRING(""), + + { "sub-add", cmd_track_add, + { + OPT_STRING("url", v.s, 0), + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"select", 0}, {"auto", 1}, {"cached", 2})), + OPT_STRING("title", v.s, MP_CMD_OPT_ARG), + OPT_STRING("lang", v.s, MP_CMD_OPT_ARG), }, .priv = &(const int){STREAM_SUB}, .spawn_thread = true, }, - { "sub-remove", cmd_track_remove, { OARG_INT(-1) }, + { "audio-add", cmd_track_add, + { + OPT_STRING("url", v.s, 0), + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"select", 0}, {"auto", 1}, {"cached", 2})), + OPT_STRING("title", v.s, MP_CMD_OPT_ARG), + OPT_STRING("lang", v.s, MP_CMD_OPT_ARG), + }, + .priv = &(const int){STREAM_AUDIO}, + .spawn_thread = true, + }, + + { "sub-remove", cmd_track_remove, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) }, .priv = &(const int){STREAM_SUB}, }, - { "sub-reload", cmd_track_reload, { OARG_INT(-1) }, + { "audio-remove", cmd_track_remove, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) }, + .priv = &(const int){STREAM_AUDIO}, }, + + { "sub-reload", cmd_track_reload, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) }, .priv = &(const int){STREAM_SUB}, .spawn_thread = true, }, + { "audio-reload", cmd_track_reload, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) }, + .priv = &(const int){STREAM_AUDIO}, + .spawn_thread = true, + }, + + { "rescan-external-files", cmd_rescan_external_files, + { + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"keep-selection", 1}, + {"reselect", 0})), + }, + .spawn_thread = true, + }, { "tv-last-channel", cmd_tv_last_channel, }, - { "screenshot", cmd_screenshot, { - OARG_FLAGS(4|2, ({"video", 4|0}, {"-", 4|0}, - {"window", 4|1}, - {"subtitles", 4|2}, - {"each-frame", 8})), - // backwards compatibility - OARG_CHOICE(0, ({"unused", 0}, {"single", 0}, - {"each-frame", 8})), + { "screenshot", cmd_screenshot, + { + OPT_FLAGS("flags", v.i, 0, + ({"video", 4|0}, {"-", 4|0}, + {"window", 4|1}, + {"subtitles", 4|2}, + {"each-frame", 8}), + OPTDEF_INT(4|2)), + // backwards compatibility + OPT_CHOICE("legacy", v.i, MP_CMD_OPT_ARG, + ({"unused", 0}, {"single", 0}, + {"each-frame", 8})), }, .spawn_thread = true, }, - { "screenshot-to-file", cmd_screenshot_to_file, { - ARG_STRING, - OARG_CHOICE(2, ({"video", 0}, + { "screenshot-to-file", cmd_screenshot_to_file, + { + OPT_STRING("filename", v.s, 0), + OPT_CHOICE("flags", v.i, 0, + ({"video", 0}, {"window", 1}, - {"subtitles", 2})), + {"subtitles", 2}), + OPTDEF_INT(2)), }, .spawn_thread = true, }, - { "screenshot-raw", cmd_screenshot_raw, { - OARG_CHOICE(2, ({"video", 0}, + { "screenshot-raw", cmd_screenshot_raw, + { + OPT_CHOICE("flags", v.i, 0, + ({"video", 0}, {"window", 1}, - {"subtitles", 2})), - }}, - { "loadfile", cmd_loadfile, { - ARG_STRING, - OARG_CHOICE(0, ({"replace", 0}, + {"subtitles", 2}), + OPTDEF_INT(2)), + }, + }, + { "loadfile", cmd_loadfile, + { + OPT_STRING("url", v.s, 0), + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"replace", 0}, {"append", 1}, {"append-play", 2})), - OPT_KEYVALUELIST(ARG(str_list), MP_CMD_OPT_ARG), - }}, - { "loadlist", cmd_loadlist, { - ARG_STRING, - OARG_CHOICE(0, ({"replace", 0}, - {"append", 1})), - }}, + OPT_KEYVALUELIST("options", v.str_list, MP_CMD_OPT_ARG), + }, + }, + { "loadlist", cmd_loadlist, { OPT_STRING("url", v.s, 0), + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"replace", 0}, {"append", 1})), }}, { "playlist-clear", cmd_playlist_clear }, - { "playlist-remove", cmd_playlist_remove, { - ARG_CHOICE_OR_INT(0, INT_MAX, ({"current", -1})), - }}, - { "playlist-move", cmd_playlist_move, { ARG_INT, ARG_INT } }, - { "run", cmd_run, { ARG_STRING, ARG_STRING }, .vararg = true }, + { "playlist-remove", cmd_playlist_remove, + {OPT_CHOICE_OR_INT("index", v.i, MP_CMD_OPT_ARG, 0, INT_MAX, + ({"current", -1}))}, + }, + { "playlist-move", cmd_playlist_move, { OPT_INT("index1", v.i, 0), + OPT_INT("index2", v.i, 0), }}, + { "run", cmd_run, { OPT_STRING("command", v.s, 0), + OPT_STRING("args", v.s, 0), }, + .vararg = true, + }, { "subprocess", cmd_subprocess, { OPT_STRINGLIST("args", v.str_list, 0), OPT_FLAG("playback_only", v.i, 0, OPTDEF_INT(1)), OPT_BYTE_SIZE("capture_size", v.i64, 0, 0, INT_MAX, OPTDEF_INT64(64 * 1024 * 1024)), - OPT_FLAG("capture_stdout", v.i, 0, OPTDEF_INT(0)), - OPT_FLAG("capture_stderr", v.i, 0, OPTDEF_INT(0)), + OPT_FLAG("capture_stdout", v.i, MP_CMD_OPT_ARG), + OPT_FLAG("capture_stderr", v.i, MP_CMD_OPT_ARG), }, .spawn_thread = true, .can_abort = true, }, - { "set", cmd_set, { ARG_STRING, ARG_STRING } }, - { "change-list", cmd_change_list, { ARG_STRING, ARG_STRING, ARG_STRING } }, - { "add", cmd_add_cycle, { ARG_STRING, OARG_DOUBLE(1) }, + { "set", cmd_set, {OPT_STRING("name", v.s, 0), OPT_STRING("value", v.s, 0)}}, + { "change-list", cmd_change_list, { OPT_STRING("name", v.s, 0), + OPT_STRING("operation", v.s, 0), + OPT_STRING("value", v.s, 0) }}, + { "add", cmd_add_cycle, { OPT_STRING("name", v.s, 0), + OPT_DOUBLE("value", v.d, 0, OPTDEF_DOUBLE(1)), }, .allow_auto_repeat = true, .scalable = true, }, - { "cycle", cmd_add_cycle, { - ARG_STRING, - OARG_CYCLEDIR(1), - }, + { "cycle", cmd_add_cycle, { OPT_STRING("name", v.s, 0), + OPT_CYCLEDIR("value", v.d, 0, OPTDEF_DOUBLE(1)), }, .allow_auto_repeat = true, .scalable = true, .priv = "", }, - { "multiply", cmd_multiply, { ARG_STRING, ARG_DOUBLE }, + { "multiply", cmd_multiply, { OPT_STRING("name", v.s, 0), + OPT_DOUBLE("value", v.d, 0)}, .allow_auto_repeat = true}, - { "cycle-values", cmd_cycle_values, { ARG_STRING, ARG_STRING, ARG_STRING }, + { "cycle-values", cmd_cycle_values, { OPT_STRING("arg0", v.s, 0), + OPT_STRING("arg1", v.s, 0), + OPT_STRING("argN", v.s, 0), }, .vararg = true}, - { "enable-section", cmd_enable_input_section, { - ARG_STRING, - OARG_FLAGS(0, ({"default", 0}, + { "enable-section", cmd_enable_input_section, + { + OPT_STRING("name", v.s, 0), + OPT_FLAGS("flags", v.i, MP_CMD_OPT_ARG, + ({"default", 0}, {"exclusive", MP_INPUT_EXCLUSIVE}, {"allow-hide-cursor", MP_INPUT_ALLOW_HIDE_CURSOR}, {"allow-vo-dragging", MP_INPUT_ALLOW_VO_DRAGGING})), - }}, - { "disable-section", cmd_disable_input_section, { ARG_STRING } }, - { "define-section", cmd_define_input_section, { - ARG_STRING, - ARG_STRING, - OARG_CHOICE(1, ({"default", 1}, - {"force", 0})), - }}, + } + }, + { "disable-section", cmd_disable_input_section, + {OPT_STRING("name", v.s, 0) }}, + { "define-section", cmd_define_input_section, + { + OPT_STRING("name", v.s, 0), + OPT_STRING("contents", v.s, 0), + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"default", 0}, {"force", 1})), + }, + }, { "ab-loop", cmd_ab_loop }, { "drop-buffers", cmd_drop_buffers, }, - { "af", cmd_filter, { ARG_STRING, ARG_STRING }, - .priv = &(const int){STREAM_AUDIO}, }, - { "af-command", cmd_filter_command, { ARG_STRING, ARG_STRING, ARG_STRING }, - .priv = &(const int){STREAM_AUDIO}, }, - { "ao-reload", cmd_ao_reload }, + { "af", cmd_filter, { OPT_STRING("operation", v.s, 0), + OPT_STRING("value", v.s, 0), }, + .priv = &(const int){STREAM_AUDIO} }, + { "vf", cmd_filter, { OPT_STRING("operation", v.s, 0), + OPT_STRING("value", v.s, 0), }, + .priv = &(const int){STREAM_VIDEO} }, + + { "af-command", cmd_filter_command, { OPT_STRING("label", v.s, 0), + OPT_STRING("command", v.s, 0), + OPT_STRING("argument", v.s, 0), }, + .priv = &(const int){STREAM_AUDIO} }, + { "vf-command", cmd_filter_command, { OPT_STRING("label", v.s, 0), + OPT_STRING("command", v.s, 0), + OPT_STRING("argument", v.s, 0), }, + .priv = &(const int){STREAM_VIDEO} }, - { "vf", cmd_filter, { ARG_STRING, ARG_STRING }, - .priv = &(const int){STREAM_VIDEO}, }, - { "vf-command", cmd_filter_command, { ARG_STRING, ARG_STRING, ARG_STRING }, - .priv = &(const int){STREAM_VIDEO}, }, + { "ao-reload", cmd_ao_reload }, - { "script-binding", cmd_script_binding, { ARG_STRING }, + { "script-binding", cmd_script_binding, { OPT_STRING("name", v.s, 0) }, .allow_auto_repeat = true, .on_updown = true}, - { "script-message", cmd_script_message, { ARG_STRING }, .vararg = true }, - { "script-message-to", cmd_script_message_to, { ARG_STRING, ARG_STRING }, + { "script-message", cmd_script_message, { OPT_STRING("args", v.s, 0) }, + .vararg = true }, + { "script-message-to", cmd_script_message_to, { OPT_STRING("target", v.s, 0), + OPT_STRING("args", v.s, 0) }, .vararg = true }, - { "overlay-add", cmd_overlay_add, - { ARG_INT, ARG_INT, ARG_INT, ARG_STRING, ARG_INT, ARG_STRING, ARG_INT, - ARG_INT, ARG_INT }}, - { "overlay-remove", cmd_overlay_remove, { ARG_INT } }, + { "overlay-add", cmd_overlay_add, { OPT_INT("id", v.i, 0), + OPT_INT("x", v.i, 0), + OPT_INT("y", v.i, 0), + OPT_STRING("file", v.s, 0), + OPT_INT("offset", v.i, 0), + OPT_STRING("fmt", v.s, 0), + OPT_INT("w", v.i, 0), + OPT_INT("h", v.i, 0), + OPT_INT("stride", v.i, 0), }}, + { "overlay-remove", cmd_overlay_remove, { OPT_INT("id", v.i, 0) } }, { "write-watch-later-config", cmd_write_watch_later_config }, - { "hook-add", cmd_hook_add, { ARG_STRING, ARG_INT, ARG_INT } }, - { "hook-ack", cmd_hook_ack, { ARG_INT } }, - - { "mouse", cmd_mouse, { - ARG_INT, ARG_INT, // coordinate (x, y) - OARG_INT(-1), // button number - OARG_CHOICE(0, ({"single", 0}, - {"double", 1})), - }}, - { "keypress", cmd_key, { ARG_STRING }, .priv = &(const int){0}}, - { "keydown", cmd_key, { ARG_STRING }, .priv = &(const int){MP_KEY_STATE_DOWN}}, - { "keyup", cmd_key, { OARG_STRING("") }, .priv = &(const int){MP_KEY_STATE_UP}}, - - { "audio-add", cmd_track_add, { - ARG_STRING, - OARG_CHOICE(0, ({"select", 0}, {"auto", 1}, {"cached", 2})), - OARG_STRING(""), OARG_STRING(""), - }, - .priv = &(const int){STREAM_AUDIO}, - .spawn_thread = true, - }, - { "audio-remove", cmd_track_remove, { OARG_INT(-1) }, - .priv = &(const int){STREAM_AUDIO}, }, - { "audio-reload", cmd_track_reload, { OARG_INT(-1) }, - .priv = &(const int){STREAM_AUDIO}, - .spawn_thread = true, - }, - - { "rescan-external-files", cmd_rescan_external_files, { - OARG_CHOICE(1, ({"keep-selection", 0}, - {"reselect", 1})), - }, - .spawn_thread = true, - }, - - { "apply-profile", cmd_apply_profile, {ARG_STRING } }, - - { "load-script", cmd_load_script, {ARG_STRING} }, + { "hook-add", cmd_hook_add, { OPT_STRING("arg0", v.s, 0), + OPT_INT("arg1", v.i, 0), + OPT_INT("arg2", v.i, 0) }}, + { "hook-ack", cmd_hook_ack, { OPT_INT("arg0", v.i, 0) }}, + + { "mouse", cmd_mouse, { OPT_INT("x", v.i, 0), + OPT_INT("y", v.i, 0), + OPT_INT("button", v.i, 0, OPTDEF_INT(-1)), + OPT_CHOICE("mode", v.i, MP_CMD_OPT_ARG, + ({"single", 0}, {"double", 1})), }}, + { "keypress", cmd_key, { OPT_STRING("name", v.s, 0) }, + .priv = &(const int){0}}, + { "keydown", cmd_key, { OPT_STRING("name", v.s, 0) }, + .priv = &(const int){MP_KEY_STATE_DOWN}}, + { "keyup", cmd_key, { OPT_STRING("name", v.s, MP_CMD_OPT_ARG) }, + .priv = &(const int){MP_KEY_STATE_UP}}, + + { "apply-profile", cmd_apply_profile, {OPT_STRING("name", v.s, 0)} }, + + { "load-script", cmd_load_script, {OPT_STRING("filename", v.s, 0)} }, {0} }; |