summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mpvcore/player/audio.c2
-rw-r--r--mpvcore/player/mp_core.h3
-rw-r--r--mpvcore/player/playloop.c7
-rw-r--r--mpvcore/player/video.c32
-rw-r--r--video/decode/dec_video.c8
-rw-r--r--video/decode/dec_video.h3
6 files changed, 24 insertions, 31 deletions
diff --git a/mpvcore/player/audio.c b/mpvcore/player/audio.c
index 042e6d66c3..ec2f039531 100644
--- a/mpvcore/player/audio.c
+++ b/mpvcore/player/audio.c
@@ -303,7 +303,7 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize)
if (hrseek)
ptsdiff = written_pts - mpctx->hrseek_pts;
else
- ptsdiff = written_pts - mpctx->d_video->pts - mpctx->delay
+ ptsdiff = written_pts - mpctx->video_next_pts - mpctx->delay
- mpctx->audio_delay;
samples = ptsdiff * real_samplerate;
diff --git a/mpvcore/player/mp_core.h b/mpvcore/player/mp_core.h
index c1fbf737f3..4aabf6a991 100644
--- a/mpvcore/player/mp_core.h
+++ b/mpvcore/player/mp_core.h
@@ -248,6 +248,9 @@ typedef struct MPContext {
// the same value if the status line is updated at a time where no new
// video frame is shown.
double last_av_difference;
+ /* Timestamp of the latest image that was queued on the VO, but not yet
+ * to be flipped. */
+ double video_next_pts;
/* timestamp of video frame currently visible on screen
* (or at least queued to be flipped by VO) */
double video_pts;
diff --git a/mpvcore/player/playloop.c b/mpvcore/player/playloop.c
index 650f164f05..9ec62834b4 100644
--- a/mpvcore/player/playloop.c
+++ b/mpvcore/player/playloop.c
@@ -173,6 +173,7 @@ static void seek_reset(struct MPContext *mpctx, bool reset_ao)
video_reset_decoding(mpctx->d_video);
vo_seek_reset(mpctx->video_out);
mpctx->video_pts = MP_NOPTS_VALUE;
+ mpctx->video_next_pts = MP_NOPTS_VALUE;
mpctx->delay = 0;
mpctx->time_frame = 0;
}
@@ -616,7 +617,7 @@ static void adjust_sync(struct MPContext *mpctx, double frame_time)
return;
double a_pts = written_audio_pts(mpctx) - mpctx->delay;
- double v_pts = mpctx->d_video->pts;
+ double v_pts = mpctx->video_next_pts;
double av_delay = a_pts - v_pts;
// Try to sync vo_flip() so it will *finish* at given time
av_delay += mpctx->last_vo_flip_duration;
@@ -1010,7 +1011,7 @@ void run_playloop(struct MPContext *mpctx)
}
if (endpts != MP_NOPTS_VALUE)
- video_left &= mpctx->d_video->pts < endpts;
+ video_left &= mpctx->video_next_pts < endpts;
handle_heartbeat_cmd(mpctx);
@@ -1064,7 +1065,7 @@ void run_playloop(struct MPContext *mpctx)
//=================== FLIP PAGE (VIDEO BLT): ======================
vo_new_frame_imminent(vo);
- mpctx->video_pts = mpctx->d_video->pts;
+ mpctx->video_pts = mpctx->video_next_pts;
mpctx->last_vo_pts = mpctx->video_pts;
mpctx->playback_pts = mpctx->video_pts;
update_subtitles(mpctx);
diff --git a/mpvcore/player/video.c b/mpvcore/player/video.c
index 45cfd6ebf4..a758995c09 100644
--- a/mpvcore/player/video.c
+++ b/mpvcore/player/video.c
@@ -145,6 +145,7 @@ int reinit_video_chain(struct MPContext *mpctx)
mpctx->restart_playback = true;
mpctx->sync_audio_to_video = !sh->attached_picture;
mpctx->delay = 0;
+ mpctx->video_next_pts = MP_NOPTS_VALUE;
mpctx->vo_pts_history_seek_ts++;
vo_seek_reset(mpctx->video_out);
@@ -277,7 +278,7 @@ static double update_video_attached_pic(struct MPContext *mpctx)
if (decoded_frame)
filter_video(mpctx, decoded_frame);
load_next_vo_frame(mpctx, true);
- d_video->pts = MP_NOPTS_VALUE;
+ mpctx->video_next_pts = MP_NOPTS_VALUE;
return 0;
}
@@ -320,29 +321,16 @@ double update_video(struct MPContext *mpctx, double endpts)
return 0;
}
mpctx->hrseek_active = false;
- d_video->pts = pts;
- if (d_video->last_pts == MP_NOPTS_VALUE) {
- d_video->last_pts = d_video->pts;
- } else if (d_video->last_pts > d_video->pts) {
- MP_WARN(mpctx, "Decreasing video pts: %f < %f\n",
- d_video->pts, d_video->last_pts);
- /* If the difference in pts is small treat it as jitter around the
- * right value (possibly caused by incorrect timestamp ordering) and
- * just show this frame immediately after the last one.
- * Treat bigger differences as timestamp resets and start counting
- * timing of later frames from the position of this one. */
- if (d_video->last_pts - d_video->pts > 0.5)
- d_video->last_pts = d_video->pts;
- else
- d_video->pts = d_video->last_pts;
- } else if (d_video->pts >= d_video->last_pts + 60) {
+ double last_pts = mpctx->video_next_pts;
+ if (last_pts == MP_NOPTS_VALUE)
+ last_pts = pts;
+ double frame_time = MPMAX(0, pts - last_pts);
+ if (frame_time >= 60) {
// Assume a PTS difference >= 60 seconds is a discontinuity.
- MP_WARN(mpctx, "Jump in video pts: %f -> %f\n",
- d_video->last_pts, d_video->pts);
- d_video->last_pts = d_video->pts;
+ MP_WARN(mpctx, "Jump in video pts: %f -> %f\n", last_pts, pts);
+ frame_time = 0;
}
- double frame_time = d_video->pts - d_video->last_pts;
- d_video->last_pts = d_video->pts;
+ mpctx->video_next_pts = pts;
if (mpctx->d_audio)
mpctx->delay -= frame_time;
return frame_time;
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c
index 402bb805ef..1802e19fbf 100644
--- a/video/decode/dec_video.c
+++ b/video/decode/dec_video.c
@@ -69,7 +69,6 @@ void video_reset_decoding(struct dec_video *d_video)
d_video->codec_dts = MP_NOPTS_VALUE;
d_video->sorted_pts = MP_NOPTS_VALUE;
d_video->unsorted_pts = MP_NOPTS_VALUE;
- d_video->pts = MP_NOPTS_VALUE;
}
int video_vd_control(struct dec_video *d_video, int cmd, void *arg)
@@ -358,9 +357,14 @@ struct mp_image *video_decode(struct dec_video *d_video,
pts += frame_time;
}
+ if (d_video->decoded_pts != MP_NOPTS_VALUE && pts < d_video->decoded_pts) {
+ mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Decreasing video pts: %f < %f\n",
+ pts, d_video->decoded_pts);
+ pts = d_video->decoded_pts;
+ }
+
mpi->pts = pts;
d_video->decoded_pts = pts;
- d_video->pts = pts;
return mpi;
}
diff --git a/video/decode/dec_video.h b/video/decode/dec_video.h
index 9117fceefd..d411717a32 100644
--- a/video/decode/dec_video.h
+++ b/video/decode/dec_video.h
@@ -65,9 +65,6 @@ struct dec_video {
// Final PTS of previously decoded image
double decoded_pts;
- // PTS of the last decoded frame (often overwritten by player)
- double pts;
-
float stream_aspect; // aspect ratio in media headers (DVD IFO files)
int i_bps; // == bitrate (compressed bytes/sec)
float fps; // FPS from demuxer or from user override