mirror of https://github.com/mpv-player/mpv
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:
parent
b5b1692593
commit
56d3ff33f1
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue