diff options
Diffstat (limited to 'video/decode/dec_video.c')
-rw-r--r-- | video/decode/dec_video.c | 42 |
1 files changed, 42 insertions, 0 deletions
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; } |