mirror of
https://github.com/mpv-player/mpv
synced 2025-02-16 12:17:12 +00:00
video: add an option to tune waiting for video timing
Probably mostly useful for the libmpv render API.
This commit is contained in:
parent
9ca1a1b068
commit
2c572e2bb1
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -50,6 +50,8 @@ typedef struct mp_vo_opts {
|
||||
|
||||
char *mmcss_profile;
|
||||
|
||||
double timing_offset;
|
||||
|
||||
// vo_drm
|
||||
struct sws_opts *sws_opts;
|
||||
// vo_drm
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user