diff options
-rw-r--r-- | player/audio.c | 8 | ||||
-rw-r--r-- | player/core.h | 21 | ||||
-rw-r--r-- | player/loadfile.c | 10 | ||||
-rw-r--r-- | player/misc.c | 19 | ||||
-rw-r--r-- | player/playloop.c | 6 | ||||
-rw-r--r-- | player/video.c | 9 |
6 files changed, 40 insertions, 33 deletions
diff --git a/player/audio.c b/player/audio.c index 3fdd9ed28b..fcc442b974 100644 --- a/player/audio.c +++ b/player/audio.c @@ -279,12 +279,8 @@ int reinit_audio_filters(struct MPContext *mpctx) // Only force refresh if the amount of dropped buffered data is going to // cause "issues" for the A/V sync logic. - if (mpctx->audio_status == STATUS_PLAYING && - mpctx->playback_pts != MP_NOPTS_VALUE && delay > 0.2) - { - queue_seek(mpctx, MPSEEK_ABSOLUTE, mpctx->playback_pts, - MPSEEK_EXACT, 0); - } + if (mpctx->audio_status == STATUS_PLAYING && delay > 0.2) + issue_refresh_seek(mpctx, MPSEEK_EXACT); return 1; } diff --git a/player/core.h b/player/core.h index d341aeb529..bdb8b4c3a5 100644 --- a/player/core.h +++ b/player/core.h @@ -73,8 +73,8 @@ enum seek_type { }; enum seek_precision { - MPSEEK_DEFAULT = 0, // The following values are numerically sorted by increasing precision + MPSEEK_DEFAULT = 0, MPSEEK_KEYFRAME, MPSEEK_EXACT, MPSEEK_VERY_EXACT, @@ -85,6 +85,13 @@ enum seek_flags { MPSEEK_FLAG_NOFLUSH = 1 << 1, // keeping remaining data for seamless loops }; +struct seek_params { + enum seek_type type; + enum seek_precision exact; + double amount; + unsigned flags; // MPSEEK_FLAG_* +}; + enum video_sync { VS_DEFAULT = 0, VS_DISP_RESAMPLE, @@ -339,6 +346,7 @@ typedef struct MPContext { bool hrseek_lastframe; // drop everything until last frame reached bool hrseek_backstep; // go to frame before seek target double hrseek_pts; + struct seek_params current_seek; bool ab_loop_clip; // clip to the "b" part of an A-B loop if available // AV sync: the next frame should be shown when the audio out has this // much (in seconds) buffered data left. Increased when more data is @@ -367,8 +375,6 @@ typedef struct MPContext { double last_frame_duration; // Video PTS, or audio PTS if video has ended. double playback_pts; - // Last known "good" PTS - double canonical_pts; // audio stats only int64_t audio_stat_start; double written_audio; @@ -398,13 +404,7 @@ typedef struct MPContext { // Used to turn a new time value to a delta from last time. int64_t last_time; - // Used to communicate the parameters of a seek between parts - struct seek_params { - enum seek_type type; - enum seek_precision exact; - double amount; - unsigned flags; // MPSEEK_FLAG_* - } seek; + struct seek_params seek; // Allow audio to issue a second seek if audio is too far ahead (for non-hr // seeks with external audio tracks). @@ -532,6 +532,7 @@ struct MPContext *mp_create(void); void mp_destroy(struct MPContext *mpctx); void mp_print_version(struct mp_log *log, int always); void mp_update_logging(struct MPContext *mpctx, bool preinit); +void issue_refresh_seek(struct MPContext *mpctx, enum seek_precision min_prec); // misc.c double rel_time_to_abs(struct MPContext *mpctx, struct m_rel_time t); diff --git a/player/loadfile.c b/player/loadfile.c index 311280d915..4a5c0e1d2c 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -1127,13 +1127,8 @@ done: void update_lavfi_complex(struct MPContext *mpctx) { if (mpctx->playback_initialized) { - if (reinit_complex_filters(mpctx, false) != 0 && - mpctx->canonical_pts != MP_NOPTS_VALUE) - { - // Refresh seek to avoid weird situations. - queue_seek(mpctx, MPSEEK_ABSOLUTE, mpctx->canonical_pts, - MPSEEK_EXACT, 0); - } + if (reinit_complex_filters(mpctx, false) != 0) + issue_refresh_seek(mpctx, MPSEEK_EXACT); } } @@ -1166,7 +1161,6 @@ static void play_current_file(struct MPContext *mpctx) mpctx->speed_factor_a = mpctx->speed_factor_v = 1.0; mpctx->display_sync_error = 0.0; mpctx->display_sync_active = false; - mpctx->canonical_pts = MP_NOPTS_VALUE; mpctx->seek = (struct seek_params){ 0 }; reset_playback_state(mpctx); diff --git a/player/misc.c b/player/misc.c index 6762f8a518..87e6521b14 100644 --- a/player/misc.c +++ b/player/misc.c @@ -111,6 +111,25 @@ double get_track_seek_offset(struct MPContext *mpctx, struct track *track) return 0; } +void issue_refresh_seek(struct MPContext *mpctx, enum seek_precision min_prec) +{ + // let queued seeks execute at a slightly later point + if (mpctx->seek.type) { + mp_wakeup_core(mpctx); + return; + } + // repeat currently ongoing seeks + if (mpctx->current_seek.type) { + mpctx->seek = mpctx->current_seek; + mp_wakeup_core(mpctx); + return; + } + // maybe happens when changing filters while file is loaded - ignore for now + if (mpctx->playback_pts == MP_NOPTS_VALUE) + return; + queue_seek(mpctx, MPSEEK_ABSOLUTE, mpctx->playback_pts, min_prec, 0); +} + float mp_get_cache_percent(struct MPContext *mpctx) { struct stream_cache_info info = {0}; diff --git a/player/playloop.c b/player/playloop.c index 0d3409065b..ea73981a4f 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -232,6 +232,7 @@ void reset_playback_state(struct MPContext *mpctx) mpctx->hrseek_framedrop = false; mpctx->hrseek_lastframe = false; mpctx->hrseek_backstep = false; + mpctx->current_seek = (struct seek_params){0}; mpctx->playback_pts = MP_NOPTS_VALUE; mpctx->last_seek_pts = MP_NOPTS_VALUE; mpctx->cache_wait_time = 0; @@ -377,7 +378,7 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek) mpctx->ab_loop_clip = mpctx->last_seek_pts < opts->ab_loop[1]; - mpctx->canonical_pts = mpctx->last_seek_pts; + mpctx->current_seek = seek; } // This combines consecutive seek requests. @@ -958,8 +959,6 @@ static void handle_playback_time(struct MPContext *mpctx) { mpctx->playback_pts = playing_audio_pts(mpctx); } - if (mpctx->playback_pts != MP_NOPTS_VALUE) - mpctx->canonical_pts = mpctx->playback_pts; } // We always make sure audio and video buffers are filled before actually @@ -993,6 +992,7 @@ static void handle_playback_restart(struct MPContext *mpctx) if (!mpctx->restart_complete) { mpctx->hrseek_active = false; mpctx->restart_complete = true; + mpctx->current_seek = (struct seek_params){0}; mpctx->audio_allow_second_chance_seek = false; handle_playback_time(mpctx); mp_notify(mpctx, MPV_EVENT_PLAYBACK_RESTART, NULL); diff --git a/player/video.c b/player/video.c index 96e08ae815..0dca3a597f 100644 --- a/player/video.c +++ b/player/video.c @@ -551,13 +551,10 @@ void mp_force_video_refresh(struct MPContext *mpctx) return; // If not paused, the next frame should come soon enough. - if ((opts->pause || mpctx->time_frame >= 0.5) && - (mpctx->video_status >= STATUS_PLAYING || - mpctx->video_status <= STATUS_DRAINING) && - mpctx->last_vo_pts != MP_NOPTS_VALUE) + if (opts->pause || mpctx->time_frame >= 0.5 || + mpctx->video_status == STATUS_EOF) { - queue_seek(mpctx, MPSEEK_ABSOLUTE, mpctx->last_vo_pts, - MPSEEK_VERY_EXACT, 0); + issue_refresh_seek(mpctx, MPSEEK_VERY_EXACT); } } |