diff --git a/player/video.c b/player/video.c index f6ab3d44c9..043abeb3b1 100644 --- a/player/video.c +++ b/player/video.c @@ -854,11 +854,11 @@ static bool using_spdif_passthrough(struct MPContext *mpctx) return false; } -// Compute the relative audio speed by taking A/V dsync into account. -static double compute_audio_speed(struct MPContext *mpctx, double vsync) +// Compute the relative audio speed difference by taking A/V dsync into account. +static double compute_audio_drift(struct MPContext *mpctx, double vsync) { - // Least-squares linear regression, using relative file PTS values for x, - // and audio time for y. Assume speed didn't change for the frames we're + // Least-squares linear regression, using relative real time for x, and + // audio desync for y. Assume speed didn't change for the frames we're // looking at for simplicity. This also should actually use the realtime // (minus paused time) for x, but use vsync scheduling points instead. if (mpctx->num_past_frames <= 10) @@ -870,7 +870,7 @@ static double compute_audio_speed(struct MPContext *mpctx, double vsync) struct frame_info *frame = &mpctx->past_frames[n + 1]; if (frame->num_vsyncs < 0) return NAN; - double y = frame->av_diff + x; + double y = frame->av_diff; sum_x += x; sum_y += y; sum_xy += x * y; @@ -923,10 +923,11 @@ static void adjust_audio_resample_speed(struct MPContext *mpctx, double vsync) if (new == 0) { // If we're resetting, actually try to be clever and pick a speed // which compensates the general drift we're getting. - double drift = compute_audio_speed(mpctx, vsync); + double drift = compute_audio_drift(mpctx, vsync); if (isnormal(drift)) { - drift /= mpctx->audio_speed; // eliminate intended speed - audio_factor = 1.0 / drift / mpctx->speed_factor_v; + // other = will be multiplied with audio_factor for final speed + double other = mpctx->opts->playback_speed * mpctx->speed_factor_v; + audio_factor = (mpctx->audio_speed - drift) / other; MP_VERBOSE(mpctx, "Compensation factor: %f\n", audio_factor); } }