aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar wm4 <wm4@nowhere>2016-12-21 18:18:24 +0100
committerGravatar wm4 <wm4@nowhere>2016-12-21 18:18:24 +0100
commitb1c0bbe8b8b9d25c2682f29af66ad243e0072897 (patch)
tree73a024a69fdfa3707de4e18962e4e1af02226c6d
parent1ba352581687548ffc2664b94f831a3dd12d05fa (diff)
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.
-rw-r--r--player/core.h3
-rw-r--r--player/video.c6
-rw-r--r--video/decode/vd_lavc.c5
-rw-r--r--video/mp_image.c1
-rw-r--r--video/mp_image.h2
5 files changed, 16 insertions, 1 deletions
diff --git a/player/core.h b/player/core.h
index 9a71ce33de..5d055482a5 100644
--- a/player/core.h
+++ b/player/core.h
@@ -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
diff --git a/player/video.c b/player/video.c
index 03dd5aeabe..4621d19cb4 100644
--- a/player/video.c
+++ b/player/video.c
@@ -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);
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index cd3c611ebd..78d34bbb47 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -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, &params);
mp_image_set_params(mpi, &params);
diff --git a/video/mp_image.c b/video/mp_image.c
index ee1ab4104e..2c4627c33e 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -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;
diff --git a/video/mp_image.h b/video/mp_image.h
index 7c0f7bad7e..6606f19c90 100644
--- a/video/mp_image.h
+++ b/video/mp_image.h
@@ -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;