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.
This commit is contained in:
wm4 2013-11-25 23:16:22 +01:00
parent b5b1692593
commit 56d3ff33f1
3 changed files with 44 additions and 42 deletions

View File

@ -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))

View File

@ -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;
}

View File

@ -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)