diff options
author | wm4 <wm4@nowhere> | 2013-11-25 23:16:22 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2013-11-25 23:16:22 +0100 |
commit | 56d3ff33f123f06b6533d7fab726e5ac4a0013ae (patch) | |
tree | 9b54b6a9ab68abb0a7f5108edd7990f3bafe6499 /video | |
parent | b5b16925938fd37a604f5235afc7257f0b9bd6c7 (diff) | |
download | mpv-56d3ff33f123f06b6533d7fab726e5ac4a0013ae.tar.bz2 mpv-56d3ff33f123f06b6533d7fab726e5ac4a0013ae.tar.xz |
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.
Diffstat (limited to 'video')
-rw-r--r-- | video/decode/dec_video.c | 42 | ||||
-rw-r--r-- | video/decode/dec_video.h | 2 |
2 files changed, 44 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; } 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) |