[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