[FFmpeg-devel] [PATCH] lavf/gifdec: add loop support.
Paul B Mahol
onemda at gmail.com
Fri Apr 19 01:50:01 CEST 2013
On 4/18/13, Clement Boesch <ubitux at gmail.com> wrote:
> ---
> Still missing FATE update (need to add -ignore_loop to them), but I'm
> waiting for review on the patch to rework the tests.
I would prefer that default is to not loop at all.
> ---
> libavcodec/gif.h | 2 ++
> libavformat/gifdec.c | 24 +++++++++++++++++++++++-
> 2 files changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/gif.h b/libavcodec/gif.h
> index b557534..b4cf665 100644
> --- a/libavcodec/gif.h
> +++ b/libavcodec/gif.h
> @@ -43,5 +43,7 @@ static const uint8_t gif89a_sig[6] = "GIF89a";
> #define GIF_EXTENSION_INTRODUCER 0x21
> #define GIF_IMAGE_SEPARATOR 0x2c
> #define GIF_GCE_EXT_LABEL 0xf9
> +#define GIF_APP_EXT_LABEL 0xff
Nice!
> +#define NETSCAPE_EXT_STR "NETSCAPE2.0"
>
> #endif /* AVCODEC_GIFDEFS_H */
> diff --git a/libavformat/gifdec.c b/libavformat/gifdec.c
> index 1122849..0028734 100644
> --- a/libavformat/gifdec.c
> +++ b/libavformat/gifdec.c
> @@ -44,6 +44,13 @@ typedef struct GIFDemuxContext {
> */
> int min_delay;
> int default_delay;
> +
> + /**
> + * loop options
> + */
> + int total_iter;
> + int iter_count;
> + int ignore_loop;
> } GIFDemuxContext;
>
> /**
> @@ -156,6 +163,17 @@ static int gif_read_ext(AVFormatContext *s)
> /* skip the rest of the Graphic Control Extension block */
> if ((ret = avio_skip(pb, sb_size - 3)) < 0 )
> return ret;
> + } else if (ext_label == GIF_APP_EXT_LABEL) {
> + uint8_t netscape_ext[sizeof(NETSCAPE_EXT_STR)-1 + 2];
> +
> + if ((sb_size = avio_r8(pb)) != strlen(NETSCAPE_EXT_STR))
> + return 0;
> + ret = avio_read(pb, netscape_ext, sizeof(netscape_ext));
> + if (ret < sizeof(netscape_ext))
> + return ret;
> + gdc->total_iter = avio_rl16(pb);
> + if (gdc->total_iter == 0)
> + gdc->total_iter = -1;
> }
>
> if ((ret = gif_skip_subblocks(pb)) < 0)
> @@ -268,9 +286,12 @@ resync:
> }
> }
>
> - if (ret >= 0 && !frame_parsed) {
> + if ((ret >= 0 && !frame_parsed) || ret == AVERROR_EOF) {
> /* This might happen when there is no image block
> * between extension blocks and GIF_TRAILER or EOF */
> + if (!gdc->ignore_loop && (block_label == GIF_TRAILER ||
> url_feof(pb))
> + && (gdc->total_iter < 0 || ++gdc->iter_count <
> gdc->total_iter))
> + return avio_seek(pb, 0, SEEK_SET);
Is it ok too loop on partial file?
> return AVERROR_EOF;
> } else
> return ret;
> @@ -279,6 +300,7 @@ resync:
> static const AVOption options[] = {
> { "min_delay" , "minimum valid delay between frames (in hundredths
> of second)", offsetof(GIFDemuxContext, min_delay) , AV_OPT_TYPE_INT,
> {.i64 = GIF_MIN_DELAY} , 0, 100 * 60, AV_OPT_FLAG_DECODING_PARAM },
> { "default_delay", "default delay between frames (in hundredths of
> second)" , offsetof(GIFDemuxContext, default_delay), AV_OPT_TYPE_INT,
> {.i64 = GIF_DEFAULT_DELAY}, 0, 100 * 60, AV_OPT_FLAG_DECODING_PARAM },
> + { "ignore_loop" , "ignore loop setting (netscape extension)"
> , offsetof(GIFDemuxContext, ignore_loop) , AV_OPT_TYPE_INT, {.i64
> = 0} , 0, 1, AV_OPT_FLAG_DECODING_PARAM },
> { NULL },
> };
>
> --
> 1.8.2.1
rest looks fine
More information about the ffmpeg-devel
mailing list