summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-25 23:16:22 +0100
committerwm4 <wm4@nowhere>2013-11-25 23:16:22 +0100
commit56d3ff33f123f06b6533d7fab726e5ac4a0013ae (patch)
tree9b54b6a9ab68abb0a7f5108edd7990f3bafe6499 /video
parentb5b16925938fd37a604f5235afc7257f0b9bd6c7 (diff)
downloadmpv-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.c42
-rw-r--r--video/decode/dec_video.h2
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)