summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-03-13 11:23:23 +0100
committerKevin Mitchell <kevmitch@gmail.com>2018-03-15 23:13:53 -0700
commit2c572e2bb1cfa4e225a6a1599f5ecdbcf4bf2dc6 (patch)
treed1006df2ce7b6ce598e7617cdb0fff6bb9575f69
parent9ca1a1b0686510d2b6471b36df9d0eea3fcfa3b3 (diff)
downloadmpv-2c572e2bb1cfa4e225a6a1599f5ecdbcf4bf2dc6.tar.bz2
mpv-2c572e2bb1cfa4e225a6a1599f5ecdbcf4bf2dc6.tar.xz
video: add an option to tune waiting for video timing
Probably mostly useful for the libmpv render API.
-rw-r--r--DOCS/man/options.rst20
-rw-r--r--libmpv/render.h6
-rw-r--r--options/m_option.h3
-rw-r--r--options/options.c2
-rw-r--r--options/options.h2
-rw-r--r--video/out/vo.c19
6 files changed, 50 insertions, 2 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 8713cf7244..16e4998453 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -5410,6 +5410,26 @@ Miscellaneous
out. This delay in reaction time to sudden A/V offsets should be the only
side effect of turning this option on, for all sound drivers.
+``--video-timing-offset=<seconds>``
+ Control how long before video display target time the frame should be
+ rendered (default: 0.050). If a video frame should be displayed at a
+ certain time, the VO will start rendering the frame earlier, and then will
+ perform a blocking wait until the display time, and only then "swap" the
+ frame to display. The rendering cannot start before the previous frame is
+ displayed, so this value is implicitly limited by the video framerate. With
+ normal video frame rates, the default value will ensure that rendering is
+ always immediately started after the previous frame was displayed. On the
+ other hand, setting a too high value can reduce responsiveness with low
+ FPS value.
+
+ For client API users using the render API (or the deprecated ``opengl-cb``
+ API), this option is interesting, because you can stop the render API
+ from limiting your FPS (see ``mpv_render_context_render()`` documentation).
+
+ This applies only to audio timing modes (e.g. ``--video-sync=audio``). In
+ other modes (``--video-sync=display-...``), video timing relies on vsync
+ blocking, and this option is not used.
+
``--video-sync=<audio|...>``
How the player synchronizes audio and video.
diff --git a/libmpv/render.h b/libmpv/render.h
index 64a317d73c..75153befb8 100644
--- a/libmpv/render.h
+++ b/libmpv/render.h
@@ -270,6 +270,12 @@ void mpv_render_context_set_update_callback(mpv_render_context *ctx,
* notifies you when a new frame was added. The details potentially depend on
* the backends and the provided parameters.
*
+ * Generally, libmpv will invoke your update callback some time before the video
+ * frame should be shown, and then lets this function block until the supposed
+ * display time. This will limit your rendering to video FPS. You can prevent
+ * this by setting the "video-timing-offset" global option to 0. (This applies
+ * only to "audio" video sync mode.)
+ *
* @param ctx a valid render context
* @param params an array of parameters, terminated by type==0. Which parameters
* are required depends on the backend. It's left unspecified what
diff --git a/options/m_option.h b/options/m_option.h
index 078e9248b9..2402405cde 100644
--- a/options/m_option.h
+++ b/options/m_option.h
@@ -616,6 +616,9 @@ extern const char m_option_path_separator;
#define OPT_FLOATRANGE(...) \
OPT_RANGE_(float, __VA_ARGS__, .type = &m_option_type_float)
+#define OPT_DOUBLERANGE(...) \
+ OPT_RANGE_(double, __VA_ARGS__, .type = &m_option_type_double)
+
#define OPT_INTPAIR(...) \
OPT_GENERAL_NOTYPE(__VA_ARGS__, .type = &m_option_type_intpair)
diff --git a/options/options.c b/options/options.c
index ebccc5976f..7c7a30ed27 100644
--- a/options/options.c
+++ b/options/options.c
@@ -139,6 +139,7 @@ static const m_option_t mp_vo_opt_list[] = {
OPT_FLAG("keepaspect-window", keepaspect_window, 0),
OPT_FLAG("hidpi-window-scale", hidpi_window_scale, 0),
OPT_FLAG("native-fs", native_fs, 0),
+ OPT_DOUBLERANGE("video-timing-offset", timing_offset, 0, 0.0, 1.0),
#if HAVE_X11
OPT_CHOICE("x11-netwm", x11_netwm, 0,
({"auto", 0}, {"no", -1}, {"yes", 1})),
@@ -176,6 +177,7 @@ const struct m_sub_options vo_sub_opts = {
.x11_bypass_compositor = 2,
.mmcss_profile = "Playback",
.ontop_level = -1,
+ .timing_offset = 0.050,
},
};
diff --git a/options/options.h b/options/options.h
index 1c58ca14b1..303b2e5761 100644
--- a/options/options.h
+++ b/options/options.h
@@ -50,6 +50,8 @@ typedef struct mp_vo_opts {
char *mmcss_profile;
+ double timing_offset;
+
// vo_drm
struct sws_opts *sws_opts;
// vo_drm
diff --git a/video/out/vo.c b/video/out/vo.c
index ac4fa9a773..fc4630b731 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -147,6 +147,7 @@ struct vo_internal {
int64_t num_successive_vsyncs;
int64_t flip_queue_offset; // queue flip events at most this much in advance
+ int64_t timing_offset; // same (but from options; not VO configured)
int64_t delayed_count;
int64_t drop_count;
@@ -212,11 +213,23 @@ static void dispatch_wakeup_cb(void *ptr)
vo_wakeup(vo);
}
+// Initialize or update options from vo->opts
+static void read_opts(struct vo *vo)
+{
+ struct vo_internal *in = vo->in;
+
+ pthread_mutex_lock(&in->lock);
+ in->timing_offset = (uint64_t)(vo->opts->timing_offset * 1e6);
+ pthread_mutex_unlock(&in->lock);
+}
+
static void update_opts(void *p)
{
struct vo *vo = p;
if (m_config_cache_update(vo->opts_cache)) {
+ read_opts(vo);
+
// "Legacy" update of video position related options.
if (vo->driver->control)
vo->driver->control(vo, VOCTRL_SET_PANSCAN, NULL);
@@ -728,8 +741,9 @@ bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts)
if (r && next_pts >= 0) {
// Don't show the frame too early - it would basically freeze the
// display by disallowing OSD redrawing or VO interaction.
- // Actually render the frame at earliest 50ms before target time.
- next_pts -= (uint64_t)(0.050 * 1e6);
+ // Actually render the frame at earliest the given offset before target
+ // time.
+ next_pts -= in->timing_offset;
next_pts -= in->flip_queue_offset;
int64_t now = mp_time_us();
if (next_pts > now)
@@ -1003,6 +1017,7 @@ static void *vo_thread(void *ptr)
if (r < 0)
return NULL;
+ read_opts(vo);
update_display_fps(vo);
vo_event(vo, VO_EVENT_WIN_STATE);