mirror of
https://github.com/mpv-player/mpv.git
synced 2026-10-28 23:13:18 +08:00
video: add heuristic to prevent framedrop during hrseek if pts broken
Using --start with files that use DTS only, or which simply have broken PTS timestamps, would incorrectly drop frames and possibly not execute the seek correctly. Add yet another heuristic to detect this. The intent is that --start and hr-seeks in general should work correctly, but in order to keep things fast, we still want to allow frame dropping during hr-seek if there are no problems doing so. Do this by disabling frame dropping by default, but re-enabling it if there are no problems found for a while. As a consequence, --start might be somewhat slower, but normal user interaction should remain as fast as before. Note that there's something subtle about the added code: the has_broken_packet_pts field is checked even before the first packet is fed to dec_video.c, so the field must not be set to 0 right on start. It's not initially set to 0 anyway, because the heuristic requires decoding some images before enabling frame drop anyway. Note 2: it's not clear whether frame dropping during hr-seek really helps; I didn't benchmark it.
This commit is contained in:
@@ -295,8 +295,11 @@ double update_video(struct MPContext *mpctx, double endpts)
|
||||
struct demux_packet *pkt = demux_read_packet(d_video->header);
|
||||
if (pkt && pkt->pts != MP_NOPTS_VALUE)
|
||||
pkt->pts += mpctx->video_offset;
|
||||
if (pkt && pkt->pts >= mpctx->hrseek_pts - .005)
|
||||
if ((pkt && pkt->pts >= mpctx->hrseek_pts - .005) ||
|
||||
d_video->has_broken_packet_pts)
|
||||
{
|
||||
mpctx->hrseek_framedrop = false;
|
||||
}
|
||||
int framedrop_type = mpctx->hrseek_active && mpctx->hrseek_framedrop ?
|
||||
1 : check_framedrop(mpctx, -1);
|
||||
struct mp_image *decoded_frame =
|
||||
|
||||
@@ -171,6 +171,7 @@ bool video_init_best_codec(struct dec_video *d_video, char* video_decoders)
|
||||
{
|
||||
assert(!d_video->vd_driver);
|
||||
video_reset_decoding(d_video);
|
||||
d_video->has_broken_packet_pts = -10; // needs 10 packets to reach decision
|
||||
|
||||
struct mp_decoder_entry *decoder = NULL;
|
||||
struct mp_decoder_list *list =
|
||||
@@ -363,6 +364,11 @@ struct mp_image *video_decode(struct dec_video *d_video,
|
||||
pts = d_video->decoded_pts;
|
||||
}
|
||||
|
||||
if (d_video->has_broken_packet_pts < 0)
|
||||
d_video->has_broken_packet_pts++;
|
||||
if (d_video->num_codec_pts_problems || pkt_pts == MP_NOPTS_VALUE)
|
||||
d_video->has_broken_packet_pts = 1;
|
||||
|
||||
mpi->pts = pts;
|
||||
d_video->decoded_pts = pts;
|
||||
return mpi;
|
||||
|
||||
@@ -62,6 +62,9 @@ struct dec_video {
|
||||
// PTS or DTS of packet last read
|
||||
double last_packet_pdts;
|
||||
|
||||
// There was at least one packet with non-sense timestamps.
|
||||
int has_broken_packet_pts; // <0: uninitialized, 0: no problems, 1: broken
|
||||
|
||||
// Final PTS of previously decoded image
|
||||
double decoded_pts;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user