summaryrefslogtreecommitdiffstats
path: root/player/command.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-09-01 20:00:43 +0200
committerwm4 <wm4@nowhere>2016-09-01 20:00:43 +0200
commitd32bee5f019f2c51839df16b7c7955dc33651cbe (patch)
tree96424f3477a67ca6b5f6220295bf4c906ac6106a /player/command.c
parent17dbb39dec1fcd3280f86e480a7191b6f78cbbcc (diff)
downloadmpv-d32bee5f019f2c51839df16b7c7955dc33651cbe.tar.bz2
mpv-d32bee5f019f2c51839df16b7c7955dc33651cbe.tar.xz
command: add options to property list
Now options are accessible through the property list as well, which unifies them to a degree. Not all options support runtime changes (meaning affected components need to be restarted for the options to take effects). Remove from the manpage those properties which are cleanly mapped to options anyway. From the user-perspective they're just options available through the property interface.
Diffstat (limited to 'player/command.c')
-rw-r--r--player/command.c129
1 files changed, 93 insertions, 36 deletions
diff --git a/player/command.c b/player/command.c
index 7a6820af3e..0d8767e922 100644
--- a/player/command.c
+++ b/player/command.c
@@ -69,6 +69,9 @@
#include "core.h"
struct command_ctx {
+ // All properties, terminated with a {0} item.
+ struct m_property *properties;
+
bool is_idle;
double last_seek_time;
@@ -251,11 +254,12 @@ static char *format_delay(double time)
}
// Property-option bridge. (Maps the property to the option with the same name.)
-static int mp_property_generic_option(void *ctx, struct m_property *prop,
- int action, void *arg)
+static int mp_property_generic_option_do(void *ctx, struct m_property *prop,
+ int action, void *arg, bool force)
{
MPContext *mpctx = ctx;
const char *optname = prop->name;
+ int flags = mpctx->initialized && !force ? M_SETOPT_RUNTIME : 0;
struct m_config_option *opt = m_config_get_co(mpctx->mconfig,
bstr0(optname));
@@ -272,12 +276,36 @@ static int mp_property_generic_option(void *ctx, struct m_property *prop,
m_option_copy(opt->opt, arg, valptr);
return M_PROPERTY_OK;
case M_PROPERTY_SET:
- m_option_copy(opt->opt, valptr, arg);
+ if (m_config_set_option_raw(mpctx->mconfig, opt, arg, flags) < 0)
+ return M_PROPERTY_ERROR;
return M_PROPERTY_OK;
}
return M_PROPERTY_NOT_IMPLEMENTED;
}
+static int mp_property_generic_option(void *ctx, struct m_property *prop,
+ int action, void *arg)
+{
+ return mp_property_generic_option_do(ctx, prop, action, arg, true);
+}
+
+static int mp_property_generic_option_bridge(void *ctx, struct m_property *prop,
+ int action, void *arg)
+{
+ return mp_property_generic_option_do(ctx, prop, action, arg, false);
+}
+
+// Dumb special-case: the option name ends in a "*".
+static int mp_property_generic_option_star(void *ctx, struct m_property *prop,
+ int action, void *arg)
+{
+ struct m_property prop2 = *prop;
+ char name[80];
+ snprintf(name, sizeof(name), "%s*", prop->name);
+ prop2.name = name;
+ return mp_property_generic_option_bridge(ctx, &prop2, action, arg);
+}
+
/// Playback speed (RW)
static int mp_property_playback_speed(void *ctx, struct m_property *prop,
int action, void *arg)
@@ -3639,11 +3667,12 @@ static int mp_property_option_info(void *ctx, struct m_property *prop,
return M_PROPERTY_NOT_IMPLEMENTED;
}
-static const struct m_property mp_properties[];
-
static int mp_property_list(void *ctx, struct m_property *prop,
int action, void *arg)
{
+ struct MPContext *mpctx = ctx;
+ struct command_ctx *cmd = mpctx->command_ctx;
+
switch (action) {
case M_PROPERTY_GET_TYPE:
*(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_STRING_LIST};
@@ -3651,9 +3680,9 @@ static int mp_property_list(void *ctx, struct m_property *prop,
case M_PROPERTY_GET: {
char **list = NULL;
int num = 0;
- for (int n = 0; mp_properties[n].name; n++) {
+ for (int n = 0; cmd->properties[n].name; n++) {
MP_TARRAY_APPEND(NULL, list, num,
- talloc_strdup(NULL, mp_properties[n].name));
+ talloc_strdup(NULL, cmd->properties[n].name));
}
MP_TARRAY_APPEND(NULL, list, num, NULL);
*(char ***)arg = list;
@@ -3686,15 +3715,10 @@ static int mp_profile_list(void *ctx, struct m_property *prop,
#define M_PROPERTY_DEPRECATED_ALIAS(name, real_property) \
{(name), mp_property_deprecated_alias, .priv = (real_property)}
-/// All properties available in MPlayer.
-/** \ingroup Properties
- */
-static const struct m_property mp_properties[] = {
+// Base list of properties. This does not include option-mapped properties.
+static const struct m_property mp_properties_base[] = {
// General
- {"osd-level", mp_property_generic_option},
{"osd-scale", property_osd_helper},
- {"loop", mp_property_generic_option},
- {"loop-file", mp_property_generic_option},
{"speed", mp_property_playback_speed},
{"audio-speed-correction", mp_property_av_speed_correction, .priv = "a"},
{"video-speed-correction", mp_property_av_speed_correction, .priv = "v"},
@@ -3706,12 +3730,12 @@ static const struct m_property mp_properties[] = {
{"media-title", mp_property_media_title},
{"stream-path", mp_property_stream_path},
{"stream-capture", mp_property_stream_capture},
- {"demuxer", mp_property_demuxer},
+ {"demuxer", mp_property_demuxer}, // conflicts with option
{"file-format", mp_property_file_format},
{"stream-pos", mp_property_stream_pos},
{"stream-end", mp_property_stream_end},
{"duration", mp_property_duration},
- M_PROPERTY_DEPRECATED_ALIAS("length", "duration"),
+ M_PROPERTY_DEPRECATED_ALIAS("length", "duration"), // conflicts with option
{"avsync", mp_property_avsync},
{"total-avsync-change", mp_property_total_avsync_change},
{"drop-frame-count", mp_property_drop_frame_cnt},
@@ -3742,7 +3766,7 @@ static const struct m_property mp_properties[] = {
{"eof-reached", mp_property_eof_reached},
{"seeking", mp_property_seeking},
{"playback-abort", mp_property_playback_abort},
- {"cache", mp_property_cache},
+ {"cache", mp_property_cache}, // conflicts with option
{"cache-free", mp_property_cache_free},
{"cache-used", mp_property_cache_used},
{"cache-size", mp_property_cache_size},
@@ -3753,11 +3777,10 @@ static const struct m_property mp_properties[] = {
{"demuxer-cache-idle", mp_property_demuxer_cache_idle},
{"cache-buffering-state", mp_property_cache_buffering},
{"paused-for-cache", mp_property_paused_for_cache},
- {"hr-seek", mp_property_generic_option},
{"clock", mp_property_clock},
{"seekable", mp_property_seekable},
{"partially-seekable", mp_property_partially_seekable},
- {"idle", mp_property_idle},
+ {"idle", mp_property_idle}, // conflicts with option
{"chapter-list", mp_property_list_chapters},
{"track-list", property_list_tracks},
@@ -3772,7 +3795,6 @@ static const struct m_property mp_properties[] = {
// Audio
{"mixer-active", mp_property_mixer_active},
{"volume", mp_property_volume},
- {"volume-max", mp_property_generic_option},
{"mute", mp_property_mute},
{"ao-volume", mp_property_ao_volume},
{"ao-mute", mp_property_ao_mute},
@@ -3781,6 +3803,7 @@ static const struct m_property mp_properties[] = {
{"audio-codec", mp_property_audio_codec},
{"audio-params", mp_property_audio_params},
{"audio-out-params", mp_property_audio_out_params},
+ // conflicts with option
M_PROPERTY_DEPRECATED_ALIAS("audio-samplerate", "audio-params/samplerate"),
M_PROPERTY_DEPRECATED_ALIAS("audio-channels", "audio-params/channel-count"),
{"aid", mp_property_audio},
@@ -3793,12 +3816,10 @@ static const struct m_property mp_properties[] = {
// Video
{"fullscreen", mp_property_fullscreen},
{"deinterlace", mp_property_deinterlace},
- {"field-dominance", mp_property_generic_option},
{"taskbar-progress", mp_property_taskbar_progress},
{"ontop", mp_property_ontop},
{"border", mp_property_border},
{"on-all-workspaces", mp_property_all_workspaces},
- {"framedrop", mp_property_generic_option},
{"gamma", mp_property_video_color},
{"brightness", mp_property_video_color},
{"contrast", mp_property_video_color},
@@ -3827,7 +3848,7 @@ static const struct m_property mp_properties[] = {
{"vo-configured", mp_property_vo_configured},
{"vo-performance", mp_property_vo_performance},
{"current-vo", mp_property_vo},
- {"fps", mp_property_fps},
+ {"fps", mp_property_fps}, // conflicts with option
{"estimated-vf-fps", mp_property_vf_fps},
{"video-aspect", mp_property_aspect},
{"vid", mp_property_video},
@@ -3924,18 +3945,18 @@ static const struct m_property mp_properties[] = {
{"property-list", mp_property_list},
{"profile-list", mp_profile_list},
- // compatibility
M_PROPERTY_ALIAS("video", "vid"),
M_PROPERTY_ALIAS("audio", "aid"),
M_PROPERTY_ALIAS("sub", "sid"),
+
+ // compatibility
M_PROPERTY_ALIAS("colormatrix", "video-params/colormatrix"),
M_PROPERTY_ALIAS("colormatrix-input-range", "video-params/colorlevels"),
M_PROPERTY_ALIAS("colormatrix-primaries", "video-params/primaries"),
M_PROPERTY_ALIAS("colormatrix-gamma", "video-params/gamma"),
+ // conflicts with option
M_PROPERTY_DEPRECATED_ALIAS("audio-format", "audio-codec-name"),
-
- {0},
};
// Each entry describes which properties an event (possibly) changes.
@@ -4013,10 +4034,11 @@ uint64_t mp_get_property_event_mask(const char *name)
// Return an ID for the property. It might not be unique, but is good enough
// for property change handling. Return -1 if property unknown.
-int mp_get_property_id(const char *name)
+int mp_get_property_id(struct MPContext *mpctx, const char *name)
{
- for (int n = 0; mp_properties[n].name; n++) {
- if (match_property(mp_properties[n].name, name))
+ struct command_ctx *ctx = mpctx->command_ctx;
+ for (int n = 0; ctx->properties[n].name; n++) {
+ if (match_property(ctx->properties[n].name, name))
return n;
}
return -1;
@@ -4042,7 +4064,8 @@ static bool is_property_set(int action, void *val)
int mp_property_do(const char *name, int action, void *val,
struct MPContext *ctx)
{
- int r = m_property_do(ctx->log, mp_properties, name, action, val, ctx);
+ struct command_ctx *cmd = ctx->command_ctx;
+ int r = m_property_do(ctx->log, cmd->properties, name, action, val, ctx);
if (r == M_PROPERTY_OK && is_property_set(action, val))
mp_notify_property(ctx, (char *)name);
if (mp_msg_test(ctx->log, MSGL_V) && is_property_set(action, val)) {
@@ -4067,7 +4090,8 @@ int mp_property_do(const char *name, int action, void *val,
char *mp_property_expand_string(struct MPContext *mpctx, const char *str)
{
- return m_properties_expand_string(mp_properties, str, mpctx);
+ struct command_ctx *ctx = mpctx->command_ctx;
+ return m_properties_expand_string(ctx->properties, str, mpctx);
}
// Before expanding properties, parse C-style escapes like "\n"
@@ -4091,12 +4115,12 @@ char *mp_property_expand_escaped_string(struct MPContext *mpctx, const char *str
return r;
}
-void property_print_help(struct mp_log *log)
+void property_print_help(struct MPContext *mpctx)
{
- m_properties_print_help_list(log, mp_properties);
+ struct command_ctx *ctx = mpctx->command_ctx;
+ m_properties_print_help_list(mpctx->log, ctx->properties);
}
-
/* List of default ways to show a property on OSD.
*
* If osd_progbar is set, a bar showing the current position between min/max
@@ -5424,10 +5448,43 @@ void command_uninit(struct MPContext *mpctx)
void command_init(struct MPContext *mpctx)
{
- mpctx->command_ctx = talloc(NULL, struct command_ctx);
- *mpctx->command_ctx = (struct command_ctx){
+ struct command_ctx *ctx = talloc(NULL, struct command_ctx);
+ *ctx = (struct command_ctx){
.last_seek_pts = MP_NOPTS_VALUE,
};
+ mpctx->command_ctx = ctx;
+
+ int num_base = MP_ARRAY_SIZE(mp_properties_base);
+ int num_opts = m_config_get_co_count(mpctx->mconfig);
+ ctx->properties =
+ talloc_zero_array(ctx, struct m_property, num_base + num_opts + 1);
+ memcpy(ctx->properties, mp_properties_base, sizeof(mp_properties_base));
+
+ int count = num_base;
+ for (int n = 0; n < num_opts; n++) {
+ struct m_config_option *co = m_config_get_co_index(mpctx->mconfig, n);
+ assert(co->name[0]);
+ if (!co->data || (co->opt->flags & M_OPT_NOPROP) ||
+ (co->opt->type->flags & M_OPT_TYPE_HAS_CHILD))
+ continue;
+
+ struct m_property prop = {
+ .name = co->name,
+ .call = mp_property_generic_option_bridge,
+ };
+
+ bstr bname = bstr0(prop.name);
+ if (bstr_eatend0(&bname, "*")) {
+ prop.name = bstrto0(ctx, bname);
+ prop.call = mp_property_generic_option_star;
+ }
+
+ // The option might be covered by a manual property already.
+ if (m_property_list_find(ctx->properties, prop.name))
+ continue;
+
+ ctx->properties[count++] = prop;
+ }
}
static void command_event(struct MPContext *mpctx, int event, void *arg)