summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Heinrich <christoph.heinrich@student.tugraz.at>2022-08-03 23:47:07 +0200
committerDudemanguy <random342@airmail.cc>2023-01-09 15:17:09 +0000
commitc4ec47a65e5840643024ba056ba4db20a4300ed2 (patch)
tree290cb471e55301f374a0607c30b4725c459c5966
parent67321b14402838eade127fa1d788a41906129b70 (diff)
downloadmpv-c4ec47a65e5840643024ba056ba4db20a4300ed2.tar.bz2
mpv-c4ec47a65e5840643024ba056ba4db20a4300ed2.tar.xz
player: add video-sync=display-tempo
So far there was no way to sync video to display and have audio sync to video without changes in pitch. With this option the audio does not get resampled (pitch change) and instead the corrected audio speed is applied to audio filters.
-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;
}