player: limit speed change in display-sync adrop mode

Discontinuities (like toggling fullscreen) can cause multiple frames to
be dropped in succession, which sounds very weird. It's better to drop
some video frames instead to compensate for larger desyncs.

We roughly base it on the maximum allowed speed changes (audio change is
"additional" to the video change to account for deviations when playing
at max. video speed change).
This commit is contained in:
wm4 2015-11-03 20:29:25 +01:00
parent 163c6ad862
commit 49d94853b5
2 changed files with 9 additions and 0 deletions

View File

@ -154,6 +154,7 @@ void reset_audio_state(struct MPContext *mpctx)
mp_audio_buffer_clear(mpctx->ao_buffer);
mpctx->audio_status = mpctx->d_audio ? STATUS_SYNCING : STATUS_EOF;
mpctx->delay = 0;
mpctx->audio_drop_throttle = 0;
mpctx->audio_stat_start = 0;
}
@ -554,8 +555,11 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
}
int skip_duplicate = 0; // >0: skip, <0: duplicate
double drop_limit =
(opts->sync_max_audio_change + opts->sync_max_video_change) / 100;
if (mpctx->display_sync_active && opts->video_sync == VS_DISP_ADROP &&
fabs(mpctx->last_av_difference) >= opts->sync_audio_drop_size &&
mpctx->audio_drop_throttle < drop_limit &&
mpctx->audio_status == STATUS_PLAYING)
{
int samples = ceil(opts->sync_audio_drop_size * play_samplerate);
@ -565,6 +569,8 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
skip_duplicate = mpctx->last_av_difference >= 0 ? -samples : samples;
playsize = MPMAX(playsize, samples);
mpctx->audio_drop_throttle += 1 - drop_limit - samples / play_samplerate;
}
int status = AD_OK;
@ -683,6 +689,8 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
assert(played >= 0 && played <= data.samples);
mp_audio_buffer_skip(mpctx->ao_buffer, played);
mpctx->audio_drop_throttle -= played / play_samplerate;
dump_audio_stats(mpctx);
mpctx->audio_status = STATUS_PLAYING;

View File

@ -268,6 +268,7 @@ typedef struct MPContext {
int display_sync_drift_dir;
// Timing error (in seconds) due to rounding on vsync boundaries
double display_sync_error;
double audio_drop_throttle;
int display_sync_disable_counter;
// Number of mistimed frames.
int mistimed_frames_total;