From 7e57adb464a9886bdef3012b08e903340465a89b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Thu, 18 Apr 2013 15:09:37 +0200 Subject: [PATCH] lavf/gif: fix timing. pkt->duration can not be used since the values are only based on frame rate. --- libavformat/gif.c | 23 ++++++++++------------- tests/ref/lavf/gif | 4 ++-- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/libavformat/gif.c b/libavformat/gif.c index f26d537b84..6b03d0a6e8 100644 --- a/libavformat/gif.c +++ b/libavformat/gif.c @@ -22,6 +22,7 @@ */ #include "avformat.h" +#include "internal.h" #include "libavutil/avassert.h" #include "libavutil/imgutils.h" #include "libavutil/log.h" @@ -67,6 +68,7 @@ static int gif_image_write_header(AVIOContext *pb, int width, int height, typedef struct { AVClass *class; /** Class for private options. */ int loop; + int64_t prev_pts; } GIFContext; static int gif_write_header(AVFormatContext *s) @@ -89,6 +91,7 @@ static int gif_write_header(AVFormatContext *s) width = video_enc->width; height = video_enc->height; + avpriv_set_pts_info(s->streams[0], 64, 1, 100); if (avpriv_set_systematic_pal2(palette, video_enc->pix_fmt) < 0) { av_assert0(video_enc->pix_fmt == AV_PIX_FMT_PAL8); gif_image_write_header(pb, width, height, gif->loop, NULL); @@ -102,10 +105,9 @@ static int gif_write_header(AVFormatContext *s) static int gif_write_packet(AVFormatContext *s, AVPacket *pkt) { - int size; - AVCodecContext *enc = s->streams[pkt->stream_index]->codec; + GIFContext *gif = s->priv_data; + int size, duration; AVIOContext *pb = s->pb; - int jiffies; uint8_t flags = 0x4, transparent_color_index = 0x1f; const uint32_t *palette; @@ -130,21 +132,15 @@ static int gif_write_packet(AVFormatContext *s, AVPacket *pkt) flags |= 0x1; /* Transparent Color Flag */ } + duration = pkt->pts == AV_NOPTS_VALUE ? 0 : av_clip_uint16(pkt->pts - gif->prev_pts); + gif->prev_pts = pkt->pts; + /* graphic control extension block */ avio_w8(pb, 0x21); avio_w8(pb, 0xf9); avio_w8(pb, 0x04); /* block size */ avio_w8(pb, flags); - - /* 1 jiffy is 1/70 s */ - /* the delay_time field indicates the number of jiffies - 1 */ - /* XXX: should use delay, in order to be more accurate */ - /* instead of using the same rounded value each time */ - /* XXX: don't even remember if I really use it for now */ - jiffies = (70 * enc->time_base.num / enc->time_base.den) - 1; - - avio_wl16(pb, jiffies); - + avio_wl16(pb, duration); avio_w8(pb, transparent_color_index); avio_w8(pb, 0x00); @@ -189,4 +185,5 @@ AVOutputFormat ff_gif_muxer = { .write_packet = gif_write_packet, .write_trailer = gif_write_trailer, .priv_class = &gif_muxer_class, + .flags = AVFMT_VARIABLE_FPS, }; diff --git a/tests/ref/lavf/gif b/tests/ref/lavf/gif index 4acd5ca087..f66d05f888 100644 --- a/tests/ref/lavf/gif +++ b/tests/ref/lavf/gif @@ -1,3 +1,3 @@ -66398be6fafa026fb0fa5f2978fa3446 *./tests/data/lavf/lavf.gif +c886d22859c033b2b0fe2d63ffcf8aef *./tests/data/lavf/lavf.gif 2011766 ./tests/data/lavf/lavf.gif -./tests/data/lavf/lavf.gif CRC=0x0d96deb8 +./tests/data/lavf/lavf.gif CRC=0xdca4429c