summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--player/audio.c8
-rw-r--r--player/core.h21
-rw-r--r--player/loadfile.c10
-rw-r--r--player/misc.c19
-rw-r--r--player/playloop.c6
-rw-r--r--player/video.c9
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);
}
}