Quoting Vittorio Giovara (2016-03-21 20:09:41)
> From: Vitaliy E Sugrobov <[email protected]>
> 
> This demuxer is capable of extracting multiple frames from GIF file.
> In conjunction with GIF decoder it implements support for reading
> animated GIFs.
> 
> Signed-off-by: Vitaliy E Sugrobov <[email protected]>
> Signed-off-by: Vittorio Giovara <[email protected]>
> ---
>  Changelog                |   1 +
>  doc/general.texi         |   2 +-
>  libavformat/Makefile     |   1 +
>  libavformat/allformats.c |   2 +-
>  libavformat/gifdec.c     | 322 
> +++++++++++++++++++++++++++++++++++++++++++++++
>  libavformat/version.h    |   2 +-
>  6 files changed, 327 insertions(+), 3 deletions(-)
>  create mode 100644 libavformat/gifdec.c
> 
> diff --git a/Changelog b/Changelog
> index ca9c9b4..71fe9e2 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -52,6 +52,7 @@ version <next>:
>  - G.723.1 muxer and encoder
>  - compressed SWF
>  - G.729 raw demuxer
> +- GIF demuxer
>  
>  
>  version 11:
> diff --git a/doc/general.texi b/doc/general.texi
> index 40d3f4a..0f89278 100644
> --- a/doc/general.texi
> +++ b/doc/general.texi
> @@ -282,7 +282,7 @@ library:
>  @item framecrc testing format   @tab X @tab
>  @item FunCom ISS                @tab   @tab X
>      @tab Audio format used in various games from FunCom like The Longest 
> Journey.
> -@item GIF Animation             @tab X @tab
> +@item GIF Animation             @tab X @tab X
>  @item GXF                       @tab X @tab X
>      @tab General eXchange Format SMPTE 360M, used by Thomson Grass Valley
>           playout servers.
> diff --git a/libavformat/Makefile b/libavformat/Makefile
> index 0095e30..3814e14 100644
> --- a/libavformat/Makefile
> +++ b/libavformat/Makefile
> @@ -134,6 +134,7 @@ OBJS-$(CONFIG_FLV_MUXER)                 += flvenc.o avc.o
>  OBJS-$(CONFIG_FOURXM_DEMUXER)            += 4xm.o
>  OBJS-$(CONFIG_FRAMECRC_MUXER)            += framecrcenc.o framehash.o
>  OBJS-$(CONFIG_FRAMEMD5_MUXER)            += md5enc.o framehash.o
> +OBJS-$(CONFIG_GIF_DEMUXER)               += gifdec.o
>  OBJS-$(CONFIG_GIF_MUXER)                 += gifenc.o
>  OBJS-$(CONFIG_GSM_DEMUXER)               += gsmdec.o
>  OBJS-$(CONFIG_GXF_DEMUXER)               += gxf.o
> diff --git a/libavformat/allformats.c b/libavformat/allformats.c
> index 0f49756..1056d7b 100644
> --- a/libavformat/allformats.c
> +++ b/libavformat/allformats.c
> @@ -106,7 +106,7 @@ void av_register_all(void)
>      REGISTER_MUXDEMUX(G722,             g722);
>      REGISTER_MUXDEMUX(G723_1,           g723_1);
>      REGISTER_DEMUXER (G729,             g729);
> -    REGISTER_MUXER   (GIF,              gif);
> +    REGISTER_MUXDEMUX(GIF,              gif);
>      REGISTER_DEMUXER (GSM,              gsm);
>      REGISTER_MUXDEMUX(GXF,              gxf);
>      REGISTER_MUXDEMUX(H261,             h261);
> diff --git a/libavformat/gifdec.c b/libavformat/gifdec.c
> new file mode 100644
> index 0000000..db210b9
> --- /dev/null
> +++ b/libavformat/gifdec.c
> @@ -0,0 +1,322 @@
> +/*
> + * GIF demuxer
> + * Copyright (c) 2012 Vitaliy E Sugrobov
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +/**
> + * @file
> + * GIF demuxer
> + *
> + * There are two options available to users: default_delay and min_delay.
> + *
> + * These options are for protection from too rapid GIF animations. In 
> practice
> + * the standard approach is to slow down rendering of this kind of GIF. If 
> you
> + * try to play a GIF with a delay between frames of one hundredth of a second
> + * (100fps) using one of the major web browsers, you get significantly slower
> + * playback, around 10 fps. This is because the browser detects that the 
> delay
> + * value is less than some threshold (usually 2 hundredths of a second) and
> + * resets it to the default value (usually 10 hundredths of a second, which
> + * corresponds to 10fps). By manipulating these options, users can achieve
> + * the same effect during conversion to some video format, or to not protect
> + * against rapid animations at all.
> + *
> + * The other case when these options are necessary is for GIF images encoded
> + * according to the GIF87a standard since prior to GIF89a there was no delay
> + * information included in GIF files.
> + */

A better place for this is probably doc/demuxers.texi

> +static int gif_read_packet(AVFormatContext *s, AVPacket *pkt)
> +{
> +    GIFDemuxContext *gdc = s->priv_data;
> +    AVIOContext *pb = s->pb;
> +    int packed_fields, block_label, ct_size;
> +    int keyframe, frame_parsed = 0;
> +    int ret;
> +    int64_t frame_start = avio_tell(pb), frame_end;
> +    unsigned char buf[6];
> +
> +    if ((ret = avio_read(pb, buf, 6)) < 0)
> +        return ret;
> +
> +    keyframe = memcmp(buf, GIF_SIG_87A, 6) == 0 ||
> +               memcmp(buf, GIF_SIG_89A, 6) == 0;
> +
> +    if (keyframe) {
> +        /* skip 2 bytes of width and 2 of height */
> +        if ((ret = avio_skip(pb, 4)) < 0)
> +            return ret;
> +
> +        packed_fields = avio_r8(pb);
> +
> +        /* skip 1 byte of Background Color Index and 1 byte of Pixel Aspect 
> Ratio */
> +        if ((ret = avio_skip(pb, 2)) < 0)
> +            return ret;
> +
> +        /* glogal color table presence */
                 ^
tyop

> +        if (packed_fields & 0x80) {
> +            ct_size = 3 * (1 << ((packed_fields & 0x07) + 1));
> +
> +            if ((ret = avio_skip(pb, ct_size)) < 0)
> +                return ret;
> +        }
> +
> +        gdc->total_duration = 0;
> +    } else {
> +        avio_seek(pb, -ret, SEEK_CUR);
> +        ret = AVERROR_EOF;
> +    }
> +
> +    while (GIF_TRAILER != (block_label = avio_r8(pb)) && !pb->eof_reached) {

This condition is concentrated evil. Just add another case with goto end
to the switch.


-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to