summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--mpvcore/player/video.c42
-rw-r--r--video/decode/dec_video.c42
-rw-r--r--video/decode/dec_video.h2
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)