player/video: don't reset ao on video chain reinit

3038e578af recently changed the logic here
so it wouldn't trigger on still images, but after thinking about the
code here some more, I don't believe it's needed at all. Doing an ao
reset when you flip the video track is very disruptive and not really
desirable at all. Since the ao no longer adds bogus delay values while
the video is off, there should be no need to do a full reset for syncing
reasons. The delay value will be zero, so we can let the audio just play
normally and let the video code do its thing. There is one slight trick
here however. When using a display sync mode, part of the syncing code
will try to update the audio and video playback speed. This can cause an
audio underrun if we're just turning the video back one. An easy way to
avoid most of these is to not update the speed if we are in the
STATUS_SYNCING state for video. This isn't quite perfect and underruns
are still possible, but it actually seems to depend on the AO. e.g. I
couldn't trigger an underrun with alsa but I could with pipewire. In any
case, the audio artifact here is much less noticeable than doing a full
ao reset, so it's still an improvement.
This commit is contained in:
Dudemanguy 2023-10-28 23:26:54 -05:00
parent 3789f1a387
commit 1f9d137153
1 changed files with 4 additions and 8 deletions

View File

@ -281,13 +281,6 @@ void reinit_video_chain_src(struct MPContext *mpctx, struct track *track)
vo_set_paused(vo_c->vo, get_internal_paused(mpctx));
// If we switch on video again, ensure audio position matches up.
if (mpctx->ao_chain && mpctx->ao_chain->ao && !(track && track->image)) {
ao_reset(mpctx->ao_chain->ao);
mpctx->ao_chain->start_pts_known = false;
mpctx->audio_status = STATUS_SYNCING;
}
reset_video_state(mpctx);
term_osd_set_subs(mpctx, NULL);
@ -929,7 +922,10 @@ static void handle_display_sync_frame(struct MPContext *mpctx,
frame->display_synced = true;
mpctx->display_sync_active = true;
update_playback_speed(mpctx);
// Try to avoid audio underruns that may occur if we update
// the playback speed while in the STATUS_SYNCING state.
if (mpctx->video_status != STATUS_SYNCING)
update_playback_speed(mpctx);
MP_STATS(mpctx, "value %f aspeed", mpctx->speed_factor_a - 1);
MP_STATS(mpctx, "value %f vspeed", mpctx->speed_factor_v - 1);