[Ffmpeg-cvslog] r6874 - in trunk/libavcodec: Makefile allcodecs.c avcodec.h bytestream.h gif.c

bcoudurier subversion
Fri Nov 3 00:13:35 CET 2006


Author: bcoudurier
Date: Fri Nov  3 00:13:34 2006
New Revision: 6874

Added:
   trunk/libavcodec/gif.c
      - copied, changed from r6872, /trunk/libavformat/gif.c
Modified:
   trunk/libavcodec/Makefile
   trunk/libavcodec/allcodecs.c
   trunk/libavcodec/avcodec.h
   trunk/libavcodec/bytestream.h

Log:
change gif muxer to simple gif encoder

Modified: trunk/libavcodec/Makefile
==============================================================================
--- trunk/libavcodec/Makefile	(original)
+++ trunk/libavcodec/Makefile	Fri Nov  3 00:13:34 2006
@@ -82,6 +82,7 @@
 OBJS-$(CONFIG_FOURXM_DECODER)          += 4xm.o
 OBJS-$(CONFIG_FRAPS_DECODER)           += fraps.o
 OBJS-$(CONFIG_GIF_DECODER)             += gifdec.o lzw.o
+OBJS-$(CONFIG_GIF_ENCODER)             += gif.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	Fri Nov  3 00:13:34 2006
@@ -68,6 +68,9 @@
 #ifdef CONFIG_FLAC_ENCODER
     register_avcodec(&flac_encoder);
 #endif
+#ifdef CONFIG_GIF_ENCODER
+    register_avcodec(&gif_encoder);
+#endif
 #ifdef CONFIG_XVID
 #ifdef CONFIG_XVID_ENCODER
     register_avcodec(&xvid_encoder);

Modified: trunk/libavcodec/avcodec.h
==============================================================================
--- trunk/libavcodec/avcodec.h	(original)
+++ trunk/libavcodec/avcodec.h	Fri Nov  3 00:13:34 2006
@@ -37,8 +37,8 @@
 #define AV_STRINGIFY(s)         AV_TOSTRING(s)
 #define AV_TOSTRING(s) #s
 
-#define LIBAVCODEC_VERSION_INT  ((51<<16)+(23<<8)+0)
-#define LIBAVCODEC_VERSION      51.23.0
+#define LIBAVCODEC_VERSION_INT  ((51<<16)+(24<<8)+0)
+#define LIBAVCODEC_VERSION      51.24.0
 #define LIBAVCODEC_BUILD        LIBAVCODEC_VERSION_INT
 
 #define LIBAVCODEC_IDENT        "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
@@ -2138,6 +2138,7 @@
 extern AVCodec oggvorbis_encoder;
 extern AVCodec faac_encoder;
 extern AVCodec flac_encoder;
+extern AVCodec gif_encoder;
 extern AVCodec xvid_encoder;
 extern AVCodec mpeg1video_encoder;
 extern AVCodec mpeg2video_encoder;

Modified: trunk/libavcodec/bytestream.h
==============================================================================
--- trunk/libavcodec/bytestream.h	(original)
+++ trunk/libavcodec/bytestream.h	Fri Nov  3 00:13:34 2006
@@ -47,4 +47,29 @@
     return size;
 }
 
+static always_inline void bytestream_put_le32(uint8_t **b, const unsigned int value)
+{
+    *(*b)++ = value;
+    *(*b)++ = value >> 8;
+    *(*b)++ = value >> 16;
+    *(*b)++ = value >> 24;
+}
+
+static always_inline void bytestream_put_le16(uint8_t **b, const unsigned int value)
+{
+    *(*b)++ = value;
+    *(*b)++ = value >> 8;
+}
+
+static always_inline void bytestream_put_byte(uint8_t **b, const unsigned int value)
+{
+    *(*b)++ = value;
+}
+
+static always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
+{
+    memcpy(*b, src, size);
+    (*b) += size;
+}
+
 #endif /* FFMPEG_BYTESTREAM_H */

Copied: trunk/libavcodec/gif.c (from r6872, /trunk/libavformat/gif.c)
==============================================================================
--- /trunk/libavformat/gif.c	(original)
+++ trunk/libavcodec/gif.c	Fri Nov  3 00:13:34 2006
@@ -1,6 +1,8 @@
 /*
- * Animated GIF muxer
+ * GIF encoder.
  * Copyright (c) 2000 Fabrice Bellard.
+ * Copyright (c) 2002 Francois Revol.
+ * Copyright (c) 2006 Baptiste Coudurier.
  *
  * This file is part of FFmpeg.
  *
@@ -39,7 +41,8 @@
  * some sites mentions an RLE type compression also.
  */
 
-#include "avformat.h"
+#include "avcodec.h"
+#include "bytestream.h"
 #include "bitstream.h"
 
 /* bitstream minipacket size */
@@ -168,33 +171,33 @@
 /* !RevPutBitContext */
 
 /* GIF header */
-static int gif_image_write_header(ByteIOContext *pb,
+static int gif_image_write_header(uint8_t **bytestream,
                                   int width, int height, int loop_count,
                                   uint32_t *palette)
 {
     int i;
     unsigned int v;
 
-    put_tag(pb, "GIF");
-    put_tag(pb, "89a");
-    put_le16(pb, width);
-    put_le16(pb, height);
-
-    put_byte(pb, 0xf7); /* flags: global clut, 256 entries */
-    put_byte(pb, 0x1f); /* background color index */
-    put_byte(pb, 0); /* aspect ratio */
+    bytestream_put_buffer(bytestream, "GIF", 3);
+    bytestream_put_buffer(bytestream, "89a", 3);
+    bytestream_put_le16(bytestream, width);
+    bytestream_put_le16(bytestream, height);
+
+    bytestream_put_byte(bytestream, 0xf7); /* flags: global clut, 256 entries */
+    bytestream_put_byte(bytestream, 0x1f); /* background color index */
+    bytestream_put_byte(bytestream, 0); /* aspect ratio */
 
     /* the global palette */
     if (!palette) {
-        put_buffer(pb, (const unsigned char *)gif_clut, 216*3);
+        bytestream_put_buffer(bytestream, (const unsigned char *)gif_clut, 216*3);
         for(i=0;i<((256-216)*3);i++)
-            put_byte(pb, 0);
+            bytestream_put_byte(bytestream, 0);
     } else {
         for(i=0;i<256;i++) {
             v = palette[i];
-            put_byte(pb, (v >> 16) & 0xff);
-            put_byte(pb, (v >> 8) & 0xff);
-            put_byte(pb, (v) & 0xff);
+            bytestream_put_byte(bytestream, (v >> 16) & 0xff);
+            bytestream_put_byte(bytestream, (v >> 8) & 0xff);
+            bytestream_put_byte(bytestream, (v) & 0xff);
         }
     }
 
@@ -220,14 +223,14 @@
     /* application extension header */
 #ifdef GIF_ADD_APP_HEADER
     if (loop_count >= 0 && loop_count <= 65535) {
-    put_byte(pb, 0x21);
-    put_byte(pb, 0xff);
-    put_byte(pb, 0x0b);
-        put_tag(pb, "NETSCAPE2.0");  // bytes 4 to 14
-        put_byte(pb, 0x03); // byte 15
-        put_byte(pb, 0x01); // byte 16
-        put_le16(pb, (uint16_t)loop_count);
-        put_byte(pb, 0x00); // byte 19
+        bytestream_put_byte(bytestream, 0x21);
+        bytestream_put_byte(bytestream, 0xff);
+        bytestream_put_byte(bytestream, 0x0b);
+        bytestream_put_buffer(bytestream, "NETSCAPE2.0", 11);  // bytes 4 to 14
+        bytestream_put_byte(bytestream, 0x03); // byte 15
+        bytestream_put_byte(bytestream, 0x01); // byte 16
+        bytestream_put_le16(bytestream, (uint16_t)loop_count);
+        bytestream_put_byte(bytestream, 0x00); // byte 19
     }
 #endif
     return 0;
@@ -240,7 +243,7 @@
 }
 
 
-static int gif_image_write_image(ByteIOContext *pb,
+static int gif_image_write_image(uint8_t **bytestream,
                                  int x1, int y1, int width, int height,
                                  const uint8_t *buf, int linesize, int pix_fmt)
 {
@@ -250,15 +253,15 @@
     const uint8_t *ptr;
     /* image block */
 
-    put_byte(pb, 0x2c);
-    put_le16(pb, x1);
-    put_le16(pb, y1);
-    put_le16(pb, width);
-    put_le16(pb, height);
-    put_byte(pb, 0x00); /* flags */
+    bytestream_put_byte(bytestream, 0x2c);
+    bytestream_put_le16(bytestream, x1);
+    bytestream_put_le16(bytestream, y1);
+    bytestream_put_le16(bytestream, width);
+    bytestream_put_le16(bytestream, height);
+    bytestream_put_byte(bytestream, 0x00); /* flags */
     /* no local clut */
 
-    put_byte(pb, 0x08);
+    bytestream_put_byte(bytestream, 0x08);
 
     left= width * height;
 
@@ -294,139 +297,54 @@
             gif_flush_put_bits_rev(&p);
         }
         if(pbBufPtr(&p) - p.buf > 0) {
-            put_byte(pb, pbBufPtr(&p) - p.buf); /* byte count of the packet */
-            put_buffer(pb, p.buf, pbBufPtr(&p) - p.buf); /* the actual buffer */
+            bytestream_put_byte(bytestream, pbBufPtr(&p) - p.buf); /* byte count of the packet */
+            bytestream_put_buffer(bytestream, p.buf, pbBufPtr(&p) - p.buf); /* the actual buffer */
             p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */
         }
         left-=GIF_CHUNKS;
     }
-    put_byte(pb, 0x00); /* end of image block */
-
+    bytestream_put_byte(bytestream, 0x00); /* end of image block */
+    bytestream_put_byte(bytestream, 0x3b);
     return 0;
 }
 
 typedef struct {
     int64_t time, file_time;
     uint8_t buffer[100]; /* data chunks */
+    AVFrame picture;
 } GIFContext;
 
-static int gif_write_header(AVFormatContext *s)
+static int gif_encode_init(AVCodecContext *avctx)
 {
-    GIFContext *gif = s->priv_data;
-    ByteIOContext *pb = &s->pb;
-    AVCodecContext *enc, *video_enc;
-    int i, width, height, loop_count /*, rate*/;
-
-/* XXX: do we reject audio streams or just ignore them ?
-    if(s->nb_streams > 1)
-        return -1;
-*/
-    gif->time = 0;
-    gif->file_time = 0;
-
-    video_enc = NULL;
-    for(i=0;i<s->nb_streams;i++) {
-        enc = s->streams[i]->codec;
-        if (enc->codec_type != CODEC_TYPE_AUDIO)
-            video_enc = enc;
-    }
-
-    if (!video_enc) {
-        av_free(gif);
-        return -1;
-    } else {
-        width = video_enc->width;
-        height = video_enc->height;
-        loop_count = s->loop_output;
-//        rate = video_enc->time_base.den;
-    }
-
-    if (video_enc->pix_fmt != PIX_FMT_RGB24) {
-        av_log(s, AV_LOG_ERROR, "ERROR: gif only handles the rgb24 pixel format. Use -pix_fmt rgb24.\n");
-        return AVERROR_IO;
-    }
+    GIFContext *s = avctx->priv_data;
 
-    gif_image_write_header(pb, width, height, loop_count, NULL);
-
-    put_flush_packet(&s->pb);
+    avctx->coded_frame = &s->picture;
     return 0;
 }
 
-static int gif_write_video(AVFormatContext *s,
-                           AVCodecContext *enc, const uint8_t *buf, int size)
+/* better than nothing gif encoder */
+static int gif_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data)
 {
-    ByteIOContext *pb = &s->pb;
-    GIFContext *gif = s->priv_data;
-    int jiffies;
-    int64_t delay;
-
-    /* graphic control extension block */
-    put_byte(pb, 0x21);
-    put_byte(pb, 0xf9);
-    put_byte(pb, 0x04); /* block size */
-    put_byte(pb, 0x04); /* flags */
-
-    /* 1 jiffy is 1/70 s */
-    /* the delay_time field indicates the number of jiffies - 1 */
-    delay = gif->file_time - gif->time;
-
-    /* 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;
-
-    put_le16(pb, jiffies);
-
-    put_byte(pb, 0x1f); /* transparent color index */
-    put_byte(pb, 0x00);
-
-    gif_image_write_image(pb, 0, 0, enc->width, enc->height,
-                          buf, enc->width * 3, PIX_FMT_RGB24);
-
-    put_flush_packet(&s->pb);
-    return 0;
+    GIFContext *s = avctx->priv_data;
+    AVFrame *pict = data;
+    AVFrame *const p = (AVFrame *)&s->picture;
+    uint8_t *outbuf_ptr = outbuf;
+
+    *p = *pict;
+    p->pict_type = FF_I_TYPE;
+    p->key_frame = 1;
+    gif_image_write_header(&outbuf_ptr, avctx->width, avctx->height, -1, (uint32_t *)pict->data[1]);
+    gif_image_write_image(&outbuf_ptr, 0, 0, avctx->width, avctx->height, pict->data[0], pict->linesize[0], PIX_FMT_PAL8);
+    return outbuf_ptr - outbuf;
 }
 
-static int gif_write_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
-    if (codec->codec_type == CODEC_TYPE_AUDIO)
-        return 0; /* just ignore audio */
-    else
-        return gif_write_video(s, codec, pkt->data, pkt->size);
-}
-
-static int gif_write_trailer(AVFormatContext *s)
-{
-    ByteIOContext *pb = &s->pb;
-
-    put_byte(pb, 0x3b);
-    put_flush_packet(&s->pb);
-    return 0;
-}
-
-/* better than nothing gif image writer */
-int gif_write(ByteIOContext *pb, AVImageInfo *info)
-{
-    gif_image_write_header(pb, info->width, info->height, AVFMT_NOOUTPUTLOOP,
-                           (uint32_t *)info->pict.data[1]);
-    gif_image_write_image(pb, 0, 0, info->width, info->height,
-                          info->pict.data[0], info->pict.linesize[0],
-                          PIX_FMT_PAL8);
-    put_byte(pb, 0x3b);
-    put_flush_packet(pb);
-    return 0;
-}
-
-AVOutputFormat gif_muxer = {
-    "gif",
-    "GIF Animation",
-    "image/gif",
+AVCodec gif_encoder = {
     "gif",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_GIF,
     sizeof(GIFContext),
-    CODEC_ID_NONE,
-    CODEC_ID_RAWVIDEO,
-    gif_write_header,
-    gif_write_packet,
-    gif_write_trailer,
+    gif_encode_init,
+    gif_encode_frame,
+    NULL, //encode_end,
+    .pix_fmts= (enum PixelFormat[]){PIX_FMT_PAL8, -1},
 };




More information about the ffmpeg-cvslog mailing list