player: fix audio drift computation at different playback speeds

This computed nonsense if the user set a playback speed other than 1
(in addition to the display-sync speed change).
This commit is contained in:
wm4 2015-11-14 21:42:18 +01:00
parent 0f3dedebb4
commit 9f43778eb2
1 changed files with 9 additions and 8 deletions

View File

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