diff options
Diffstat (limited to 'player')
-rw-r--r-- | player/audio.c | 22 | ||||
-rw-r--r-- | player/core.h | 4 | ||||
-rw-r--r-- | player/playloop.c | 4 |
3 files changed, 30 insertions, 0 deletions
diff --git a/player/audio.c b/player/audio.c index fd007fedf7..e186a375b6 100644 --- a/player/audio.c +++ b/player/audio.c @@ -268,6 +268,7 @@ void reset_audio_state(struct MPContext *mpctx) mpctx->delay = 0; mpctx->audio_drop_throttle = 0; mpctx->audio_stat_start = 0; + mpctx->audio_allow_second_chance_seek = false; } void uninit_audio_out(struct MPContext *mpctx) @@ -688,6 +689,27 @@ static bool get_sync_samples(struct MPContext *mpctx, int *skip) } ptsdiff = MPCLAMP(ptsdiff, -3600, 3600); + // Heuristic: if audio is "too far" ahead, and one of them is a separate + // track, allow a refresh seek to the correct position to fix it. + if (ptsdiff > 0.2 && mpctx->audio_allow_second_chance_seek && sync_to_video) { + struct ao_chain *ao_c = mpctx->ao_chain; + if (ao_c && ao_c->track && mpctx->vo_chain && mpctx->vo_chain->track && + ao_c->track->demuxer != mpctx->vo_chain->track->demuxer) + { + struct track *track = ao_c->track; + double pts = mpctx->video_pts; + if (pts != MP_NOPTS_VALUE) + pts += get_track_seek_offset(mpctx, track); + // (disable it first to make it take any effect) + demuxer_select_track(track->demuxer, track->stream, pts, false); + demuxer_select_track(track->demuxer, track->stream, pts, true); + reset_audio_state(mpctx); + MP_VERBOSE(mpctx, "retrying audio seek\n"); + return false; + } + } + mpctx->audio_allow_second_chance_seek = false; + int align = af_format_sample_alignment(out_format.format); *skip = (int)(-ptsdiff * play_samplerate) / align * align; return true; diff --git a/player/core.h b/player/core.h index 1dc6da7331..70570fccb3 100644 --- a/player/core.h +++ b/player/core.h @@ -382,6 +382,10 @@ typedef struct MPContext { bool immediate; // disable seek delay logic } seek; + // Allow audio to issue a second seek if audio is too far ahead (for non-hr + // seeks with external audio tracks). + bool audio_allow_second_chance_seek; + /* Heuristic for relative chapter seeks: keep track which chapter * the user wanted to go to, even if we aren't exactly within the * boundaries of that chapter due to an inaccurate seek. */ diff --git a/player/playloop.c b/player/playloop.c index da3e995975..9b15ac3f50 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -298,6 +298,9 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek) mp_notify(mpctx, MPV_EVENT_SEEK, NULL); mp_notify(mpctx, MPV_EVENT_TICK, NULL); + + mpctx->audio_allow_second_chance_seek = + !hr_seek && !(demux_flags & SEEK_FORWARD); } // This combines consecutive seek requests. @@ -889,6 +892,7 @@ static void handle_playback_restart(struct MPContext *mpctx) if (!mpctx->restart_complete) { mpctx->hrseek_active = false; mpctx->restart_complete = true; + mpctx->audio_allow_second_chance_seek = false; mp_notify(mpctx, MPV_EVENT_PLAYBACK_RESTART, NULL); if (!mpctx->playing_msg_shown) { if (opts->playing_msg && opts->playing_msg[0]) { |