summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/interface-changes.rst1
-rw-r--r--DOCS/man/options.rst16
-rw-r--r--common/common.h2
-rw-r--r--options/options.c1
-rw-r--r--player/audio.c14
-rw-r--r--player/video.c13
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;
}