|
@@ -40,6 +40,8 @@
|
|
|
*/
|
|
|
|
|
|
#include "avformat.h"
|
|
|
+#include "libavutil/log.h"
|
|
|
+#include "libavutil/opt.h"
|
|
|
|
|
|
/* The GIF format uses reversed order for bitstreams... */
|
|
|
/* at least they don't use PDP_ENDIAN :) */
|
|
@@ -245,8 +247,10 @@ static int gif_image_write_image(AVIOContext *pb,
|
|
|
}
|
|
|
|
|
|
typedef struct {
|
|
|
+ AVClass *class; /** Class for private options. */
|
|
|
int64_t time, file_time;
|
|
|
uint8_t buffer[100]; /* data chunks */
|
|
|
+ int loop;
|
|
|
} GIFContext;
|
|
|
|
|
|
static int gif_write_header(AVFormatContext *s)
|
|
@@ -254,7 +258,7 @@ static int gif_write_header(AVFormatContext *s)
|
|
|
GIFContext *gif = s->priv_data;
|
|
|
AVIOContext *pb = s->pb;
|
|
|
AVCodecContext *enc, *video_enc;
|
|
|
- int i, width, height, loop_count /*, rate*/;
|
|
|
+ int i, width, height /*, rate*/;
|
|
|
|
|
|
/* XXX: do we reject audio streams or just ignore them ?
|
|
|
if(s->nb_streams > 1)
|
|
@@ -276,7 +280,6 @@ static int gif_write_header(AVFormatContext *s)
|
|
|
} else {
|
|
|
width = video_enc->width;
|
|
|
height = video_enc->height;
|
|
|
- loop_count = s->loop_output;
|
|
|
// rate = video_enc->time_base.den;
|
|
|
}
|
|
|
|
|
@@ -285,7 +288,12 @@ static int gif_write_header(AVFormatContext *s)
|
|
|
return AVERROR(EIO);
|
|
|
}
|
|
|
|
|
|
- gif_image_write_header(pb, width, height, loop_count, NULL);
|
|
|
+#if FF_API_LOOP_OUTPUT
|
|
|
+ if (s->loop_output)
|
|
|
+ gif->loop = s->loop_output;
|
|
|
+#endif
|
|
|
+
|
|
|
+ gif_image_write_header(pb, width, height, gif->loop, NULL);
|
|
|
|
|
|
avio_flush(s->pb);
|
|
|
return 0;
|
|
@@ -340,6 +348,20 @@ static int gif_write_trailer(AVFormatContext *s)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+#define OFFSET(x) offsetof(GIFContext, x)
|
|
|
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
|
|
|
+static const AVOption options[] = {
|
|
|
+ { "loop", "Number of times to loop the output.", OFFSET(loop), FF_OPT_TYPE_INT, {0}, 0, 65535, ENC },
|
|
|
+ { NULL },
|
|
|
+};
|
|
|
+
|
|
|
+static const AVClass gif_muxer_class = {
|
|
|
+ .class_name = "GIF muxer",
|
|
|
+ .item_name = av_default_item_name,
|
|
|
+ .version = LIBAVUTIL_VERSION_INT,
|
|
|
+ .option = options,
|
|
|
+};
|
|
|
+
|
|
|
AVOutputFormat ff_gif_muxer = {
|
|
|
"gif",
|
|
|
NULL_IF_CONFIG_SMALL("GIF Animation"),
|
|
@@ -351,4 +373,5 @@ AVOutputFormat ff_gif_muxer = {
|
|
|
gif_write_header,
|
|
|
gif_write_packet,
|
|
|
gif_write_trailer,
|
|
|
+ .priv_class = &gif_muxer_class,
|
|
|
};
|