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. --- mpvcore/player/video.c | 42 ------------------------------------------ video/decode/dec_video.c | 42 ++++++++++++++++++++++++++++++++++++++++++ video/decode/dec_video.h | 2 ++ 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/mpvcore/player/video.c b/mpvcore/player/video.c index a1585e560d..a3fef6d53c 100644 --- a/mpvcore/player/video.c +++ b/mpvcore/player/video.c @@ -236,7 +236,6 @@ static void filter_video(struct MPContext *mpctx, struct mp_image *frame) init_filter_params(mpctx); - frame->pts = d_video->pts; mp_image_set_params(frame, &d_video->vf_input); // force csp/aspect overrides vf_filter_frame(d_video->vfilter, frame); filter_output_queued_frame(mpctx); @@ -284,46 +283,6 @@ static double update_video_attached_pic(struct MPContext *mpctx) return 0; } -static void determine_frame_pts(struct MPContext *mpctx) -{ - struct dec_video *d_video = mpctx->d_video; - struct MPOpts *opts = mpctx->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_WARN(mpctx, "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; -} - double update_video(struct MPContext *mpctx, double endpts) { struct dec_video *d_video = mpctx->d_video; @@ -356,7 +315,6 @@ double update_video(struct MPContext *mpctx, double endpts) video_decode(d_video, pkt, framedrop_type); talloc_free(pkt); if (decoded_frame) { - determine_frame_pts(mpctx); filter_video(mpctx, decoded_frame); } else if (!pkt) { if (!load_next_vo_frame(mpctx, true)) 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