diff options
-rw-r--r-- | DOCS/interface-changes.rst | 1 | ||||
-rw-r--r-- | DOCS/man/options.rst | 16 | ||||
-rw-r--r-- | common/common.h | 2 | ||||
-rw-r--r-- | options/options.c | 1 | ||||
-rw-r--r-- | player/audio.c | 14 | ||||
-rw-r--r-- | player/video.c | 13 |
6 files changed, 37 insertions, 10 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index bfdd5e172d..f1788147a4 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -40,6 +40,7 @@ Interface changes `--vo-sixel-alt-screen` - deprecate `--drm-atomic` - add `--demuxer-hysteresis-secs` + - add `--video-sync=display-tempo` --- mpv 0.35.0 --- - add the `--vo=gpu-next` video output driver, as well as the options `--allow-delayed-peak-detect`, `--builtin-scalers`, diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index e97cb63b0d..bd8037379b 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -6845,6 +6845,15 @@ Miscellaneous :display-resample-vdrop: Resample audio to match the video. Drop video frames to compensate for drift. :display-resample-desync: Like the previous mode, but no A/V compensation. + :display-tempo: Same as ``display-resample``, but apply audio speed + changes to audio filters instead of resampling to avoid + the change in pitch. Beware that some audio filters + don't do well with a speed close to 1. It is recommend + to use a conditional profile to automatically switch to + ``display-resample`` when speed gets too close to 1 for + your filter setup. Use (speed * video_speed_correction) + to get the actual playback speed in the condition. + See `Conditional auto profiles`_ for details. :display-vdrop: Drop or repeat video frames to compensate desyncing video. (Although it should have the same effects as ``audio``, the implementation is very different.) @@ -6883,8 +6892,11 @@ Miscellaneous 25 fps. We consider the pitch change too extreme to allow this behavior by default. Set this option to a value of ``5`` to enable it. - Note that in the ``--video-sync=display-resample`` mode, audio speed will - additionally be changed by a small amount if necessary for A/V sync. See + Note that ``--video-sync=display-tempo`` avoids this pitch change. + + Also note that in the ``--video-sync=display-resample`` or + ``--video-sync=display-tempo`` mode, audio speed will additionally be + changed by a small amount if necessary for A/V sync. See ``--video-sync-max-audio-change``. ``--video-sync-max-audio-change=<value>`` diff --git a/common/common.h b/common/common.h index 124a0e4956..206062e8ed 100644 --- a/common/common.h +++ b/common/common.h @@ -73,6 +73,7 @@ enum video_sync { VS_DISP_RESAMPLE, VS_DISP_RESAMPLE_VDROP, VS_DISP_RESAMPLE_NONE, + VS_DISP_TEMPO, VS_DISP_ADROP, VS_DISP_VDROP, VS_DISP_NONE, @@ -82,6 +83,7 @@ enum video_sync { #define VS_IS_DISP(x) ((x) == VS_DISP_RESAMPLE || \ (x) == VS_DISP_RESAMPLE_VDROP || \ (x) == VS_DISP_RESAMPLE_NONE || \ + (x) == VS_DISP_TEMPO || \ (x) == VS_DISP_ADROP || \ (x) == VS_DISP_VDROP || \ (x) == VS_DISP_NONE) diff --git a/options/options.c b/options/options.c index 8785d78182..8075f02077 100644 --- a/options/options.c +++ b/options/options.c @@ -168,6 +168,7 @@ static const m_option_t mp_vo_opt_list[] = { {"display-resample", VS_DISP_RESAMPLE}, {"display-resample-vdrop", VS_DISP_RESAMPLE_VDROP}, {"display-resample-desync", VS_DISP_RESAMPLE_NONE}, + {"display-tempo", VS_DISP_TEMPO}, {"display-adrop", VS_DISP_ADROP}, {"display-vdrop", VS_DISP_VDROP}, {"display-desync", VS_DISP_NONE}, diff --git a/player/audio.c b/player/audio.c index 9e1bb708d5..40a6a3a32a 100644 --- a/player/audio.c +++ b/player/audio.c @@ -64,9 +64,17 @@ static void update_speed_filters(struct MPContext *mpctx) speed = 1.0; } - if (mpctx->display_sync_active && mpctx->video_out->opts->video_sync == VS_DISP_ADROP) { - drop *= speed * resample; - resample = speed = 1.0; + if (mpctx->display_sync_active) { + switch (mpctx->video_out->opts->video_sync) { + case VS_DISP_ADROP: + drop *= speed * resample; + resample = speed = 1.0; + break; + case VS_DISP_TEMPO: + speed = mpctx->audio_speed; + resample = 1.0; + break; + } } mp_output_chain_set_audio_speed(ao_c->filter, speed, resample, drop); diff --git a/player/video.c b/player/video.c index 1ea68f92df..63763d22e5 100644 --- a/player/video.c +++ b/player/video.c @@ -736,12 +736,14 @@ static double compute_audio_drift(struct MPContext *mpctx, double vsync) return (sum_x * sum_y - num * sum_xy) / (sum_x * sum_x - num * sum_xx); } -static void adjust_audio_resample_speed(struct MPContext *mpctx, double vsync) +static void adjust_audio_drift_compensation(struct MPContext *mpctx, double vsync) { struct MPOpts *opts = mpctx->opts; int mode = mpctx->video_out->opts->video_sync; - if (mode != VS_DISP_RESAMPLE || mpctx->audio_status != STATUS_PLAYING) { + if ((mode != VS_DISP_RESAMPLE && mode != VS_DISP_TEMPO) || + mpctx->audio_status != STATUS_PLAYING) + { mpctx->speed_factor_a = mpctx->speed_factor_v; return; } @@ -813,7 +815,8 @@ static void handle_display_sync_frame(struct MPContext *mpctx, bool resample = mode == VS_DISP_RESAMPLE || mode == VS_DISP_RESAMPLE_VDROP || mode == VS_DISP_RESAMPLE_NONE; bool drop = mode == VS_DISP_VDROP || mode == VS_DISP_RESAMPLE || - mode == VS_DISP_ADROP || mode == VS_DISP_RESAMPLE_VDROP; + mode == VS_DISP_ADROP || mode == VS_DISP_RESAMPLE_VDROP || + mode == VS_DISP_TEMPO; drop &= frame->can_drop; if (resample && using_spdif_passthrough(mpctx)) @@ -896,8 +899,8 @@ static void handle_display_sync_frame(struct MPContext *mpctx, mpctx->past_frames[0].num_vsyncs = num_vsyncs; mpctx->past_frames[0].av_diff = mpctx->last_av_difference; - if (resample || mode == VS_DISP_ADROP) { - adjust_audio_resample_speed(mpctx, vsync); + if (resample || mode == VS_DISP_ADROP || mode == VS_DISP_TEMPO) { + adjust_audio_drift_compensation(mpctx, vsync); } else { mpctx->speed_factor_a = 1.0; } |