From 872b7a26549568dc72cae7fae024c4c3a103c845 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 26 Aug 2016 20:19:39 +0200 Subject: vo: remove redundant wakeup Shouldn't matter. Was pointed out by someone. The change should help avoiding extra unneeded wakeups on the VO thread. --- video/out/vo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/video/out/vo.c b/video/out/vo.c index 139b840c23..0d70106ed8 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -665,7 +665,9 @@ bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts) r = false; if (!in->wakeup_pts || next_pts < in->wakeup_pts) { in->wakeup_pts = next_pts; - wakeup_locked(vo); + // If we have to wait, update the vo thread's timer. + if (!r) + wakeup_locked(vo); } } pthread_mutex_unlock(&in->lock); -- cgit v1.2.3 From 37d6604d70c8c594de2817db26356c4c950ac0fd Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 26 Aug 2016 20:22:33 +0200 Subject: x11, wayland: always round up wait times If wait_us is >0 and <500, the wait time gets rounded down 0, effectively turning this into busy waiting. Round it up instead. --- video/out/wayland_common.c | 2 +- video/out/x11_common.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index d4b7a1eecc..3ea4a3f4a6 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -1139,7 +1139,7 @@ void vo_wayland_wait_events(struct vo *vo, int64_t until_time_us) }; int64_t wait_us = until_time_us - mp_time_us(); - int timeout_ms = MPCLAMP((wait_us + 500) / 1000, 0, 10000); + int timeout_ms = MPCLAMP((wait_us + 999) / 1000, 0, 10000); wl_display_dispatch_pending(dp); wl_display_flush(dp); diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 1b780598af..8c51329a13 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -1938,7 +1938,7 @@ void vo_x11_wait_events(struct vo *vo, int64_t until_time_us) { .fd = x11->wakeup_pipe[0], .events = POLLIN }, }; int64_t wait_us = until_time_us - mp_time_us(); - int timeout_ms = MPCLAMP((wait_us + 500) / 1000, 0, 10000); + int timeout_ms = MPCLAMP((wait_us + 999) / 1000, 0, 10000); poll(fds, 2, timeout_ms); -- cgit v1.2.3 From ed62f56a40b7854c957bef2f18003a511a54d82d Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 26 Aug 2016 20:27:46 +0200 Subject: player: avoid some redundant terminal status updates Run term_osd_update() just once per update, instead of twice (once for the status line, and once for the terminal OSD messafe). --- player/osd.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/player/osd.c b/player/osd.c index e2606829be..48bf22b346 100644 --- a/player/osd.c +++ b/player/osd.c @@ -115,17 +115,16 @@ void term_osd_set_subs(struct MPContext *mpctx, const char *text) term_osd_update(mpctx); } -static void term_osd_set_text(struct MPContext *mpctx, const char *text) +static void term_osd_set_text_lazy(struct MPContext *mpctx, const char *text) { if ((mpctx->video_out && mpctx->opts->term_osd != 1) || !mpctx->opts->term_osd || !text) text = ""; // disable talloc_free(mpctx->term_osd_text); mpctx->term_osd_text = talloc_strdup(mpctx, text); - term_osd_update(mpctx); } -static void term_osd_set_status(struct MPContext *mpctx, const char *text) +static void term_osd_set_status_lazy(struct MPContext *mpctx, const char *text) { talloc_free(mpctx->term_osd_status); mpctx->term_osd_status = talloc_strdup(mpctx, text); @@ -134,8 +133,6 @@ static void term_osd_set_status(struct MPContext *mpctx, const char *text) terminal_get_size(&w, &h); if (strlen(mpctx->term_osd_status) > w && !strchr(mpctx->term_osd_status, '\n')) mpctx->term_osd_status[w] = '\0'; - - term_osd_update(mpctx); } static void add_term_osd_bar(struct MPContext *mpctx, char **line, int width) @@ -167,7 +164,7 @@ static bool is_busy(struct MPContext *mpctx) return !mpctx->restart_complete && mp_time_sec() - mpctx->start_timestamp > 0.3; } -static void print_status(struct MPContext *mpctx) +static void term_osd_print_status_lazy(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; @@ -179,13 +176,13 @@ static void print_status(struct MPContext *mpctx) if (opts->quiet || !mpctx->playback_initialized || !mpctx->playing_msg_shown) { - term_osd_set_status(mpctx, ""); + term_osd_set_status_lazy(mpctx, ""); return; } if (opts->status_msg) { char *r = mp_property_expand_escaped_string(mpctx, opts->status_msg); - term_osd_set_status(mpctx, r); + term_osd_set_status_lazy(mpctx, r); talloc_free(r); return; } @@ -292,7 +289,7 @@ static void print_status(struct MPContext *mpctx) } // end - term_osd_set_status(mpctx, line); + term_osd_set_status_lazy(mpctx, line); talloc_free(line); } @@ -563,8 +560,9 @@ void update_osd_msg(struct MPContext *mpctx) update_osd_bar(mpctx, OSD_BAR_SEEK, 0, 1, MPCLAMP(pos, 0, 1)); } - term_osd_set_text(mpctx, mpctx->osd_msg_text); - print_status(mpctx); + term_osd_set_text_lazy(mpctx, mpctx->osd_msg_text); + term_osd_print_status_lazy(mpctx); + term_osd_update(mpctx); int osd_level = opts->osd_level; if (mpctx->osd_show_pos) -- cgit v1.2.3 From a05f20ea1e7be645c141fa908b149ad0aa8e07d8 Mon Sep 17 00:00:00 2001 From: wgmk Date: Fri, 26 Aug 2016 18:43:55 +0000 Subject: TOOLS/zsh.pl: add m4a to zsh completion filetype list --- TOOLS/zsh.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TOOLS/zsh.pl b/TOOLS/zsh.pl index 306e9765b7..809a8a4d8a 100755 --- a/TOOLS/zsh.pl +++ b/TOOLS/zsh.pl @@ -142,7 +142,7 @@ $runtime_completions _tags files urls while _tags; do _requested files expl 'media file' _files -g \\ - "*.(#i)(asf|asx|avi|f4v|flac|flv|m1v|m2p|m2v|m4v|mjpg|mka|mkv|mov|mp3|mp4|mpe|mpeg|mpg|ogg|ogm|ogv|opus|qt|rm|ts|vob|wav|webm|wma|wmv|wv)(-.)" && rc=0 + "*.(#i)(asf|asx|avi|f4v|flac|flv|m1v|m2p|m2v|m4a|m4v|mjpg|mka|mkv|mov|mp3|mp4|mpe|mpeg|mpg|ogg|ogm|ogv|opus|qt|rm|ts|vob|wav|webm|wma|wmv|wv)(-.)" && rc=0 if _requested urls; then while _next_label urls expl URL; do _urls "\$expl[@]" && rc=0 -- cgit v1.2.3 From eed99d36096173baaf1964413fd070a466952598 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Sat, 27 Aug 2016 00:12:10 +0100 Subject: player: fix minor spelling mistake in osc.lua Lintain (https://lintian.debian.org/) complains about this particular spelling mistake. --- player/lua/osc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/player/lua/osc.lua b/player/lua/osc.lua index 09142e0813..d5960977ef 100644 --- a/player/lua/osc.lua +++ b/player/lua/osc.lua @@ -80,7 +80,7 @@ local state = { tc_ms = user_opts.timems, -- Should the timecodes display their time with milliseconds mp_screen_sizeX, mp_screen_sizeY, -- last screen-resolution, to detect resolution changes to issue reINITs initREQ = false, -- is a re-init request pending? - last_mouseX, last_mouseY, -- last mouse position, to detect siginificant mouse movement + last_mouseX, last_mouseY, -- last mouse position, to detect significant mouse movement message_text, message_timeout, fullscreen = false, -- cgit v1.2.3 From 7af6e64db748f71b472cd2b70ef7ebbe9da97859 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 27 Aug 2016 21:14:41 +0200 Subject: command: add property for current subtitle text Requested by someone. Reuses the code for terminal subtitle display. --- DOCS/man/input.rst | 7 +++++++ player/command.c | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index 8cdba41a3d..d720961226 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -1668,6 +1668,13 @@ Property list ``sub-use-margins`` (RW) See ``--sub-use-margins``. +``sub-text`` + Return the current subtitle text. Formatting is stripped. If a subtitle + is selected, but no text is currently visible, or the subtitle is not + text-based (i.e. DVD/BD subtitles), an empty string is returned. + + This property is experimental and might be removed in the future. + ``ass-vsfilter-aspect-compat`` (RW) See ``--ass-vsfilter-aspect-compat``. diff --git a/player/command.c b/player/command.c index f4c10d48b9..d0e69834aa 100644 --- a/player/command.c +++ b/player/command.c @@ -2971,6 +2971,25 @@ static int mp_property_sub_pos(void *ctx, struct m_property *prop, return property_osd_helper(mpctx, prop, action, arg); } +static int mp_property_sub_text(void *ctx, struct m_property *prop, + int action, void *arg) +{ + MPContext *mpctx = ctx; + struct track *track = mpctx->current_track[0][STREAM_SUB]; + struct dec_sub *sub = track ? track->d_sub : NULL; + double pts = mpctx->playback_pts; + if (!sub || pts == MP_NOPTS_VALUE) + return M_PROPERTY_UNAVAILABLE; + + pts -= mpctx->opts->sub_delay; + + char *text = sub_get_text(sub, pts); + if (!text) + text = ""; + + return m_property_strdup_ro(action, arg, text); +} + static int mp_property_cursor_autohide(void *ctx, struct m_property *prop, int action, void *arg) { @@ -3823,6 +3842,7 @@ static const struct m_property mp_properties[] = { {"secondary-sid", mp_property_sub2}, {"sub-delay", mp_property_sub_delay}, {"sub-pos", mp_property_sub_pos}, + {"sub-text", mp_property_sub_text}, {"sub-visibility", property_osd_helper}, {"sub-forced-only", property_osd_helper}, {"sub-scale", property_osd_helper}, @@ -3924,7 +3944,7 @@ static const char *const *const mp_event_property_change[] = { "estimated-vf-fps", "drop-frame-count", "vo-drop-frame-count", "total-avsync-change", "audio-speed-correction", "video-speed-correction", "vo-delayed-frame-count", "mistimed-frame-count", "vsync-ratio", - "estimated-display-fps", "vsync-jitter"), + "estimated-display-fps", "vsync-jitter", "sub-text"), E(MPV_EVENT_VIDEO_RECONFIG, "video-out-params", "video-params", "video-format", "video-codec", "video-bitrate", "dwidth", "dheight", "width", "height", "fps", "aspect", "vo-configured", "current-vo", -- cgit v1.2.3 From 5086b2d4568bfd8b39a4418a2db4dbfbb1fae92f Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 28 Aug 2016 18:15:37 +0200 Subject: player: add option to disable video OSD Normally, OSD can be disabled with --osd-level=0. But this also disables terminal OSD, and some users want _only_ the terminal OSD. Add --video-osd=no, which essentially disables the video OSD. Ideally, it should probably be possible to control terminal and video OSD levels independently, but that would require separate OSD timers (and other state) for both components, so don't do it. But because the current situation isn't too ideal, add a threat to the manpage that might be changed in the future. Fixes #3387. --- DOCS/man/options.rst | 23 +++++++++++++++++++---- options/options.c | 3 +++ options/options.h | 2 ++ player/osd.c | 13 +++++++++---- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index ec8f82349d..7cc66dcb8d 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -2890,6 +2890,17 @@ OSD Default: 0. +``--video-osd=`` + Enabled OSD rendering on the video window (default: yes). This can be used + in situations where terminal OSD is preferred. If you just want to disable + all OSD rendering, use ``--osd-level=0``. + + It does not affect subtitles or overlays created by scripts (in particular, + the OSC needs to be disabled with ``--no-osc``). + + This option is somewhat experimental and could be replaced by another + mechanism in the future. + Screenshot ---------- @@ -3136,11 +3147,15 @@ Terminal Only show warnings or worse, and let the ao_alsa output show errors only. -``--term-osd, --no-term-osd``, ``--term-osd=force`` - Display OSD messages on the console when no video output is available. - Enabled by default. +``--term-osd=`` + Control whether OSD messages are shown on the console when no video output + is available (default: auto). + + :auto: use terminal OSD if no video output active + :no: disable terminal OSD + :force: use terminal OSD even if video output active - ``force`` enables terminal OSD even if a video window is created. + The ``auto`` mode also enables terminal OSD if ``--video-osd=no`` was set. ``--term-osd-bar``, ``--no-term-osd-bar`` Enable printing a progress bar under the status line on the terminal. diff --git a/options/options.c b/options/options.c index 0ef89650a3..129f0cc53c 100644 --- a/options/options.c +++ b/options/options.c @@ -589,6 +589,8 @@ const m_option_t mp_opts[] = { OPT_STRING("osd-msg2", osd_msg[1], 0), OPT_STRING("osd-msg3", osd_msg[2], 0), + OPT_FLAG("video-osd", video_osd, 0), + OPT_CHOICE("idle", player_idle_mode, 0, ({"no", 0}, {"once", 1}, @@ -739,6 +741,7 @@ const struct MPOpts mp_default_opts = { .gamma_contrast = 1000, .gamma_saturation = 1000, .gamma_hue = 1000, + .video_osd = 1, .osd_level = 1, .osd_duration = 1000, .osd_bar_align_y = 0.5, diff --git a/options/options.h b/options/options.h index 263caaa8de..187abc2c1a 100644 --- a/options/options.h +++ b/options/options.h @@ -127,6 +127,8 @@ typedef struct MPOpts { int osd_level; int osd_duration; int osd_fractions; + int video_osd; + int untimed; char *stream_capture; char *stream_dump; diff --git a/player/osd.c b/player/osd.c index 48bf22b346..6f26e9361c 100644 --- a/player/osd.c +++ b/player/osd.c @@ -117,8 +117,8 @@ void term_osd_set_subs(struct MPContext *mpctx, const char *text) static void term_osd_set_text_lazy(struct MPContext *mpctx, const char *text) { - if ((mpctx->video_out && mpctx->opts->term_osd != 1) || - !mpctx->opts->term_osd || !text) + bool video_osd = mpctx->video_out && mpctx->opts->video_osd; + if ((video_osd && mpctx->opts->term_osd != 1) || !text) text = ""; // disable talloc_free(mpctx->term_osd_text); mpctx->term_osd_text = talloc_strdup(mpctx, text); @@ -325,7 +325,8 @@ void set_osd_bar(struct MPContext *mpctx, int type, double min, double max, double neutral, double val) { struct MPOpts *opts = mpctx->opts; - if (opts->osd_level < 1 || !opts->osd_bar_visible || !mpctx->video_out) + bool video_osd = mpctx->video_out && mpctx->opts->video_osd; + if (opts->osd_level < 1 || !opts->osd_bar_visible || !video_osd) return; mpctx->osd_visible = mp_time_sec() + opts->osd_duration / 1000.0; @@ -460,7 +461,8 @@ static void add_seek_osd_messages(struct MPContext *mpctx) } if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_TEXT) { // Never in term-osd mode - if (mpctx->video_out && mpctx->opts->term_osd != 1) { + bool video_osd = mpctx->video_out && mpctx->opts->video_osd; + if (video_osd && mpctx->opts->term_osd != 1) { if (set_osd_msg(mpctx, 1, mpctx->opts->osd_duration, "")) mpctx->osd_show_pos = true; } @@ -564,6 +566,9 @@ void update_osd_msg(struct MPContext *mpctx) term_osd_print_status_lazy(mpctx); term_osd_update(mpctx); + if (!opts->video_osd) + return; + int osd_level = opts->osd_level; if (mpctx->osd_show_pos) osd_level = 3; -- cgit v1.2.3 From 5e56c07417934d590665ad8330f04db7dd164229 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 28 Aug 2016 19:33:04 +0200 Subject: common: add assert.h include Because why not. --- common/common.h | 1 + 1 file changed, 1 insertion(+) diff --git a/common/common.h b/common/common.h index 4b7da54dbd..b687ffccf0 100644 --- a/common/common.h +++ b/common/common.h @@ -18,6 +18,7 @@ #ifndef MPLAYER_MPCOMMON_H #define MPLAYER_MPCOMMON_H +#include #include #include #include -- cgit v1.2.3 From a9a55ea7f28894d9e72be5e8b2d5a9331f1e7be4 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 28 Aug 2016 19:33:52 +0200 Subject: misc: add some annoying mpv_node helpers Sigh. Some parts of mpv essentially duplicate this code (with varrying levels of triviality) - this can be fixed "later". --- misc/node.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ misc/node.h | 11 ++++++++++ wscript_build.py | 1 + 3 files changed, 77 insertions(+) create mode 100644 misc/node.c create mode 100644 misc/node.h diff --git a/misc/node.c b/misc/node.c new file mode 100644 index 0000000000..1ea8ea7da5 --- /dev/null +++ b/misc/node.c @@ -0,0 +1,65 @@ +#include "common/common.h" + +#include "node.h" + +// Init a node with the given format. If parent is not NULL, it is set as +// parent allocation according to m_option_type_node rules (which means +// the mpv_node_list allocs are used for chaining the TA allocations). +// format == MPV_FORMAT_NONE will simply initialize it with all-0. +void node_init(struct mpv_node *dst, int format, struct mpv_node *parent) +{ + // Other formats need to be initialized manually. + assert(format == MPV_FORMAT_NODE_MAP || format == MPV_FORMAT_NODE_ARRAY || + format == MPV_FORMAT_FLAG || format == MPV_FORMAT_INT64 || + format == MPV_FORMAT_DOUBLE || format == MPV_FORMAT_NONE); + + void *ta_parent = NULL; + if (parent) { + assert(parent->format == MPV_FORMAT_NODE_MAP || + parent->format == MPV_FORMAT_NODE_ARRAY); + ta_parent = parent->u.list; + } + + *dst = (struct mpv_node){ .format = format }; + if (format == MPV_FORMAT_NODE_MAP || format == MPV_FORMAT_NODE_ARRAY) + dst->u.list = talloc_zero(ta_parent, struct mpv_node_list); +} + +// Add an entry to a MPV_FORMAT_NODE_ARRAY. +// m_option_type_node memory management rules apply. +struct mpv_node *node_array_add(struct mpv_node *dst, int format) +{ + struct mpv_node_list *list = dst->u.list; + assert(dst->format == MPV_FORMAT_NODE_ARRAY && dst->u.list); + MP_TARRAY_GROW(list, list->values, list->num); + node_init(&list->values[list->num], format, dst); + return &list->values[list->num++]; +} + +// Add an entry to a MPV_FORMAT_NODE_MAP. Keep in mind that this does +// not check for already existing entries under the same key. +// m_option_type_node memory management rules apply. +struct mpv_node *node_map_add(struct mpv_node *dst, const char *key, int format) +{ + assert(key); + + struct mpv_node_list *list = dst->u.list; + assert(dst->format == MPV_FORMAT_NODE_MAP && dst->u.list); + MP_TARRAY_GROW(list, list->values, list->num); + MP_TARRAY_GROW(list, list->keys, list->num); + list->keys[list->num] = talloc_strdup(list, key); + node_init(&list->values[list->num], format, dst); + return &list->values[list->num++]; +} + +// Add a string entry to a MPV_FORMAT_NODE_MAP. Keep in mind that this does +// not check for already existing entries under the same key. +// m_option_type_node memory management rules apply. +void node_map_add_string(struct mpv_node *dst, const char *key, const char *val) +{ + assert(val); + + struct mpv_node *entry = node_map_add(dst, key, MPV_FORMAT_NONE); + entry->format = MPV_FORMAT_STRING; + entry->u.string = talloc_strdup(dst->u.list, val); +} diff --git a/misc/node.h b/misc/node.h new file mode 100644 index 0000000000..c3b4501dc8 --- /dev/null +++ b/misc/node.h @@ -0,0 +1,11 @@ +#ifndef MP_MISC_NODE_H_ +#define MP_MISC_NODE_H_ + +#include "libmpv/client.h" + +void node_init(struct mpv_node *dst, int format, struct mpv_node *parent); +struct mpv_node *node_array_add(struct mpv_node *dst, int format); +struct mpv_node *node_map_add(struct mpv_node *dst, const char *key, int format); +void node_map_add_string(struct mpv_node *dst, const char *key, const char *val); + +#endif diff --git a/wscript_build.py b/wscript_build.py index 9f30e741a5..f246ae4a33 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -195,6 +195,7 @@ def build(ctx): ( "misc/charset_conv.c" ), ( "misc/dispatch.c" ), ( "misc/json.c" ), + ( "misc/node.c" ), ( "misc/ring.c" ), ( "misc/rendezvous.c" ), -- cgit v1.2.3 From f42e4374d55a3b68b0c4fcb342d9cdcd5d15c9c7 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 28 Aug 2016 19:42:03 +0200 Subject: command: export profile list as a property Targeted at scripts, which can do whatever they want with it. This comes with the promise that they could get randomly broken any time. See #977. --- DOCS/man/input.rst | 8 ++++++++ options/m_config.c | 27 +++++++++++++++++++++++++++ options/m_config.h | 2 ++ player/command.c | 17 +++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index d720961226..5892649fe5 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -2211,6 +2211,14 @@ Property list ``property-list`` Return the list of top-level properties. +``profile-list`` + Return the list of profiles and their contents. This is highly + implementation-specific, and may change any time. Currently, it returns + an array of options for each profile. Each option has a name and a value, + with the value currently always being a string. Note that the options array + is not a map, as order matters and duplicate entries are possible. Recursive + profiles are not expanded, and show up as special ``profile`` options. + Property Expansion ------------------ diff --git a/options/m_config.c b/options/m_config.c index 1cb01ebfdc..3dbbb5020a 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -36,6 +36,7 @@ #include "options/m_option.h" #include "common/msg.h" #include "common/msg_control.h" +#include "misc/node.h" static const union m_option_value default_value; @@ -933,6 +934,32 @@ int m_config_set_profile(struct m_config *config, char *name, int flags) return 0; } +struct mpv_node m_config_get_profiles(struct m_config *config) +{ + struct mpv_node root; + node_init(&root, MPV_FORMAT_NODE_ARRAY, NULL); + + for (m_profile_t *profile = config->profiles; profile; profile = profile->next) + { + struct mpv_node *entry = node_array_add(&root, MPV_FORMAT_NODE_MAP); + + node_map_add_string(entry, "name", profile->name); + if (profile->desc) + node_map_add_string(entry, "profile-desc", profile->desc); + + struct mpv_node *opts = + node_map_add(entry, "options", MPV_FORMAT_NODE_ARRAY); + + for (int n = 0; n < profile->num_opts; n++) { + struct mpv_node *opt_entry = node_array_add(opts, MPV_FORMAT_NODE_MAP); + node_map_add_string(opt_entry, "key", profile->opts[n * 2 + 0]); + node_map_add_string(opt_entry, "value", profile->opts[n * 2 + 1]); + } + } + + return root; +} + void *m_config_alloc_struct(void *talloc_ctx, const struct m_sub_options *subopts) { diff --git a/options/m_config.h b/options/m_config.h index ed34389921..5937a4492e 100644 --- a/options/m_config.h +++ b/options/m_config.h @@ -247,6 +247,8 @@ int m_config_set_profile_option(struct m_config *config, struct m_profile *p, */ int m_config_set_profile(struct m_config *config, char *name, int flags); +struct mpv_node m_config_get_profiles(struct m_config *config); + void *m_config_alloc_struct(void *talloc_ctx, const struct m_sub_options *subopts); diff --git a/player/command.c b/player/command.c index d0e69834aa..e725f2f529 100644 --- a/player/command.c +++ b/player/command.c @@ -3668,6 +3668,22 @@ static int mp_property_list(void *ctx, struct m_property *prop, return M_PROPERTY_NOT_IMPLEMENTED; } +static int mp_profile_list(void *ctx, struct m_property *prop, + int action, void *arg) +{ + MPContext *mpctx = ctx; + switch (action) { + case M_PROPERTY_GET_TYPE: + *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_NODE}; + return M_PROPERTY_OK; + case M_PROPERTY_GET: { + *(struct mpv_node *)arg = m_config_get_profiles(mpctx->mconfig); + return M_PROPERTY_OK; + } + } + return M_PROPERTY_NOT_IMPLEMENTED; +} + // Redirect a property name to another #define M_PROPERTY_ALIAS(name, real_property) \ {(name), mp_property_alias, .priv = (real_property)} @@ -3911,6 +3927,7 @@ static const struct m_property mp_properties[] = { {"file-local-options", mp_property_local_options}, {"option-info", mp_property_option_info}, {"property-list", mp_property_list}, + {"profile-list", mp_profile_list}, // compatibility M_PROPERTY_ALIAS("video", "vid"), -- cgit v1.2.3 From bda614bfd81ae4660ed6356bc124e015645ff3b0 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 29 Aug 2016 09:30:39 +0200 Subject: m_config: profile option values can be NULL Sigh. --- options/m_config.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/options/m_config.c b/options/m_config.c index 3dbbb5020a..106a8f20ee 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -953,7 +953,8 @@ struct mpv_node m_config_get_profiles(struct m_config *config) for (int n = 0; n < profile->num_opts; n++) { struct mpv_node *opt_entry = node_array_add(opts, MPV_FORMAT_NODE_MAP); node_map_add_string(opt_entry, "key", profile->opts[n * 2 + 0]); - node_map_add_string(opt_entry, "value", profile->opts[n * 2 + 1]); + if (profile->opts[n * 2 + 1]) + node_map_add_string(opt_entry, "value", profile->opts[n * 2 + 1]); } } -- cgit v1.2.3 From 0110b738d5d37a0f7cafd522b89017436f7cfd73 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 29 Aug 2016 12:46:12 +0200 Subject: vd_lavc, ad_lavc: set pkt_timebase, not time_base These are different AVCodecContext fields. pkt_timebase is the correct one for identifying the unit of packet/frame timestamps when decoding, while time_base is for encoding. Some decoders also overwrite the time_base field with some unrelated codec metadata. pkt_timebase does not exist in Libav, so an #if is required. --- audio/decode/ad_lavc.c | 5 ++++- video/decode/vd_lavc.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index 78d0cec807..e5c426e912 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -103,7 +103,10 @@ static int init(struct dec_audio *da, const char *decoder) lavc_context->refcounted_frames = 1; lavc_context->codec_type = AVMEDIA_TYPE_AUDIO; lavc_context->codec_id = lavc_codec->id; - lavc_context->time_base = ctx->codec_timebase; + +#if LIBAVCODEC_VERSION_MICRO >= 100 + lavc_context->pkt_timebase = ctx->codec_timebase; +#endif if (opts->downmix && mpopts->audio_output_channels.num_chmaps == 1) { lavc_context->request_channel_layout = diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 8cc5d4eca4..18cbeda4e9 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -460,7 +460,10 @@ static void init_avctx(struct dec_video *vd, const char *decoder, avctx->opaque = vd; avctx->codec_type = AVMEDIA_TYPE_VIDEO; avctx->codec_id = lavc_codec->id; - avctx->time_base = ctx->codec_timebase; + +#if LIBAVCODEC_VERSION_MICRO >= 100 + avctx->pkt_timebase = ctx->codec_timebase; +#endif avctx->refcounted_frames = 1; ctx->pic = av_frame_alloc(); -- cgit v1.2.3 From edbb8f6286806945e87afd23f30c409c8774d1df Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 29 Aug 2016 12:49:18 +0200 Subject: vd_lavc: always force milliseconds for MMAL This libavcodec wrapper should rescale the API timestamps to whatever it internally needs, but it doesn't yet. So restore this code. --- video/decode/vd_lavc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 18cbeda4e9..4b8528fc3a 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -450,6 +450,11 @@ static void init_avctx(struct dec_video *vd, const char *decoder, return; ctx->codec_timebase = mp_get_codec_timebase(vd->codec); + + // This decoder does not read pkt_timebase correctly yet. + if (strstr(decoder, "_mmal")) + ctx->codec_timebase = (AVRational){1, 1000000}; + ctx->pix_fmt = AV_PIX_FMT_NONE; ctx->hwdec = hwdec; ctx->hwdec_fmt = 0; -- cgit v1.2.3 From 251ecf6e4b3d4215450a977315afa85f1cb781ab Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 29 Aug 2016 13:13:37 +0200 Subject: sd_lavc: always set decoder timebase Like it's done for audio and video. Just to be uniform. I'm sorry for deleting the anti-ffmpeg vitriol. It's still all true, but since we decided to always set the timebase, the crappiness is isolated to FFmpeg internals. --- sub/sd_lavc.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c index 9c217a6936..f310367734 100644 --- a/sub/sd_lavc.c +++ b/sub/sd_lavc.c @@ -123,25 +123,9 @@ static int init(struct sd *sd) if (!ctx) goto error; mp_lavc_set_extradata(ctx, sd->codec->extradata, sd->codec->extradata_size); + priv->pkt_timebase = mp_get_codec_timebase(sd->codec); #if LIBAVCODEC_VERSION_MICRO >= 100 - if (cid == AV_CODEC_ID_HDMV_PGS_SUBTITLE) { - // We don't always want to set this, because the ridiculously shitty - // libavcodec API will mess with certain fields (end_display_time) - // when setting it. On the other hand, PGS in particular needs PTS - // mangling. While the PGS decoder doesn't modify the timestamps (just - // reorder it), the ridiculously shitty libavcodec wants a timebase - // anyway and for no good reason. It always sets end_display_time to - // UINT32_MAX (which is a broken and undocumented way to say "unknown"), - // which coincidentally won't be overridden by the ridiculously shitty - // pkt_timebase code. also, Libav doesn't have the pkt_timebase field, - // because Libav tends to avoid _adding_ ridiculously shitty APIs. - priv->pkt_timebase = (AVRational){1, AV_TIME_BASE}; - ctx->pkt_timebase = priv->pkt_timebase; - } else { - // But old ffmpeg releases have a buggy pkt_timebase check, because the - // shit above wasn't bad enough! - ctx->pkt_timebase = (AVRational){0, 0}; - } + ctx->pkt_timebase = priv->pkt_timebase; #endif if (avcodec_open2(ctx, sub_codec, NULL) < 0) goto error; -- cgit v1.2.3 From 3e0d4de98850cc2327b03db926ce0c2d28e2f103 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 29 Aug 2016 14:02:24 +0200 Subject: vo_opengl: explicitly check for GL errors around framebuffer depth check It seems like many GL implementations (including Mesa) choke on this, while others are fine. We still think that this use of the GL API is allowed by the standard (at least in the Mesa case), so to reduce confusion, explicitly check the "controversial" calls, and use an appropriate error message. --- video/out/opengl/video.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c index 901e208cab..8e419a1bd5 100644 --- a/video/out/opengl/video.c +++ b/video/out/opengl/video.c @@ -3153,6 +3153,8 @@ static void init_gl(struct gl_video *p) if ((gl->es >= 300 || gl->version) && (gl->mpgl_caps & MPGL_CAP_FB)) { gl->BindFramebuffer(GL_FRAMEBUFFER, gl->main_fb); + debug_check_gl(p, "before retrieving framebuffer depth"); + GLenum obj = gl->version ? GL_BACK_LEFT : GL_BACK; if (gl->main_fb) obj = GL_COLOR_ATTACHMENT0; @@ -3166,6 +3168,8 @@ static void init_gl(struct gl_video *p) gl->GetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, obj, GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, &depth_b); + debug_check_gl(p, "retrieving framebuffer depth"); + MP_VERBOSE(p, "Reported display depth: R=%d, G=%d, B=%d\n", depth_r, depth_g, depth_b); -- cgit v1.2.3 From cb2cb540f49654d5b3377743bfea387411ce43f8 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Mon, 29 Aug 2016 13:20:35 +0100 Subject: wayland: reject resize events with either dimension being 0 Newer versions of mutter/gnome now ask mpv to resize to 0 by 0 pixels. --- video/out/wayland_common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 3ea4a3f4a6..e42af8438e 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -142,6 +142,8 @@ static void ssurface_handle_configure(void *data, { struct vo_wayland_state *wl = data; float win_aspect = wl->window.aspect; + if (!width || !height) + return; if (!wl->window.is_fullscreen) width = win_aspect * height; schedule_resize(wl, edges, width, height); -- cgit v1.2.3 From d223959cda7ef816b95303c328f7a8ad0e35dbff Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 29 Aug 2016 17:15:06 +0200 Subject: player: slightly adjust framerate guessing heuristic Some files not only use rounded timestamps, but they also do it incorrectly. They may jitter between up to 4 specific frame durations. In this case, I found a file that mostly used 41ms and 42ms, but also had 40ms and 43ms outliers (often but not always following each other). This breaks the assumption of the framerate estimation code that the frame duration can deviate up to 1ms. If it jitters around 4 possible frame durations, the maximum deviation is 3ms. Increase it accordingly. The change might make playback of "true VFR" video via display-sync mode worse, but it's not like it was particularly good in the first place. Also, the check whether to usen the container FPS needs to be stricter. In the worst case, num_dur is 1, which doesn't really indicate any evidence that the framerate is correct. Only if there are "enough" frames the deviation check will become meaningful. 16 is an arbitrary value that has been designated "enough" by myself. Also otuput the frame duration values for --dump-stats. --- player/video.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/player/video.c b/player/video.c index 5e0266b8d0..1ceda1f999 100644 --- a/player/video.c +++ b/player/video.c @@ -1291,11 +1291,10 @@ static void calculate_frame_duration(struct MPContext *mpctx) // The following code tries to compensate for rounded Matroska timestamps // by "unrounding" frame durations, or if not possible, approximating them. - // These formats usually round on 1ms. (Some muxers do this incorrectly, - // and might be off by 2ms or more, and compensate for it later by an - // equal rounding error into the opposite direction. Don't try to deal - // with them; too much potential damage to timing.) - double tolerance = 0.0011; + // These formats usually round on 1ms. Some muxers do this incorrectly, + // and might go off by 1ms more, and compensate for it later by an equal + // rounding error into the opposite direction. + double tolerance = 0.001 * 3 + 0.0001; double total = 0; int num_dur = 0; @@ -1314,7 +1313,7 @@ static void calculate_frame_duration(struct MPContext *mpctx) // Note that even if each timestamp is within rounding tolerance, it // could literally not add up (e.g. if demuxer FPS is rounded itself). if (fabs(duration - demux_duration) < tolerance && - fabs(total - demux_duration * num_dur) < tolerance) + fabs(total - demux_duration * num_dur) < tolerance && num_dur >= 16) { approx_duration = demux_duration; } @@ -1322,6 +1321,9 @@ static void calculate_frame_duration(struct MPContext *mpctx) mpctx->past_frames[0].duration = duration; mpctx->past_frames[0].approx_duration = approx_duration; + + MP_STATS(mpctx, "value %f frame-duration", MPMAX(0, duration)); + MP_STATS(mpctx, "value %f frame-duration-approx", MPMAX(0, approx_duration)); } void write_video(struct MPContext *mpctx) -- cgit v1.2.3 From f3b3702025c0382bd045769e05fec6cb4723d26b Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 30 Aug 2016 23:44:28 +0200 Subject: player: make --force-window work with opengl-cb No reason not to? This probably avoids surprises if someone really tries to combine them. --- player/playloop.c | 1 + 1 file changed, 1 insertion(+) diff --git a/player/playloop.c b/player/playloop.c index ed4f57dd5c..3bf2216962 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -813,6 +813,7 @@ int handle_force_window(struct MPContext *mpctx, bool force) .input_ctx = mpctx->input, .osd = mpctx->osd, .encode_lavc_ctx = mpctx->encode_lavc_ctx, + .opengl_cb_context = mpctx->gl_cb_ctx, }; mpctx->video_out = init_best_video_out(mpctx->global, &ex); if (!mpctx->video_out) -- cgit v1.2.3 From 6f6d2eb7705db6e315f7df72db8f81ef7e7d3f35 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 30 Aug 2016 23:45:20 +0200 Subject: command: cosmetics: fix some minor whitespace mistakes --- player/command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/player/command.c b/player/command.c index e725f2f529..1c59d130ce 100644 --- a/player/command.c +++ b/player/command.c @@ -576,7 +576,7 @@ static int mp_property_drop_frame_cnt(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - if (!mpctx->vo_chain) + if (!mpctx->vo_chain) return M_PROPERTY_UNAVAILABLE; return m_property_int_ro(action, arg, mpctx->vo_chain->video_src->dropped_frames); @@ -2390,7 +2390,7 @@ static int mp_property_taskbar_progress(void *ctx, struct m_property *prop, return M_PROPERTY_OK; mpctx->opts->vo.taskbar_progress = desired; if (mpctx->video_out) - update_vo_playback_state( mpctx ); + update_vo_playback_state(mpctx); return M_PROPERTY_OK; } return mp_property_generic_option(mpctx, prop, action, arg); -- cgit v1.2.3 From 3bb134969eb624e859a546fd7142fe2eae076346 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 30 Aug 2016 23:45:58 +0200 Subject: m_option: remove M_OPT_TYPE_DYNAMIC flag It's actually redundant with whether m_option_type.free is set. Some option types were flagged inconsistently. Its only use was for running an additional sanity check without any real functionality. --- options/m_config.c | 2 +- options/m_option.c | 9 ++------- options/m_option.h | 10 +--------- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/options/m_config.c b/options/m_config.c index 106a8f20ee..d2fe3fdcfa 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -424,7 +424,7 @@ static void m_config_add_option(struct m_config *config, } else { // Initialize options if (co.data && co.default_data) { - if (arg->type->flags & M_OPT_TYPE_DYNAMIC) { + if (arg->type->free) { // Would leak memory by overwriting *co.data repeatedly. for (int i = 0; i < config->num_opts; i++) { if (co.data == config->opts[i].data) diff --git a/options/m_option.c b/options/m_option.c index 0acdc55b0a..94dab9f59f 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -1175,7 +1175,6 @@ static void free_str(void *src) const m_option_type_t m_option_type_string = { .name = "String", .size = sizeof(char *), - .flags = M_OPT_TYPE_DYNAMIC, .parse = parse_str, .print = print_str, .copy = copy_str, @@ -1486,7 +1485,7 @@ const m_option_type_t m_option_type_string_list = { */ .name = "String list", .size = sizeof(char **), - .flags = M_OPT_TYPE_DYNAMIC | M_OPT_TYPE_ALLOW_WILDCARD, + .flags = M_OPT_TYPE_ALLOW_WILDCARD, .parse = parse_str_list, .print = print_str_list, .copy = copy_str_list, @@ -1522,7 +1521,6 @@ static int parse_str_append_list(struct mp_log *log, const m_option_t *opt, const m_option_type_t m_option_type_string_append_list = { .name = "String list", .size = sizeof(char **), - .flags = M_OPT_TYPE_DYNAMIC, .parse = parse_str_append_list, .print = print_str_list, .copy = copy_str_list, @@ -1636,7 +1634,6 @@ static int keyvalue_list_get(const m_option_t *opt, void *ta_parent, const m_option_type_t m_option_type_keyvalue_list = { .name = "Key/value list", .size = sizeof(char **), - .flags = M_OPT_TYPE_DYNAMIC, .parse = parse_keyvalue_list, .print = print_keyvalue_list, .copy = copy_str_list, @@ -1703,7 +1700,6 @@ static int set_msglevels(const m_option_t *opt, void *dst, const m_option_type_t m_option_type_msglevels = { .name = "Output verbosity levels", .size = sizeof(char **), - .flags = M_OPT_TYPE_DYNAMIC, .parse = parse_msglevels, .print = print_keyvalue_list, .copy = copy_str_list, @@ -3284,7 +3280,7 @@ static int get_obj_settings_list(const m_option_t *opt, void *ta_parent, const m_option_type_t m_option_type_obj_settings_list = { .name = "Object settings list", .size = sizeof(m_obj_settings_t *), - .flags = M_OPT_TYPE_DYNAMIC | M_OPT_TYPE_ALLOW_WILDCARD, + .flags = M_OPT_TYPE_ALLOW_WILDCARD, .parse = parse_obj_settings_list, .print = print_obj_settings_list, .copy = copy_obj_settings_list, @@ -3405,7 +3401,6 @@ static int node_get(const m_option_t *opt, void *ta_parent, const m_option_type_t m_option_type_node = { .name = "Complex", .size = sizeof(struct mpv_node), - .flags = M_OPT_TYPE_DYNAMIC, .parse = parse_node, .print = print_node, .copy = copy_node, diff --git a/options/m_option.h b/options/m_option.h index 80be447c42..847cd1097c 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -403,19 +403,11 @@ struct m_option { */ #define M_OPT_TYPE_ALLOW_WILDCARD (1 << 1) -// Dynamic data type. -/** This flag indicates that the data is dynamically allocated (m_option::p - * points to a pointer). It enables a little hack in the \ref Config which - * replaces the initial value of such variables with a dynamic copy in case - * the initial value is statically allocated (pretty common with strings). - */ -#define M_OPT_TYPE_DYNAMIC (1 << 2) - // The parameter is optional and by default no parameter is preferred. If // ambiguous syntax is used ("--opt value"), the command line parser will // assume that the argument takes no parameter. In config files, these // options can be used without "=" and value. -#define M_OPT_TYPE_OPTIONAL_PARAM (1 << 3) +#define M_OPT_TYPE_OPTIONAL_PARAM (1 << 2) ///////////////////////////// Parser flags ///////////////////////////////// -- cgit v1.2.3 From 5f88e6a0db292d272b3dc8f66c257c27327d1733 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 30 Aug 2016 23:47:09 +0200 Subject: m_config: rename is_generated to is_hidden More appropriate. Originally it really was for automatically added options, but now it even needed some stupid comments to indicate that it was used for simply hiding options. --- options/m_config.c | 12 ++++++------ options/m_config.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/options/m_config.c b/options/m_config.c index d2fe3fdcfa..c98ee6713f 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -334,7 +334,7 @@ static void add_negation_option(struct m_config *config, struct m_config_option co = *orig; co.name = talloc_asprintf(config, "no-%s", orig->name); co.opt = no_opt; - co.is_generated = true; + co.is_hidden = true; MP_TARRAY_APPEND(config, config->opts, config->num_opts, co); // Add --sub-no-opt (unfortunately needed for: "--sub=...:no-opt") if (parent_name[0]) { @@ -441,7 +441,7 @@ static void m_config_add_option(struct m_config *config, add_negation_option(config, &co, parent_name); if (co.opt->type == &m_option_type_alias) { - co.is_generated = true; // hide it + co.is_hidden = true; const char *alias = (const char *)co.opt->priv; char no_alias[40]; snprintf(no_alias, sizeof(no_alias), "no-%s", alias); @@ -456,7 +456,7 @@ static void m_config_add_option(struct m_config *config, } if (co.opt->type == &m_option_type_removed) - co.is_generated = true; // hide it + co.is_hidden = true; } struct m_config_option *m_config_get_co(const struct m_config *config, @@ -519,7 +519,7 @@ const char *m_config_get_positional_option(const struct m_config *config, int p) int pos = 0; for (int n = 0; n < config->num_opts; n++) { struct m_config_option *co = &config->opts[n]; - if (!co->is_generated) { + if (!co->is_hidden) { if (pos == p) return co->name; pos++; @@ -794,7 +794,7 @@ void m_config_print_option_list(const struct m_config *config) const struct m_option *opt = co->opt; if (opt->type->flags & M_OPT_TYPE_HAS_CHILD) continue; - if (co->is_generated) + if (co->is_hidden) continue; if (opt->type == &m_option_type_alias || opt->type == &m_option_type_removed) @@ -848,7 +848,7 @@ char **m_config_list_options(void *ta_parent, const struct m_config *config) const struct m_option *opt = co->opt; if (opt->type->flags & M_OPT_TYPE_HAS_CHILD) continue; - if (co->is_generated) + if (co->is_hidden) continue; // For use with CONF_TYPE_STRING_LIST, it's important not to set list // as allocation parent. diff --git a/options/m_config.h b/options/m_config.h index 5937a4492e..af8ab421f0 100644 --- a/options/m_config.h +++ b/options/m_config.h @@ -37,7 +37,7 @@ struct mp_log; // Config option struct m_config_option { - bool is_generated : 1; // Automatically added ("no-" options) + bool is_hidden : 1; // Does not show up in help bool is_set_from_cmdline : 1; // Set by user from command line bool is_set_locally : 1; // Has a backup entry bool warning_was_printed : 1; -- cgit v1.2.3 From e65a8d7b61762ddf07825c59a6ebd47b026b0ea7 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 30 Aug 2016 23:48:42 +0200 Subject: m_config: pass parent option in m_config_add_option() Instead of just the parent name. This is a minor refactor as preparation for other things. --- options/m_config.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/options/m_config.c b/options/m_config.c index c98ee6713f..8a4d5998d6 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -174,7 +174,7 @@ static void substruct_write_ptr(void *ptr, void *val) } static void add_options(struct m_config *config, - const char *parent_name, + struct m_config_option *parent, void *optstruct, const void *optstruct_def, const struct m_option *defs); @@ -202,7 +202,7 @@ struct m_config *m_config_new(void *talloc_ctx, struct mp_log *log, memcpy(config->optstruct, defaults, size); } if (options) - add_options(config, "", config->optstruct, defaults, options); + add_options(config, NULL, config->optstruct, defaults, options); return config; } @@ -344,19 +344,19 @@ static void add_negation_option(struct m_config *config, } static void m_config_add_option(struct m_config *config, - const char *parent_name, + struct m_config_option *parent, void *optstruct, const void *optstruct_def, const struct m_option *arg); static void add_options(struct m_config *config, - const char *parent_name, + struct m_config_option *parent, void *optstruct, const void *optstruct_def, const struct m_option *defs) { for (int i = 0; defs && defs[i].name; i++) - m_config_add_option(config, parent_name, optstruct, optstruct_def, &defs[i]); + m_config_add_option(config, parent, optstruct, optstruct_def, &defs[i]); } // Initialize a field with a given value. In case this is dynamic data, it has @@ -372,7 +372,7 @@ static void init_opt_inplace(const struct m_option *opt, void *dst, } static void m_config_add_option(struct m_config *config, - const char *parent_name, + struct m_config_option *parent, void *optstruct, const void *optstruct_def, const struct m_option *arg) @@ -380,6 +380,8 @@ static void m_config_add_option(struct m_config *config, assert(config != NULL); assert(arg != NULL); + const char *parent_name = parent ? parent->name : ""; + struct m_config_option co = { .opt = arg, .name = arg->name, @@ -419,8 +421,7 @@ static void m_config_add_option(struct m_config *config, if (!new_optstruct_def) new_optstruct_def = subopts->defaults; - add_options(config, co.name, new_optstruct, - new_optstruct_def, subopts->opts); + add_options(config, &co, new_optstruct, new_optstruct_def, subopts->opts); } else { // Initialize options if (co.data && co.default_data) { @@ -451,7 +452,7 @@ static void m_config_add_option(struct m_config *config, new->priv = talloc_strdup(config, no_alias); new->type = &m_option_type_alias; new->offset = -1; - m_config_add_option(config, "", NULL, NULL, new); + m_config_add_option(config, NULL, NULL, NULL, new); } } -- cgit v1.2.3 From af1379c43d6a5274b75bce0adeef9e3a9ce87bdf Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 30 Aug 2016 23:50:57 +0200 Subject: options: make mp_vo_opts options an actual sub-option group Just a minor refactor along the planned option change. This commit will make it easier to update (i.e. copy) the VO options without copying _all_ options. For now, behavior should be equivalent, though. (The VO options were put into a separate struct quite early - when all global variables were removed from the source code. It wasn't clear whether the separate struct would have any actual purpose, but it seems it will now. Awesome, huh.) --- options/options.c | 145 +++++++++++++++++++++++++---------------------- options/options.h | 2 +- player/command.c | 16 +++--- player/configfiles.c | 4 +- player/misc.c | 2 +- player/playloop.c | 2 +- video/filter/vf_scale.c | 2 +- video/out/vo.c | 4 +- video/out/vo_opengl_cb.c | 2 +- 9 files changed, 94 insertions(+), 85 deletions(-) diff --git a/options/options.c b/options/options.c index 129f0cc53c..dc880d3339 100644 --- a/options/options.c +++ b/options/options.c @@ -97,6 +97,81 @@ const struct m_opt_choice_alternatives mp_hwdec_names[] = { {0} }; +#define OPT_BASE_STRUCT struct mp_vo_opts + +static const m_option_t mp_vo_opt_list[] = { + OPT_SETTINGSLIST("vo", video_driver_list, 0, &vo_obj_list), + OPT_SETTINGSLIST("vo-defaults", vo_defs, 0, &vo_obj_list), + OPT_CHOICE_C("hwdec-preload", hwdec_preload_api, 0, mp_hwdec_names), + OPT_SUBSTRUCT("sws", sws_opts, sws_conf, 0), + OPT_FLAG("taskbar-progress", taskbar_progress, 0), + OPT_FLAG("ontop", ontop, M_OPT_FIXED), + OPT_FLAG("border", border, M_OPT_FIXED), + OPT_FLAG("fit-border", fit_border, M_OPT_FIXED), + OPT_FLAG("on-all-workspaces", all_workspaces, M_OPT_FIXED), + OPT_GEOMETRY("geometry", geometry, 0), + OPT_SIZE_BOX("autofit", autofit, 0), + OPT_SIZE_BOX("autofit-larger", autofit_larger, 0), + OPT_SIZE_BOX("autofit-smaller", autofit_smaller, 0), + OPT_FLOATRANGE("window-scale", window_scale, 0, 0.001, 100), + OPT_FLAG("force-window-position", force_window_position, 0), + OPT_STRING("x11-name", winname, 0), + OPT_FLOATRANGE("monitoraspect", force_monitor_aspect, 0, 0.0, 9.0), + OPT_FLOATRANGE("monitorpixelaspect", monitor_pixel_aspect, 0, 0.2, 9.0), + OPT_FLAG("fullscreen", fullscreen, M_OPT_FIXED), + OPT_FLAG("fs", fullscreen, M_OPT_FIXED), + OPT_FLAG("native-keyrepeat", native_keyrepeat, M_OPT_FIXED), + OPT_FLOATRANGE("panscan", panscan, 0, 0.0, 1.0), + OPT_FLOATRANGE("video-zoom", zoom, 0, -20.0, 20.0), + OPT_FLOATRANGE("video-pan-x", pan_x, 0, -3.0, 3.0), + OPT_FLOATRANGE("video-pan-y", pan_y, 0, -3.0, 3.0), + OPT_FLOATRANGE("video-align-x", align_x, 0, -1.0, 1.0), + OPT_FLOATRANGE("video-align-y", align_y, 0, -1.0, 1.0), + OPT_CHOICE("video-unscaled", unscaled, 0, + ({"no", 0}, {"yes", 1}, {"downscale-big", 2})), + OPT_INT64("wid", WinID, 0), + OPT_CHOICE_OR_INT("screen", screen_id, 0, 0, 32, + ({"default", -1})), + OPT_CHOICE_OR_INT("fs-screen", fsscreen_id, 0, 0, 32, + ({"all", -2}, {"current", -1})), + OPT_FLAG("fs-black-out-screens", fs_black_out_screens, 0), + OPT_FLAG("keepaspect", keepaspect, 0), + OPT_FLAG("keepaspect-window", keepaspect_window, 0), +#if HAVE_X11 + OPT_CHOICE("x11-netwm", x11_netwm, 0, + ({"auto", 0}, {"no", -1}, {"yes", 1})), + OPT_CHOICE("x11-bypass-compositor", x11_bypass_compositor, 0, + ({"no", 0}, {"yes", 1}, {"fs-only", 2}, {"never", 3})), +#endif +#if HAVE_WIN32 + OPT_STRING("vo-mmcss-profile", mmcss_profile, M_OPT_FIXED), +#endif + + {0} +}; + +static const struct m_sub_options vo_sub_opts = { + .opts = mp_vo_opt_list, + .size = sizeof(struct mp_vo_opts), + .defaults = &(const struct mp_vo_opts){ + .video_driver_list = NULL, + .monitor_pixel_aspect = 1.0, + .screen_id = -1, + .fsscreen_id = -1, + .panscan = 0.0f, + .keepaspect = 1, + .keepaspect_window = 1, + .taskbar_progress = 1, + .border = 1, + .fit_border = 1, + .WinID = -1, + .window_scale = 1.0, + .x11_bypass_compositor = 2, + .mmcss_profile = "Playback", + }, +}; + +#undef OPT_BASE_STRUCT #define OPT_BASE_STRUCT struct MPOpts const m_option_t mp_opts[] = { @@ -313,14 +388,11 @@ const m_option_t mp_opts[] = { OPT_FLAG("ad-spdif-dtshd", dtshd, 0), OPT_CHOICE_C("hwdec", hwdec_api, 0, mp_hwdec_names), - OPT_CHOICE_C("hwdec-preload", vo.hwdec_preload_api, 0, mp_hwdec_names), OPT_STRING("hwdec-codecs", hwdec_codecs, 0), #if HAVE_VIDEOTOOLBOX_HWACCEL OPT_IMAGEFORMAT("videotoolbox-format", videotoolbox_format, 0), #endif - OPT_SUBSTRUCT("sws", vo.sws_opts, sws_conf, 0), - // -1 means auto aspect (prefer container size until aspect change) // 0 means square pixels OPT_FLOATRANGE("video-aspect", movie_aspect, 0, -1.0, 10.0), @@ -393,8 +465,6 @@ const m_option_t mp_opts[] = { OPT_FLAG("sub-clear-on-seek", sub_clear_on_seek, 0), //---------------------- libao/libvo options ------------------------ - OPT_SETTINGSLIST("vo", vo.video_driver_list, 0, &vo_obj_list), - OPT_SETTINGSLIST("vo-defaults", vo.vo_defs, 0, &vo_obj_list), OPT_SETTINGSLIST("ao", audio_driver_list, 0, &ao_obj_list), OPT_SETTINGSLIST("ao-defaults", ao_defs, 0, &ao_obj_list), OPT_STRING("audio-device", audio_device, 0), @@ -404,11 +474,6 @@ const m_option_t mp_opts[] = { OPT_FLOATRANGE("audio-wait-open", audio_wait_open, 0, 0, 60), OPT_CHOICE("force-window", force_vo, 0, ({"no", 0}, {"yes", 1}, {"immediate", 2})), - OPT_FLAG("taskbar-progress", vo.taskbar_progress, 0), - OPT_FLAG("ontop", vo.ontop, M_OPT_FIXED), - OPT_FLAG("border", vo.border, M_OPT_FIXED), - OPT_FLAG("fit-border", vo.fit_border, M_OPT_FIXED), - OPT_FLAG("on-all-workspaces", vo.all_workspaces, M_OPT_FIXED), OPT_FLAG("window-dragging", allow_win_drag, CONF_GLOBAL), @@ -431,31 +496,9 @@ const m_option_t mp_opts[] = { .min = 0, .max = 10), OPT_FLOATRANGE("balance", balance, 0, -1, 1), - OPT_GEOMETRY("geometry", vo.geometry, 0), - OPT_SIZE_BOX("autofit", vo.autofit, 0), - OPT_SIZE_BOX("autofit-larger", vo.autofit_larger, 0), - OPT_SIZE_BOX("autofit-smaller", vo.autofit_smaller, 0), - OPT_FLOATRANGE("window-scale", vo.window_scale, 0, 0.001, 100), - OPT_FLAG("force-window-position", vo.force_window_position, 0), - // vo name (X classname) and window title strings - OPT_STRING("x11-name", vo.winname, 0), OPT_STRING("title", wintitle, 0), OPT_STRING("force-media-title", media_title, 0), // set aspect ratio of monitor - useful for 16:9 TV-out - OPT_FLOATRANGE("monitoraspect", vo.force_monitor_aspect, 0, 0.0, 9.0), - OPT_FLOATRANGE("monitorpixelaspect", vo.monitor_pixel_aspect, 0, 0.2, 9.0), - // start in fullscreen mode: - OPT_FLAG("fullscreen", vo.fullscreen, M_OPT_FIXED), - OPT_FLAG("fs", vo.fullscreen, M_OPT_FIXED), - OPT_FLAG("native-keyrepeat", vo.native_keyrepeat, M_OPT_FIXED), - OPT_FLOATRANGE("panscan", vo.panscan, 0, 0.0, 1.0), - OPT_FLOATRANGE("video-zoom", vo.zoom, 0, -20.0, 20.0), - OPT_FLOATRANGE("video-pan-x", vo.pan_x, 0, -3.0, 3.0), - OPT_FLOATRANGE("video-pan-y", vo.pan_y, 0, -3.0, 3.0), - OPT_FLOATRANGE("video-align-x", vo.align_x, 0, -1.0, 1.0), - OPT_FLOATRANGE("video-align-y", vo.align_y, 0, -1.0, 1.0), - OPT_CHOICE("video-unscaled", vo.unscaled, 0, - ({"no", 0}, {"yes", 1}, {"downscale-big", 2})), OPT_FLAG("force-rgba-osd-rendering", force_rgba_osd, 0), OPT_CHOICE_OR_INT("video-rotate", video_rotate, 0, 0, 359, ({"no", -1})), @@ -466,28 +509,10 @@ const m_option_t mp_opts[] = { OPT_FLAG("cursor-autohide-fs-only", cursor_autohide_fs, 0), OPT_FLAG("stop-screensaver", stop_screensaver, 0), - OPT_INT64("wid", vo.WinID, 0), -#if HAVE_X11 - OPT_CHOICE("x11-netwm", vo.x11_netwm, 0, - ({"auto", 0}, {"no", -1}, {"yes", 1})), - OPT_CHOICE("x11-bypass-compositor", vo.x11_bypass_compositor, 0, - ({"no", 0}, {"yes", 1}, {"fs-only", 2}, {"never", 3})), -#endif -#if HAVE_WIN32 - OPT_STRING("vo-mmcss-profile", vo.mmcss_profile, M_OPT_FIXED), -#endif - OPT_STRING("heartbeat-cmd", heartbeat_cmd, 0, .deprecation_message = "use Lua scripting instead"), OPT_FLOAT("heartbeat-interval", heartbeat_interval, CONF_MIN, 0), - OPT_CHOICE_OR_INT("screen", vo.screen_id, 0, 0, 32, - ({"default", -1})), - - OPT_CHOICE_OR_INT("fs-screen", vo.fsscreen_id, 0, 0, 32, - ({"all", -2}, {"current", -1})), - - OPT_FLAG("fs-black-out-screens", vo.fs_black_out_screens, 0), OPT_INTRANGE("brightness", gamma_brightness, 0, -100, 100), OPT_INTRANGE("saturation", gamma_saturation, 0, -100, 100), OPT_INTRANGE("contrast", gamma_contrast, 0, -100, 100), @@ -495,8 +520,6 @@ const m_option_t mp_opts[] = { OPT_INTRANGE("gamma", gamma_gamma, 0, -100, 100), OPT_CHOICE_C("video-output-levels", video_output_levels, 0, mp_csp_levels_names), - OPT_FLAG("keepaspect", vo.keepaspect, 0), - OPT_FLAG("keepaspect-window", vo.keepaspect_window, 0), OPT_FLAG("use-filedir-conf", use_filedir_conf, 0), OPT_CHOICE("osd-level", osd_level, 0, @@ -614,6 +637,8 @@ const m_option_t mp_opts[] = { OPT_PRINT("version", print_version), OPT_PRINT("V", print_version), + OPT_SUBSTRUCT("", vo, vo_sub_opts, 0), + #if HAVE_ENCODING OPT_SUBSTRUCT("", encode_opts, encode_config, 0), #endif @@ -715,22 +740,6 @@ const struct MPOpts mp_default_opts = { .audio_buffer = 0.2, .audio_device = "auto", .audio_client_name = "mpv", - .vo = { - .video_driver_list = NULL, - .monitor_pixel_aspect = 1.0, - .screen_id = -1, - .fsscreen_id = -1, - .panscan = 0.0f, - .keepaspect = 1, - .keepaspect_window = 1, - .taskbar_progress = 1, - .border = 1, - .fit_border = 1, - .WinID = -1, - .window_scale = 1.0, - .x11_bypass_compositor = 2, - .mmcss_profile = "Playback", - }, .allow_win_drag = 1, .wintitle = "${?media-title:${media-title}}${!media-title:No file} - mpv", .heartbeat_interval = 30.0, diff --git a/options/options.h b/options/options.h index 187abc2c1a..130ab4c1cf 100644 --- a/options/options.h +++ b/options/options.h @@ -98,7 +98,7 @@ typedef struct MPOpts { int gapless_audio; double audio_buffer; - mp_vo_opts vo; + mp_vo_opts *vo; int allow_win_drag; char *wintitle; diff --git a/player/command.c b/player/command.c index 1c59d130ce..a59fa059b8 100644 --- a/player/command.c +++ b/player/command.c @@ -2371,10 +2371,10 @@ static int mp_property_fullscreen(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - int oldval = mpctx->opts->vo.fullscreen; + int oldval = mpctx->opts->vo->fullscreen; int r = mp_property_vo_flag(prop, action, arg, VOCTRL_FULLSCREEN, - &mpctx->opts->vo.fullscreen, mpctx); - if (oldval && oldval != mpctx->opts->vo.fullscreen) + &mpctx->opts->vo->fullscreen, mpctx); + if (oldval && oldval != mpctx->opts->vo->fullscreen) mpctx->mouse_event_ts--; // Show mouse cursor return r; } @@ -2386,9 +2386,9 @@ static int mp_property_taskbar_progress(void *ctx, struct m_property *prop, MPContext *mpctx = ctx; if (action == M_PROPERTY_SET) { int desired = !!*(int *) arg; - if (mpctx->opts->vo.taskbar_progress == desired) + if (mpctx->opts->vo->taskbar_progress == desired) return M_PROPERTY_OK; - mpctx->opts->vo.taskbar_progress = desired; + mpctx->opts->vo->taskbar_progress = desired; if (mpctx->video_out) update_vo_playback_state(mpctx); return M_PROPERTY_OK; @@ -2402,7 +2402,7 @@ static int mp_property_ontop(void *ctx, struct m_property *prop, { MPContext *mpctx = ctx; return mp_property_vo_flag(prop, action, arg, VOCTRL_ONTOP, - &mpctx->opts->vo.ontop, mpctx); + &mpctx->opts->vo->ontop, mpctx); } /// Show window borders (RW) @@ -2411,7 +2411,7 @@ static int mp_property_border(void *ctx, struct m_property *prop, { MPContext *mpctx = ctx; return mp_property_vo_flag(prop, action, arg, VOCTRL_BORDER, - &mpctx->opts->vo.border, mpctx); + &mpctx->opts->vo->border, mpctx); } static int mp_property_all_workspaces(void *ctx, struct m_property *prop, @@ -2419,7 +2419,7 @@ static int mp_property_all_workspaces(void *ctx, struct m_property *prop, { MPContext *mpctx = ctx; return mp_property_vo_flag(prop, action, arg, VOCTRL_ALL_WORKSPACES, - &mpctx->opts->vo.all_workspaces, mpctx); + &mpctx->opts->vo->all_workspaces, mpctx); } static int get_frame_count(struct MPContext *mpctx) diff --git a/player/configfiles.c b/player/configfiles.c index 7356a9a81b..59cb510bf8 100644 --- a/player/configfiles.c +++ b/player/configfiles.c @@ -152,8 +152,8 @@ void mp_load_auto_profiles(struct MPContext *mpctx) mp_load_per_file_config(mpctx); - if (opts->vo.video_driver_list) - mp_auto_load_profile(mpctx, "vo", bstr0(opts->vo.video_driver_list[0].name)); + if (opts->vo->video_driver_list) + mp_auto_l