From 56d3ff33f123f06b6533d7fab726e5ac4a0013ae Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 25 Nov 2013 23:16:22 +0100 Subject: video: move timestamp determination code to dec_video This means the code that tries to figure out the timestamp from demuxer and decoder output is now all in dec_video.c. We set the final timestamp on the returned image (mp_image.pts), as well as the d_video->pts field. The way the player uses d_video->pts field is still a bit messy. Maybe this could be cleaned up later. --- video/decode/dec_video.c | 42 ++++++++++++++++++++++++++++++++++++++++++ video/decode/dec_video.h | 2 ++ 2 files changed, 44 insertions(+) (limited to 'video') diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c index d0d7355803..8d4b6cb194 100644 --- a/video/decode/dec_video.c +++ b/video/decode/dec_video.c @@ -205,6 +205,46 @@ bool video_init_best_codec(struct dec_video *d_video, char* video_decoders) return !!d_video->vd_driver; } +static void determine_frame_pts(struct dec_video *d_video) +{ + struct MPOpts *opts = d_video->opts; + + if (!opts->correct_pts) { + double frame_time = 1.0f / (d_video->fps > 0 ? d_video->fps : 25); + double pkt_pts = d_video->last_packet_pts; + if (d_video->pts == MP_NOPTS_VALUE) + d_video->pts = pkt_pts == MP_NOPTS_VALUE ? 0 : pkt_pts; + + d_video->pts = d_video->pts + frame_time; + return; + } + + if (opts->user_pts_assoc_mode) + d_video->pts_assoc_mode = opts->user_pts_assoc_mode; + else if (d_video->pts_assoc_mode == 0) { + if (d_video->codec_reordered_pts != MP_NOPTS_VALUE) + d_video->pts_assoc_mode = 1; + else + d_video->pts_assoc_mode = 2; + } else { + int probcount1 = d_video->num_reordered_pts_problems; + int probcount2 = d_video->num_sorted_pts_problems; + if (d_video->pts_assoc_mode == 2) { + int tmp = probcount1; + probcount1 = probcount2; + probcount2 = tmp; + } + if (probcount1 >= probcount2 * 1.5 + 2) { + d_video->pts_assoc_mode = 3 - d_video->pts_assoc_mode; + mp_msg(MSGT_DECVIDEO, MSGL_WARN, + "Switching to pts association mode %d.\n", + d_video->pts_assoc_mode); + } + } + d_video->pts = d_video->pts_assoc_mode == 1 ? + d_video->codec_reordered_pts : d_video->sorted_pts; +} + struct mp_image *video_decode(struct dec_video *d_video, struct demux_packet *packet, int drop_frame) @@ -286,6 +326,8 @@ struct mp_image *video_decode(struct dec_video *d_video, if (prevpts != MP_NOPTS_VALUE && pts <= prevpts || pts == MP_NOPTS_VALUE) d_video->num_sorted_pts_problems++; + determine_frame_pts(d_video); + mpi->pts = d_video->pts; return mpi; } diff --git a/video/decode/dec_video.h b/video/decode/dec_video.h index 827dcb6237..6259d5b0d4 100644 --- a/video/decode/dec_video.h +++ b/video/decode/dec_video.h @@ -51,6 +51,8 @@ struct dec_video { double prev_sorted_pts; int num_sorted_pts_problems; int pts_assoc_mode; + + // PTS of the last decoded frame (often overwritten by player) double pts; float stream_aspect; // aspect ratio in media headers (DVD IFO files) -- cgit v1.2.3