mirror of https://github.com/mpv-player/mpv
video: use demuxer-signaled duration for last video frame
Helps with gif, probably does unwanted things with other formats. This doesn't handle --end quite correctly, but this could be added later. Fixes #3924.
This commit is contained in:
parent
1ba3525816
commit
b1c0bbe8b8
|
@ -353,6 +353,9 @@ typedef struct MPContext {
|
|||
// As video_pts, but is not reset when seeking away. (For the very short
|
||||
// period of time until a new frame is decoded and shown.)
|
||||
double last_vo_pts;
|
||||
// Frame duration field from demuxer. Only used for duration of the last
|
||||
// video frame.
|
||||
double last_frame_duration;
|
||||
// Video PTS, or audio PTS if video has ended.
|
||||
double playback_pts;
|
||||
// audio stats only
|
||||
|
|
|
@ -343,6 +343,7 @@ void reset_video_state(struct MPContext *mpctx)
|
|||
mpctx->delay = 0;
|
||||
mpctx->time_frame = 0;
|
||||
mpctx->video_pts = MP_NOPTS_VALUE;
|
||||
mpctx->last_frame_duration = 0;
|
||||
mpctx->num_past_frames = 0;
|
||||
mpctx->total_avsync_change = 0;
|
||||
mpctx->last_av_difference = 0;
|
||||
|
@ -1369,6 +1370,9 @@ void write_video(struct MPContext *mpctx)
|
|||
{
|
||||
MP_VERBOSE(mpctx, "assuming this is an image\n");
|
||||
mpctx->time_frame += opts->image_display_duration;
|
||||
} else if (mpctx->last_frame_duration > 0) {
|
||||
MP_VERBOSE(mpctx, "using demuxer frame duration for last frame\n");
|
||||
mpctx->time_frame += mpctx->last_frame_duration;
|
||||
} else {
|
||||
mpctx->time_frame = 0;
|
||||
}
|
||||
|
@ -1482,6 +1486,8 @@ void write_video(struct MPContext *mpctx)
|
|||
|
||||
mpctx->video_pts = mpctx->next_frames[0]->pts;
|
||||
mpctx->last_vo_pts = mpctx->video_pts;
|
||||
mpctx->last_frame_duration =
|
||||
mpctx->next_frames[0]->pkt_duration / mpctx->video_speed;
|
||||
|
||||
shift_frames(mpctx);
|
||||
|
||||
|
|
|
@ -859,6 +859,11 @@ static void decode(struct dec_video *vd, struct demux_packet *packet,
|
|||
mpi->pts = mp_pts_from_av(ctx->pic->pts, &ctx->codec_timebase);
|
||||
mpi->dts = mp_pts_from_av(ctx->pic->pkt_dts, &ctx->codec_timebase);
|
||||
|
||||
#if LIBAVCODEC_VERSION_MICRO >= 100
|
||||
mpi->pkt_duration =
|
||||
mp_pts_from_av(av_frame_get_pkt_duration(ctx->pic), &ctx->codec_timebase);
|
||||
#endif
|
||||
|
||||
struct mp_image_params params;
|
||||
update_image_params(vd, ctx->pic, ¶ms);
|
||||
mp_image_set_params(mpi, ¶ms);
|
||||
|
|
|
@ -386,6 +386,7 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
|
|||
dst->fields = src->fields;
|
||||
dst->pts = src->pts;
|
||||
dst->dts = src->dts;
|
||||
dst->pkt_duration = src->pkt_duration;
|
||||
dst->params.rotate = src->params.rotate;
|
||||
dst->params.stereo_in = src->params.stereo_in;
|
||||
dst->params.stereo_out = src->params.stereo_out;
|
||||
|
|
|
@ -85,7 +85,7 @@ typedef struct mp_image {
|
|||
/* only inside filter chain */
|
||||
double pts;
|
||||
/* only after decoder */
|
||||
double dts;
|
||||
double dts, pkt_duration;
|
||||
/* for private use */
|
||||
void* priv;
|
||||
|
||||
|
|
Loading…
Reference in New Issue