[Ffmpeg-cvslog] r6760 - in trunk: Changelog MAINTAINERS libavcodec/Makefile libavcodec/allcodecs.c libavcodec/avcodec.h libavcodec/bytestream.h libavcodec/gifdec.c

bcoudurier subversion
Sun Oct 22 17:05:04 CEST 2006


Author: bcoudurier
Date: Sun Oct 22 17:05:03 2006
New Revision: 6760

Added:
   trunk/libavcodec/bytestream.h
   trunk/libavcodec/gifdec.c
      - copied, changed from r6758, /trunk/libavformat/gifdec.c
Modified:
   trunk/Changelog
   trunk/MAINTAINERS
   trunk/libavcodec/Makefile
   trunk/libavcodec/allcodecs.c
   trunk/libavcodec/avcodec.h

Log:
change gif demuxer to gif decoder

Modified: trunk/Changelog
==============================================================================
--- trunk/Changelog	(original)
+++ trunk/Changelog	Sun Oct 22 17:05:03 2006
@@ -64,6 +64,7 @@
 - Tiertex .seq demuxer/video decoder
 - MTV demuxer
 - TIFF picture decoder
+- GIF picture decoder
 
 version 0.4.9-pre1:
 

Modified: trunk/MAINTAINERS
==============================================================================
--- trunk/MAINTAINERS	(original)
+++ trunk/MAINTAINERS	Sun Oct 22 17:05:03 2006
@@ -121,6 +121,7 @@
   flashsv.c                             Benjamin Larsson
   flicvideo.c                           Mike Melanson
   g726.c                                Roman Shaposhnik
+  gifdec.c                              Baptiste Coudurier
   h264*                                 Loren Merritt, Michael Niedermayer
   h261*                                 Michael Niedermayer
   h263*                                 Michael Niedermayer

Modified: trunk/libavcodec/Makefile
==============================================================================
--- trunk/libavcodec/Makefile	(original)
+++ trunk/libavcodec/Makefile	Sun Oct 22 17:05:03 2006
@@ -84,6 +84,7 @@
 OBJS-$(CONFIG_FLIC_DECODER)            += flicvideo.o
 OBJS-$(CONFIG_FOURXM_DECODER)          += 4xm.o
 OBJS-$(CONFIG_FRAPS_DECODER)           += fraps.o
+OBJS-$(CONFIG_GIF_DECODER)             += gifdec.o
 OBJS-$(CONFIG_H261_DECODER)            += h261.o
 OBJS-$(CONFIG_H261_ENCODER)            += h261.o
 OBJS-$(CONFIG_H264_DECODER)            += h264.o

Modified: trunk/libavcodec/allcodecs.c
==============================================================================
--- trunk/libavcodec/allcodecs.c	(original)
+++ trunk/libavcodec/allcodecs.c	Sun Oct 22 17:05:03 2006
@@ -193,6 +193,9 @@
 #endif //CONFIG_RAWVIDEO_ENCODER
 
     /* decoders */
+#ifdef CONFIG_GIF_DECODER
+    register_avcodec(&gif_decoder);
+#endif
 #ifdef CONFIG_H263_DECODER
     register_avcodec(&h263_decoder);
 #endif //CONFIG_H263_DECODER

Modified: trunk/libavcodec/avcodec.h
==============================================================================
--- trunk/libavcodec/avcodec.h	(original)
+++ trunk/libavcodec/avcodec.h	Sun Oct 22 17:05:03 2006
@@ -37,8 +37,8 @@
 #define AV_STRINGIFY(s)         AV_TOSTRING(s)
 #define AV_TOSTRING(s) #s
 
-#define LIBAVCODEC_VERSION_INT  ((51<<16)+(20<<8)+0)
-#define LIBAVCODEC_VERSION      51.20.0
+#define LIBAVCODEC_VERSION_INT  ((51<<16)+(21<<8)+0)
+#define LIBAVCODEC_VERSION      51.21.0
 #define LIBAVCODEC_BUILD        LIBAVCODEC_VERSION_INT
 
 #define LIBAVCODEC_IDENT        "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
@@ -148,6 +148,7 @@
     CODEC_ID_DSICINVIDEO,
     CODEC_ID_TIERTEXSEQVIDEO,
     CODEC_ID_TIFF,
+    CODEC_ID_GIF,
 
     /* various pcm "codecs" */
     CODEC_ID_PCM_S16LE= 0x10000,
@@ -2177,6 +2178,7 @@
 extern AVCodec svq1_encoder;
 extern AVCodec x264_encoder;
 
+extern AVCodec gif_decoder;
 extern AVCodec h263_decoder;
 extern AVCodec h261_decoder;
 extern AVCodec mpeg4_decoder;

Added: trunk/libavcodec/bytestream.h
==============================================================================
--- (empty file)
+++ trunk/libavcodec/bytestream.h	Sun Oct 22 17:05:03 2006
@@ -0,0 +1,50 @@
+/*
+ * Bytestream functions
+ * copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier at free.fr>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef FFMPEG_BYTESTREAM_H
+#define FFMPEG_BYTESTREAM_H
+
+static always_inline unsigned int bytestream_get_le32(uint8_t **b)
+{
+    (*b) += 4;
+    return LE_32(*b - 4);
+}
+
+static always_inline unsigned int bytestream_get_le16(uint8_t **b)
+{
+    (*b) += 2;
+    return LE_16(*b - 2);
+}
+
+static always_inline unsigned int bytestream_get_byte(uint8_t **b)
+{
+    (*b)++;
+    return (*b)[-1];
+}
+
+static always_inline unsigned int bytestream_get_buffer(uint8_t **b, uint8_t *dst, unsigned int size)
+{
+    memcpy(dst, *b, size);
+    (*b) += size;
+    return size;
+}
+
+#endif /* FFMPEG_BYTESTREAM_H */

Copied: trunk/libavcodec/gifdec.c (from r6758, /trunk/libavformat/gifdec.c)
==============================================================================
--- /trunk/libavformat/gifdec.c	(original)
+++ trunk/libavcodec/gifdec.c	Sun Oct 22 17:05:03 2006
@@ -1,6 +1,7 @@
 /*
  * GIF decoder
  * Copyright (c) 2003 Fabrice Bellard.
+ * Copyright (c) 2006 Baptiste Coudurier.
  *
  * This file is part of FFmpeg.
  *
@@ -18,12 +19,12 @@
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
-#include "avformat.h"
-
-int gif_write(ByteIOContext *pb, AVImageInfo *info);
 
 //#define DEBUG
 
+#include "avcodec.h"
+#include "bytestream.h"
+
 #define MAXBITS                 12
 #define         SIZTABLE        (1<<MAXBITS)
 
@@ -41,7 +42,7 @@
     int color_resolution;
     uint8_t *image_buf;
     int image_linesize;
-    uint32_t *image_palette;
+    uint32_t image_palette[256];
     int pix_fmt;
 
     /* after the frame is displayed, the disposal method is used */
@@ -50,7 +51,7 @@
     int gce_delay;
 
     /* LZW compatible decoder */
-    ByteIOContext *f;
+    uint8_t *bytestream;
     int eob_reached;
     uint8_t *pbuf, *ebuf;
     int bbits;
@@ -76,7 +77,6 @@
     uint8_t buf[256];
 } GifState;
 
-
 static const uint8_t gif87a_sig[6] = "GIF87a";
 static const uint8_t gif89a_sig[6] = "GIF89a";
 
@@ -88,73 +88,6 @@
     0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
 };
 
-/* Probe gif video format or gif image format. The current heuristic
-   supposes the gif87a is always a single image. For gif89a, we
-   consider it as a video only if a GCE extension is present in the
-   first kilobyte. */
-static int gif_video_probe(AVProbeData * pd)
-{
-    const uint8_t *p, *p_end;
-    int bits_per_pixel, has_global_palette, ext_code, ext_len;
-    int gce_flags, gce_disposal;
-
-    if (pd->buf_size < 24 ||
-        memcmp(pd->buf, gif89a_sig, 6) != 0)
-        return 0;
-    p_end = pd->buf + pd->buf_size;
-    p = pd->buf + 6;
-    bits_per_pixel = (p[4] & 0x07) + 1;
-    has_global_palette = (p[4] & 0x80);
-    p += 7;
-    if (has_global_palette)
-        p += (1 << bits_per_pixel) * 3;
-    for(;;) {
-        if (p >= p_end)
-            return 0;
-        if (*p != '!')
-            break;
-        p++;
-        if (p >= p_end)
-            return 0;
-        ext_code = *p++;
-        if (p >= p_end)
-            return 0;
-        ext_len = *p++;
-        if (ext_code == 0xf9) {
-            if (p >= p_end)
-                return 0;
-            /* if GCE extension found with gce_disposal != 0: it is
-               likely to be an animation */
-            gce_flags = *p++;
-            gce_disposal = (gce_flags >> 2) & 0x7;
-            if (gce_disposal != 0)
-                return AVPROBE_SCORE_MAX;
-            else
-                return 0;
-        }
-        for(;;) {
-            if (ext_len == 0)
-                break;
-            p += ext_len;
-            if (p >= p_end)
-                return 0;
-            ext_len = *p++;
-        }
-    }
-    return 0;
-}
-
-static int gif_image_probe(AVProbeData * pd)
-{
-    if (pd->buf_size >= 24 &&
-        (memcmp(pd->buf, gif87a_sig, 6) == 0 ||
-         memcmp(pd->buf, gif89a_sig, 6) == 0))
-        return AVPROBE_SCORE_MAX - 1;
-    else
-        return 0;
-}
-
-
 static void GLZWDecodeInit(GifState * s, int csize)
 {
     /* read buffer */
@@ -186,11 +119,11 @@
         ptr = s->pbuf;
         if (ptr >= s->ebuf) {
             if (!s->eob_reached) {
-                sizbuf = get_byte(s->f);
+                sizbuf = bytestream_get_byte(&s->bytestream);
                 s->ebuf = s->buf + sizbuf;
                 s->pbuf = s->buf;
                 if (sizbuf > 0) {
-                    get_buffer(s->f, s->buf, sizbuf);
+                    bytestream_get_buffer(&s->bytestream, s->buf, sizbuf);
                 } else {
                     s->eob_reached = 1;
                 }
@@ -290,16 +223,15 @@
 
 static int gif_read_image(GifState *s)
 {
-    ByteIOContext *f = s->f;
     int left, top, width, height, bits_per_pixel, code_size, flags;
     int is_interleaved, has_local_palette, y, x, pass, y1, linesize, n, i;
     uint8_t *ptr, *line, *d, *spal, *palette, *sptr, *ptr1;
 
-    left = get_le16(f);
-    top = get_le16(f);
-    width = get_le16(f);
-    height = get_le16(f);
-    flags = get_byte(f);
+    left = bytestream_get_le16(&s->bytestream);
+    top = bytestream_get_le16(&s->bytestream);
+    width = bytestream_get_le16(&s->bytestream);
+    height = bytestream_get_le16(&s->bytestream);
+    flags = bytestream_get_byte(&s->bytestream);
     is_interleaved = flags & 0x40;
     has_local_palette = flags & 0x80;
     bits_per_pixel = (flags & 0x07) + 1;
@@ -308,7 +240,7 @@
 #endif
 
     if (has_local_palette) {
-        get_buffer(f, s->local_palette, 3 * (1 << bits_per_pixel));
+        bytestream_get_buffer(&s->bytestream, s->local_palette, 3 * (1 << bits_per_pixel));
         palette = s->local_palette;
     } else {
         palette = s->global_palette;
@@ -321,11 +253,6 @@
         return -EINVAL;
 
     /* build the palette */
-    if (s->pix_fmt == PIX_FMT_RGB24) {
-        line = av_malloc(width);
-        if (!line)
-            return -ENOMEM;
-    } else {
         n = (1 << bits_per_pixel);
         spal = palette;
         for(i = 0; i < n; i++) {
@@ -339,11 +266,9 @@
         if (s->transparent_color_index >= 0)
             s->image_palette[s->transparent_color_index] = 0;
         line = NULL;
-    }
 
     /* now get the image data */
-    s->f = f;
-    code_size = get_byte(f);
+    code_size = bytestream_get_byte(&s->bytestream);
     GLZWDecodeInit(s, code_size);
 
     /* read all the image */
@@ -353,22 +278,7 @@
     pass = 0;
     y1 = 0;
     for (y = 0; y < height; y++) {
-        if (s->pix_fmt == PIX_FMT_RGB24) {
-            /* transcode to RGB24 */
-            GLZWDecode(s, line, width);
-            d = ptr;
-            sptr = line;
-            for(x = 0; x < width; x++) {
-                spal = palette + sptr[0] * 3;
-                d[0] = spal[0];
-                d[1] = spal[1];
-                d[2] = spal[2];
-                d += 3;
-                sptr++;
-            }
-        } else {
             GLZWDecode(s, ptr, width);
-        }
         if (is_interleaved) {
             switch(pass) {
             default:
@@ -413,12 +323,11 @@
 
 static int gif_read_extension(GifState *s)
 {
-    ByteIOContext *f = s->f;
     int ext_code, ext_len, i, gce_flags, gce_transparent_index;
 
     /* extension */
-    ext_code = get_byte(f);
-    ext_len = get_byte(f);
+    ext_code = bytestream_get_byte(&s->bytestream);
+    ext_len = bytestream_get_byte(&s->bytestream);
 #ifdef DEBUG
     printf("gif: ext_code=0x%x len=%d\n", ext_code, ext_len);
 #endif
@@ -427,9 +336,9 @@
         if (ext_len != 4)
             goto discard_ext;
         s->transparent_color_index = -1;
-        gce_flags = get_byte(f);
-        s->gce_delay = get_le16(f);
-        gce_transparent_index = get_byte(f);
+        gce_flags = bytestream_get_byte(&s->bytestream);
+        s->gce_delay = bytestream_get_le16(&s->bytestream);
+        gce_transparent_index = bytestream_get_byte(&s->bytestream);
         if (gce_flags & 0x01)
             s->transparent_color_index = gce_transparent_index;
         else
@@ -440,7 +349,7 @@
                gce_flags, s->gce_delay,
                s->transparent_color_index, s->gce_disposal);
 #endif
-        ext_len = get_byte(f);
+        ext_len = bytestream_get_byte(&s->bytestream);
         break;
     }
 
@@ -448,8 +357,8 @@
  discard_ext:
     while (ext_len != 0) {
         for (i = 0; i < ext_len; i++)
-            get_byte(f);
-        ext_len = get_byte(f);
+            bytestream_get_byte(&s->bytestream);
+        ext_len = bytestream_get_byte(&s->bytestream);
 #ifdef DEBUG
         printf("gif: ext_len1=%d\n", ext_len);
 #endif
@@ -459,35 +368,32 @@
 
 static int gif_read_header1(GifState *s)
 {
-    ByteIOContext *f = s->f;
     uint8_t sig[6];
     int ret, v, n;
     int has_global_palette;
 
     /* read gif signature */
-    ret = get_buffer(f, sig, 6);
-    if (ret != 6)
-        return -1;
+    bytestream_get_buffer(&s->bytestream, sig, 6);
     if (memcmp(sig, gif87a_sig, 6) != 0 &&
         memcmp(sig, gif89a_sig, 6) != 0)
         return -1;
 
     /* read screen header */
     s->transparent_color_index = -1;
-    s->screen_width = get_le16(f);
-    s->screen_height = get_le16(f);
+    s->screen_width = bytestream_get_le16(&s->bytestream);
+    s->screen_height = bytestream_get_le16(&s->bytestream);
     if(   (unsigned)s->screen_width  > 32767
        || (unsigned)s->screen_height > 32767){
         av_log(NULL, AV_LOG_ERROR, "picture size too large\n");
         return -1;
     }
 
-    v = get_byte(f);
+    v = bytestream_get_byte(&s->bytestream);
     s->color_resolution = ((v & 0x70) >> 4) + 1;
     has_global_palette = (v & 0x80);
     s->bits_per_pixel = (v & 0x07) + 1;
-    s->background_color_index = get_byte(f);
-    get_byte(f);                /* ignored */
+    s->background_color_index = bytestream_get_byte(&s->bytestream);
+    bytestream_get_byte(&s->bytestream);                /* ignored */
 #ifdef DEBUG
     printf("gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n",
            s->screen_width, s->screen_height, s->bits_per_pixel,
@@ -495,39 +401,38 @@
 #endif
     if (has_global_palette) {
         n = 1 << s->bits_per_pixel;
-        get_buffer(f, s->global_palette, n * 3);
+        bytestream_get_buffer(&s->bytestream, s->global_palette, n * 3);
     }
     return 0;
 }
 
 static int gif_parse_next_image(GifState *s)
 {
-    ByteIOContext *f = s->f;
     int ret, code;
 
     for (;;) {
-        code = url_fgetc(f);
+        code = bytestream_get_byte(&s->bytestream);
 #ifdef DEBUG
         printf("gif: code=%02x '%c'\n", code, code);
 #endif
         switch (code) {
         case ',':
             if (gif_read_image(s) < 0)
-                return AVERROR_IO;
+                return -1;
             ret = 0;
             goto the_end;
         case ';':
             /* end of image */
-            ret = AVERROR_IO;
+            ret = -1;
             goto the_end;
         case '!':
             if (gif_read_extension(s) < 0)
-                return AVERROR_IO;
+                return -1;
             break;
         case EOF:
         default:
             /* error or errneous EOF */
-            ret = AVERROR_IO;
+            ret = -1;
             goto the_end;
         }
     }
@@ -535,14 +440,20 @@
     return ret;
 }
 
-static int gif_read_header(AVFormatContext * s1,
-                           AVFormatParameters * ap)
+static int gif_decode_init(AVCodecContext *avctx)
+{
+    GifState *s = avctx->priv_data;
+
+    return 0;
+}
+
+static int gif_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
 {
-    GifState *s = s1->priv_data;
-    ByteIOContext *f = &s1->pb;
-    AVStream *st;
+    GifState *s = avctx->priv_data;
+    AVFrame *picture = data;
+    int ret;
 
-    s->f = f;
+    s->bytestream = buf;
     if (gif_read_header1(s) < 0)
         return -1;
 
@@ -551,94 +462,34 @@
     s->image_buf = av_malloc(s->screen_height * s->image_linesize);
     if (!s->image_buf)
         return -ENOMEM;
-    s->pix_fmt = PIX_FMT_RGB24;
+    s->pix_fmt = PIX_FMT_PAL8;
     /* now we are ready: build format streams */
-    st = av_new_stream(s1, 0);
-    if (!st)
-        return -1;
 
-    st->codec->codec_type = CODEC_TYPE_VIDEO;
-    st->codec->codec_id = CODEC_ID_RAWVIDEO;
-    st->codec->time_base.den = 5;
-    st->codec->time_base.num = 1;
     /* XXX: check if screen size is always valid */
-    st->codec->width = s->screen_width;
-    st->codec->height = s->screen_height;
-    st->codec->pix_fmt = PIX_FMT_RGB24;
-    return 0;
-}
-
-static int gif_read_packet(AVFormatContext * s1,
-                           AVPacket * pkt)
-{
-    GifState *s = s1->priv_data;
-    int ret;
+    avctx->width = s->screen_width;
+    avctx->height = s->screen_height;
+    avctx->pix_fmt = PIX_FMT_PAL8;
 
     ret = gif_parse_next_image(s);
     if (ret < 0)
         return ret;
 
-    /* XXX: avoid copying */
-    if (av_new_packet(pkt, s->screen_width * s->screen_height * 3)) {
-        return AVERROR_IO;
-    }
-    pkt->stream_index = 0;
-    memcpy(pkt->data, s->image_buf, s->screen_width * s->screen_height * 3);
-    return 0;
-}
+    picture->data[0] = s->image_buf;
+    picture->linesize[0] = s->image_linesize;
+    picture->data[1] = s->image_palette;
+    picture->linesize[1] = 4;
 
-static int gif_read_close(AVFormatContext *s1)
-{
-    GifState *s = s1->priv_data;
-    av_free(s->image_buf);
+    *data_size = sizeof(AVPicture);
     return 0;
 }
 
-/* read gif as image */
-static int gif_read(ByteIOContext *f,
-                    int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque)
-{
-    GifState s1, *s = &s1;
-    AVImageInfo info1, *info = &info1;
-    int ret;
-
-    memset(s, 0, sizeof(GifState));
-    s->f = f;
-    if (gif_read_header1(s) < 0)
-        return -1;
-    info->width = s->screen_width;
-    info->height = s->screen_height;
-    info->pix_fmt = PIX_FMT_PAL8;
-    ret = alloc_cb(opaque, info);
-    if (ret)
-        return ret;
-    s->image_buf = info->pict.data[0];
-    s->image_linesize = info->pict.linesize[0];
-    s->image_palette = (uint32_t *)info->pict.data[1];
-
-    if (gif_parse_next_image(s) < 0)
-        return -1;
-    return 0;
-}
-
-AVInputFormat gif_demuxer =
-{
+AVCodec gif_decoder = {
     "gif",
-    "gif format",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_GIF,
     sizeof(GifState),
-    gif_video_probe,
-    gif_read_header,
-    gif_read_packet,
-    gif_read_close,
-};
-
-AVImageFormat gif_image_format = {
-    "gif",
-    "gif",
-    gif_image_probe,
-    gif_read,
-    (1 << PIX_FMT_PAL8),
-#ifdef CONFIG_GIF_MUXER
-    gif_write,
-#endif
+    gif_decode_init,
+    NULL,
+    NULL,
+    gif_decode_frame,
 };




More information about the ffmpeg-cvslog mailing list