mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-23 15:53:08 +00:00
Cleanse GIF muxer and encoder.
This commit removes the badly duplicated code between the encoder and the muxer. That may sound surprising, but the encoder is now responsible from the encoding of the picture when muxing to a .gif file. It also does not require anymore a manual user intervention such as a -pix_fmt rgb24 to work properly. To summarize, output gif are now easier to generate, code is saner and simpler, and files are smaller (thanks to the lzw encoding which was unused so far with the default .gif output). We can certainly make things even better, but this is the first step. FATE is updated because of the output being produced by the encoder and not the muxer (no lzw in the muxer), and in the seek test only the size mismatches. Fixes Ticket #2262
This commit is contained in:
parent
1efcab02b6
commit
635389ccfa
@ -51,61 +51,54 @@ typedef struct {
|
||||
uint8_t *buf;
|
||||
} GIFContext;
|
||||
|
||||
/* GIF header */
|
||||
static int gif_image_write_header(AVCodecContext *avctx,
|
||||
uint8_t **bytestream, uint32_t *palette)
|
||||
{
|
||||
int i;
|
||||
unsigned int v, smallest_alpha = 0xFF, alpha_component = 0;
|
||||
|
||||
bytestream_put_buffer(bytestream, "GIF", 3);
|
||||
bytestream_put_buffer(bytestream, "89a", 3);
|
||||
bytestream_put_le16(bytestream, avctx->width);
|
||||
bytestream_put_le16(bytestream, avctx->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 */
|
||||
for(i=0;i<256;i++) {
|
||||
v = palette[i];
|
||||
bytestream_put_be24(bytestream, v);
|
||||
if (v >> 24 < smallest_alpha) {
|
||||
smallest_alpha = v >> 24;
|
||||
alpha_component = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (smallest_alpha < 128) {
|
||||
bytestream_put_byte(bytestream, 0x21); /* Extension Introducer */
|
||||
bytestream_put_byte(bytestream, 0xf9); /* Graphic Control Label */
|
||||
bytestream_put_byte(bytestream, 0x04); /* block length */
|
||||
bytestream_put_byte(bytestream, 0x01); /* Transparent Color Flag */
|
||||
bytestream_put_le16(bytestream, 0x00); /* no delay */
|
||||
bytestream_put_byte(bytestream, alpha_component);
|
||||
bytestream_put_byte(bytestream, 0x00);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gif_image_write_image(AVCodecContext *avctx,
|
||||
uint8_t **bytestream, uint8_t *end,
|
||||
const uint32_t *palette,
|
||||
const uint8_t *buf, int linesize)
|
||||
{
|
||||
GIFContext *s = avctx->priv_data;
|
||||
int len = 0, height;
|
||||
const uint8_t *ptr;
|
||||
/* image block */
|
||||
|
||||
/* Mark one colour as transparent if the input palette contains at least
|
||||
* one colour that is more than 50% transparent. */
|
||||
if (palette) {
|
||||
unsigned i, smallest_alpha = 0xFF, alpha_component = 0;
|
||||
for (i = 0; i < AVPALETTE_COUNT; i++) {
|
||||
const uint32_t v = palette[i];
|
||||
if (v >> 24 < smallest_alpha) {
|
||||
smallest_alpha = v >> 24;
|
||||
alpha_component = i;
|
||||
}
|
||||
}
|
||||
if (smallest_alpha < 128) {
|
||||
bytestream_put_byte(bytestream, 0x21); /* Extension Introducer */
|
||||
bytestream_put_byte(bytestream, 0xf9); /* Graphic Control Label */
|
||||
bytestream_put_byte(bytestream, 0x04); /* block length */
|
||||
bytestream_put_byte(bytestream, 0x01); /* Transparent Color Flag */
|
||||
bytestream_put_le16(bytestream, 0x00); /* no delay */
|
||||
bytestream_put_byte(bytestream, alpha_component);
|
||||
bytestream_put_byte(bytestream, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
/* image block */
|
||||
bytestream_put_byte(bytestream, 0x2c);
|
||||
bytestream_put_le16(bytestream, 0);
|
||||
bytestream_put_le16(bytestream, 0);
|
||||
bytestream_put_le16(bytestream, avctx->width);
|
||||
bytestream_put_le16(bytestream, avctx->height);
|
||||
|
||||
if (!palette) {
|
||||
bytestream_put_byte(bytestream, 0x00); /* flags */
|
||||
/* no local clut */
|
||||
} else {
|
||||
unsigned i;
|
||||
bytestream_put_byte(bytestream, 1<<7 | 0x7); /* flags */
|
||||
for (i = 0; i < AVPALETTE_COUNT; i++) {
|
||||
const uint32_t v = palette[i];
|
||||
bytestream_put_be24(bytestream, v);
|
||||
}
|
||||
}
|
||||
|
||||
bytestream_put_byte(bytestream, 0x08);
|
||||
|
||||
@ -130,7 +123,6 @@ static int gif_image_write_image(AVCodecContext *avctx,
|
||||
len -= size;
|
||||
}
|
||||
bytestream_put_byte(bytestream, 0x00); /* end of image block */
|
||||
bytestream_put_byte(bytestream, 0x3b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -160,6 +152,7 @@ static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
GIFContext *s = avctx->priv_data;
|
||||
AVFrame *const p = &s->picture;
|
||||
uint8_t *outbuf_ptr, *end;
|
||||
const uint32_t *palette = NULL;
|
||||
int ret;
|
||||
|
||||
if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*7/5 + FF_MIN_BUFFER_SIZE)) < 0)
|
||||
@ -170,8 +163,11 @@ static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
*p = *pict;
|
||||
p->pict_type = AV_PICTURE_TYPE_I;
|
||||
p->key_frame = 1;
|
||||
gif_image_write_header(avctx, &outbuf_ptr, (uint32_t *)pict->data[1]);
|
||||
gif_image_write_image(avctx, &outbuf_ptr, end, pict->data[0], pict->linesize[0]);
|
||||
|
||||
if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
|
||||
palette = (uint32_t*)p->data[1];
|
||||
|
||||
gif_image_write_image(avctx, &outbuf_ptr, end, palette, pict->data[0], pict->linesize[0]);
|
||||
|
||||
pkt->size = outbuf_ptr - pkt->data;
|
||||
pkt->flags |= AV_PKT_FLAG_KEY;
|
||||
|
@ -40,84 +40,17 @@
|
||||
*/
|
||||
|
||||
#include "avformat.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/imgutils.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 :) */
|
||||
#define BITSTREAM_WRITER_LE
|
||||
|
||||
#include "libavcodec/put_bits.h"
|
||||
|
||||
/* bitstream minipacket size */
|
||||
#define GIF_CHUNKS 100
|
||||
|
||||
/* slows down the decoding (and some browsers don't like it) */
|
||||
/* update on the 'some browsers don't like it issue from above:
|
||||
* this was probably due to missing 'Data Sub-block Terminator'
|
||||
* (byte 19) in the app_header */
|
||||
#define GIF_ADD_APP_HEADER // required to enable looping of animated gif
|
||||
|
||||
typedef struct {
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
} rgb_triplet;
|
||||
|
||||
/* we use the standard 216 color palette */
|
||||
|
||||
/* this script was used to create the palette:
|
||||
* for r in 00 33 66 99 cc ff; do
|
||||
* for g in 00 33 66 99 cc ff; do
|
||||
* echo -n " "
|
||||
* for b in 00 33 66 99 cc ff; do
|
||||
* echo -n "{ 0x$r, 0x$g, 0x$b }, "
|
||||
* done
|
||||
* echo ""
|
||||
* done
|
||||
* done
|
||||
*/
|
||||
|
||||
static const rgb_triplet gif_clut[216] = {
|
||||
{ 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x33 }, { 0x00, 0x00, 0x66 }, { 0x00, 0x00, 0x99 }, { 0x00, 0x00, 0xcc }, { 0x00, 0x00, 0xff },
|
||||
{ 0x00, 0x33, 0x00 }, { 0x00, 0x33, 0x33 }, { 0x00, 0x33, 0x66 }, { 0x00, 0x33, 0x99 }, { 0x00, 0x33, 0xcc }, { 0x00, 0x33, 0xff },
|
||||
{ 0x00, 0x66, 0x00 }, { 0x00, 0x66, 0x33 }, { 0x00, 0x66, 0x66 }, { 0x00, 0x66, 0x99 }, { 0x00, 0x66, 0xcc }, { 0x00, 0x66, 0xff },
|
||||
{ 0x00, 0x99, 0x00 }, { 0x00, 0x99, 0x33 }, { 0x00, 0x99, 0x66 }, { 0x00, 0x99, 0x99 }, { 0x00, 0x99, 0xcc }, { 0x00, 0x99, 0xff },
|
||||
{ 0x00, 0xcc, 0x00 }, { 0x00, 0xcc, 0x33 }, { 0x00, 0xcc, 0x66 }, { 0x00, 0xcc, 0x99 }, { 0x00, 0xcc, 0xcc }, { 0x00, 0xcc, 0xff },
|
||||
{ 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0x33 }, { 0x00, 0xff, 0x66 }, { 0x00, 0xff, 0x99 }, { 0x00, 0xff, 0xcc }, { 0x00, 0xff, 0xff },
|
||||
{ 0x33, 0x00, 0x00 }, { 0x33, 0x00, 0x33 }, { 0x33, 0x00, 0x66 }, { 0x33, 0x00, 0x99 }, { 0x33, 0x00, 0xcc }, { 0x33, 0x00, 0xff },
|
||||
{ 0x33, 0x33, 0x00 }, { 0x33, 0x33, 0x33 }, { 0x33, 0x33, 0x66 }, { 0x33, 0x33, 0x99 }, { 0x33, 0x33, 0xcc }, { 0x33, 0x33, 0xff },
|
||||
{ 0x33, 0x66, 0x00 }, { 0x33, 0x66, 0x33 }, { 0x33, 0x66, 0x66 }, { 0x33, 0x66, 0x99 }, { 0x33, 0x66, 0xcc }, { 0x33, 0x66, 0xff },
|
||||
{ 0x33, 0x99, 0x00 }, { 0x33, 0x99, 0x33 }, { 0x33, 0x99, 0x66 }, { 0x33, 0x99, 0x99 }, { 0x33, 0x99, 0xcc }, { 0x33, 0x99, 0xff },
|
||||
{ 0x33, 0xcc, 0x00 }, { 0x33, 0xcc, 0x33 }, { 0x33, 0xcc, 0x66 }, { 0x33, 0xcc, 0x99 }, { 0x33, 0xcc, 0xcc }, { 0x33, 0xcc, 0xff },
|
||||
{ 0x33, 0xff, 0x00 }, { 0x33, 0xff, 0x33 }, { 0x33, 0xff, 0x66 }, { 0x33, 0xff, 0x99 }, { 0x33, 0xff, 0xcc }, { 0x33, 0xff, 0xff },
|
||||
{ 0x66, 0x00, 0x00 }, { 0x66, 0x00, 0x33 }, { 0x66, 0x00, 0x66 }, { 0x66, 0x00, 0x99 }, { 0x66, 0x00, 0xcc }, { 0x66, 0x00, 0xff },
|
||||
{ 0x66, 0x33, 0x00 }, { 0x66, 0x33, 0x33 }, { 0x66, 0x33, 0x66 }, { 0x66, 0x33, 0x99 }, { 0x66, 0x33, 0xcc }, { 0x66, 0x33, 0xff },
|
||||
{ 0x66, 0x66, 0x00 }, { 0x66, 0x66, 0x33 }, { 0x66, 0x66, 0x66 }, { 0x66, 0x66, 0x99 }, { 0x66, 0x66, 0xcc }, { 0x66, 0x66, 0xff },
|
||||
{ 0x66, 0x99, 0x00 }, { 0x66, 0x99, 0x33 }, { 0x66, 0x99, 0x66 }, { 0x66, 0x99, 0x99 }, { 0x66, 0x99, 0xcc }, { 0x66, 0x99, 0xff },
|
||||
{ 0x66, 0xcc, 0x00 }, { 0x66, 0xcc, 0x33 }, { 0x66, 0xcc, 0x66 }, { 0x66, 0xcc, 0x99 }, { 0x66, 0xcc, 0xcc }, { 0x66, 0xcc, 0xff },
|
||||
{ 0x66, 0xff, 0x00 }, { 0x66, 0xff, 0x33 }, { 0x66, 0xff, 0x66 }, { 0x66, 0xff, 0x99 }, { 0x66, 0xff, 0xcc }, { 0x66, 0xff, 0xff },
|
||||
{ 0x99, 0x00, 0x00 }, { 0x99, 0x00, 0x33 }, { 0x99, 0x00, 0x66 }, { 0x99, 0x00, 0x99 }, { 0x99, 0x00, 0xcc }, { 0x99, 0x00, 0xff },
|
||||
{ 0x99, 0x33, 0x00 }, { 0x99, 0x33, 0x33 }, { 0x99, 0x33, 0x66 }, { 0x99, 0x33, 0x99 }, { 0x99, 0x33, 0xcc }, { 0x99, 0x33, 0xff },
|
||||
{ 0x99, 0x66, 0x00 }, { 0x99, 0x66, 0x33 }, { 0x99, 0x66, 0x66 }, { 0x99, 0x66, 0x99 }, { 0x99, 0x66, 0xcc }, { 0x99, 0x66, 0xff },
|
||||
{ 0x99, 0x99, 0x00 }, { 0x99, 0x99, 0x33 }, { 0x99, 0x99, 0x66 }, { 0x99, 0x99, 0x99 }, { 0x99, 0x99, 0xcc }, { 0x99, 0x99, 0xff },
|
||||
{ 0x99, 0xcc, 0x00 }, { 0x99, 0xcc, 0x33 }, { 0x99, 0xcc, 0x66 }, { 0x99, 0xcc, 0x99 }, { 0x99, 0xcc, 0xcc }, { 0x99, 0xcc, 0xff },
|
||||
{ 0x99, 0xff, 0x00 }, { 0x99, 0xff, 0x33 }, { 0x99, 0xff, 0x66 }, { 0x99, 0xff, 0x99 }, { 0x99, 0xff, 0xcc }, { 0x99, 0xff, 0xff },
|
||||
{ 0xcc, 0x00, 0x00 }, { 0xcc, 0x00, 0x33 }, { 0xcc, 0x00, 0x66 }, { 0xcc, 0x00, 0x99 }, { 0xcc, 0x00, 0xcc }, { 0xcc, 0x00, 0xff },
|
||||
{ 0xcc, 0x33, 0x00 }, { 0xcc, 0x33, 0x33 }, { 0xcc, 0x33, 0x66 }, { 0xcc, 0x33, 0x99 }, { 0xcc, 0x33, 0xcc }, { 0xcc, 0x33, 0xff },
|
||||
{ 0xcc, 0x66, 0x00 }, { 0xcc, 0x66, 0x33 }, { 0xcc, 0x66, 0x66 }, { 0xcc, 0x66, 0x99 }, { 0xcc, 0x66, 0xcc }, { 0xcc, 0x66, 0xff },
|
||||
{ 0xcc, 0x99, 0x00 }, { 0xcc, 0x99, 0x33 }, { 0xcc, 0x99, 0x66 }, { 0xcc, 0x99, 0x99 }, { 0xcc, 0x99, 0xcc }, { 0xcc, 0x99, 0xff },
|
||||
{ 0xcc, 0xcc, 0x00 }, { 0xcc, 0xcc, 0x33 }, { 0xcc, 0xcc, 0x66 }, { 0xcc, 0xcc, 0x99 }, { 0xcc, 0xcc, 0xcc }, { 0xcc, 0xcc, 0xff },
|
||||
{ 0xcc, 0xff, 0x00 }, { 0xcc, 0xff, 0x33 }, { 0xcc, 0xff, 0x66 }, { 0xcc, 0xff, 0x99 }, { 0xcc, 0xff, 0xcc }, { 0xcc, 0xff, 0xff },
|
||||
{ 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0x33 }, { 0xff, 0x00, 0x66 }, { 0xff, 0x00, 0x99 }, { 0xff, 0x00, 0xcc }, { 0xff, 0x00, 0xff },
|
||||
{ 0xff, 0x33, 0x00 }, { 0xff, 0x33, 0x33 }, { 0xff, 0x33, 0x66 }, { 0xff, 0x33, 0x99 }, { 0xff, 0x33, 0xcc }, { 0xff, 0x33, 0xff },
|
||||
{ 0xff, 0x66, 0x00 }, { 0xff, 0x66, 0x33 }, { 0xff, 0x66, 0x66 }, { 0xff, 0x66, 0x99 }, { 0xff, 0x66, 0xcc }, { 0xff, 0x66, 0xff },
|
||||
{ 0xff, 0x99, 0x00 }, { 0xff, 0x99, 0x33 }, { 0xff, 0x99, 0x66 }, { 0xff, 0x99, 0x99 }, { 0xff, 0x99, 0xcc }, { 0xff, 0x99, 0xff },
|
||||
{ 0xff, 0xcc, 0x00 }, { 0xff, 0xcc, 0x33 }, { 0xff, 0xcc, 0x66 }, { 0xff, 0xcc, 0x99 }, { 0xff, 0xcc, 0xcc }, { 0xff, 0xcc, 0xff },
|
||||
{ 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0x33 }, { 0xff, 0xff, 0x66 }, { 0xff, 0xff, 0x99 }, { 0xff, 0xff, 0xcc }, { 0xff, 0xff, 0xff },
|
||||
};
|
||||
|
||||
/* GIF header */
|
||||
static int gif_image_write_header(AVIOContext *pb, int width, int height,
|
||||
int loop_count, uint32_t *palette)
|
||||
{
|
||||
@ -129,22 +62,21 @@ static int gif_image_write_header(AVIOContext *pb, int width, int height,
|
||||
avio_wl16(pb, width);
|
||||
avio_wl16(pb, height);
|
||||
|
||||
if (palette) {
|
||||
/* TODO: reindent */
|
||||
avio_w8(pb, 0xf7); /* flags: global clut, 256 entries */
|
||||
avio_w8(pb, 0x1f); /* background color index */
|
||||
avio_w8(pb, 0); /* aspect ratio */
|
||||
|
||||
/* the global palette */
|
||||
if (!palette) {
|
||||
avio_write(pb, (const unsigned char *)gif_clut, 216 * 3);
|
||||
for (i = 0; i < ((256 - 216) * 3); i++)
|
||||
avio_w8(pb, 0);
|
||||
} else {
|
||||
for (i = 0; i < 256; i++) {
|
||||
v = palette[i];
|
||||
avio_w8(pb, (v >> 16) & 0xff);
|
||||
avio_w8(pb, (v >> 8) & 0xff);
|
||||
avio_w8(pb, (v) & 0xff);
|
||||
}
|
||||
} else {
|
||||
avio_w8(pb, 0); /* flags */
|
||||
avio_w8(pb, 0); /* background color index */
|
||||
avio_w8(pb, 0); /* aspect ratio */
|
||||
}
|
||||
|
||||
/* update: this is the 'NETSCAPE EXTENSION' that allows for looped animated
|
||||
@ -183,76 +115,6 @@ static int gif_image_write_header(AVIOContext *pb, int width, int height,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this is maybe slow, but allows for extensions */
|
||||
static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
return (((r) / 47) % 6) * 6 * 6 + (((g) / 47) % 6) * 6 + (((b) / 47) % 6);
|
||||
}
|
||||
|
||||
static int gif_image_write_image(AVIOContext *pb,
|
||||
int x1, int y1, int width, int height,
|
||||
const uint8_t *buf, int linesize, int pix_fmt)
|
||||
{
|
||||
PutBitContext p;
|
||||
uint8_t buffer[200]; /* 100 * 9 / 8 = 113 */
|
||||
int i, left, w, v;
|
||||
const uint8_t *ptr;
|
||||
/* image block */
|
||||
|
||||
avio_w8(pb, 0x2c);
|
||||
avio_wl16(pb, x1);
|
||||
avio_wl16(pb, y1);
|
||||
avio_wl16(pb, width);
|
||||
avio_wl16(pb, height);
|
||||
avio_w8(pb, 0x00); /* flags */
|
||||
/* no local clut */
|
||||
|
||||
avio_w8(pb, 0x08);
|
||||
|
||||
left = width * height;
|
||||
|
||||
init_put_bits(&p, buffer, 130);
|
||||
|
||||
/*
|
||||
* the thing here is the bitstream is written as little packets, with a size
|
||||
* byte before but it's still the same bitstream between packets (no flush !)
|
||||
*/
|
||||
ptr = buf;
|
||||
w = width;
|
||||
while (left > 0) {
|
||||
put_bits(&p, 9, 0x0100); /* clear code */
|
||||
|
||||
for (i = (left < GIF_CHUNKS) ? left : GIF_CHUNKS; i; i--) {
|
||||
if (pix_fmt == AV_PIX_FMT_RGB24) {
|
||||
v = gif_clut_index(ptr[0], ptr[1], ptr[2]);
|
||||
ptr += 3;
|
||||
} else {
|
||||
v = *ptr++;
|
||||
}
|
||||
put_bits(&p, 9, v);
|
||||
if (--w == 0) {
|
||||
w = width;
|
||||
buf += linesize;
|
||||
ptr = buf;
|
||||
}
|
||||
}
|
||||
|
||||
if (left <= GIF_CHUNKS) {
|
||||
put_bits(&p, 9, 0x101); /* end of stream */
|
||||
flush_put_bits(&p);
|
||||
}
|
||||
if (put_bits_ptr(&p) - p.buf > 0) {
|
||||
avio_w8(pb, put_bits_ptr(&p) - p.buf); /* byte count of the packet */
|
||||
avio_write(pb, p.buf, put_bits_ptr(&p) - p.buf); /* the actual buffer */
|
||||
p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */
|
||||
}
|
||||
left -= GIF_CHUNKS;
|
||||
}
|
||||
avio_w8(pb, 0x00); /* end of image block */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
AVClass *class; /** Class for private options. */
|
||||
int64_t time, file_time;
|
||||
@ -266,6 +128,7 @@ static int gif_write_header(AVFormatContext *s)
|
||||
AVIOContext *pb = s->pb;
|
||||
AVCodecContext *enc, *video_enc;
|
||||
int i, width, height /*, rate*/;
|
||||
uint32_t palette[AVPALETTE_COUNT];
|
||||
|
||||
/* XXX: do we reject audio streams or just ignore them ?
|
||||
* if (s->nb_streams > 1)
|
||||
@ -290,14 +153,13 @@ static int gif_write_header(AVFormatContext *s)
|
||||
// rate = video_enc->time_base.den;
|
||||
}
|
||||
|
||||
if (video_enc->pix_fmt != AV_PIX_FMT_RGB24) {
|
||||
av_log(s, AV_LOG_ERROR,
|
||||
"ERROR: gif only handles the rgb24 pixel format. Use -pix_fmt rgb24.\n");
|
||||
return AVERROR(EIO);
|
||||
if (avpriv_set_systematic_pal2(palette, video_enc->pix_fmt) < 0) {
|
||||
av_assert0(video_enc->pix_fmt == AV_PIX_FMT_PAL8);
|
||||
gif_image_write_header(pb, width, height, gif->loop, NULL);
|
||||
} else {
|
||||
gif_image_write_header(pb, width, height, gif->loop, palette);
|
||||
}
|
||||
|
||||
gif_image_write_header(pb, width, height, gif->loop, NULL);
|
||||
|
||||
avio_flush(s->pb);
|
||||
return 0;
|
||||
}
|
||||
@ -326,8 +188,7 @@ static int gif_write_video(AVFormatContext *s, AVCodecContext *enc,
|
||||
avio_w8(pb, 0x1f); /* transparent color index */
|
||||
avio_w8(pb, 0x00);
|
||||
|
||||
gif_image_write_image(pb, 0, 0, enc->width, enc->height,
|
||||
buf, enc->width * 3, AV_PIX_FMT_RGB24);
|
||||
avio_write(pb, buf, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -372,7 +233,7 @@ AVOutputFormat ff_gif_muxer = {
|
||||
.extensions = "gif",
|
||||
.priv_data_size = sizeof(GIFContext),
|
||||
.audio_codec = AV_CODEC_ID_NONE,
|
||||
.video_codec = AV_CODEC_ID_RAWVIDEO,
|
||||
.video_codec = AV_CODEC_ID_GIF,
|
||||
.write_header = gif_write_header,
|
||||
.write_packet = gif_write_packet,
|
||||
.write_trailer = gif_write_trailer,
|
||||
|
@ -50,7 +50,6 @@ static const IdStrMap img_tags[] = {
|
||||
{ AV_CODEC_ID_RAWVIDEO, "y" },
|
||||
{ AV_CODEC_ID_RAWVIDEO, "raw" },
|
||||
{ AV_CODEC_ID_BMP, "bmp" },
|
||||
{ AV_CODEC_ID_GIF, "gif" },
|
||||
{ AV_CODEC_ID_TARGA, "tga" },
|
||||
{ AV_CODEC_ID_TIFF, "tiff" },
|
||||
{ AV_CODEC_ID_TIFF, "tif" },
|
||||
|
@ -1,24 +1,24 @@
|
||||
e6089fd4ef3b9df44090ab3650bdd810 *./tests/data/lavf/lavf.gif
|
||||
2906401 ./tests/data/lavf/lavf.gif
|
||||
./tests/data/lavf/lavf.gif CRC=0x9825d7c0
|
||||
66398be6fafa026fb0fa5f2978fa3446 *./tests/data/lavf/lavf.gif
|
||||
2011766 ./tests/data/lavf/lavf.gif
|
||||
./tests/data/lavf/lavf.gif CRC=0x0d96deb8
|
||||
022dc66b5068404e88c618ce79d9eb5f *./tests/data/images/gif/02.gif
|
||||
./tests/data/images/gif/%02d.gif CRC=0x032e0034
|
||||
81538 ./tests/data/images/gif/02.gif
|
||||
759522b3025fcf8ed6aae582a18c5a14 *./tests/data/images/gif/02.gif
|
||||
./tests/data/images/gif/%02d.gif CRC=0x4c8f8a89
|
||||
38715 ./tests/data/images/gif/02.gif
|
||||
21e802ae7a2239bdbea6f915da1134b9 *./tests/data/images/gif/02.gif
|
||||
./tests/data/images/gif/%02d.gif CRC=0x4c8f8a89
|
||||
38715 ./tests/data/images/gif/02.gif
|
||||
fc4792ac40319344dc7027668a403fc3 *./tests/data/images/gif/02.gif
|
||||
./tests/data/images/gif/%02d.gif CRC=0x032e0034
|
||||
./tests/data/images/gif/%02d.gif CRC=0x51811243
|
||||
81538 ./tests/data/images/gif/02.gif
|
||||
022dc66b5068404e88c618ce79d9eb5f *./tests/data/images/gif/02.gif
|
||||
./tests/data/images/gif/%02d.gif CRC=0x032e0034
|
||||
./tests/data/images/gif/%02d.gif CRC=0x006183fd
|
||||
81538 ./tests/data/images/gif/02.gif
|
||||
e3392f49c55aa794d3dc49189f52f257 *./tests/data/images/gif/02.gif
|
||||
./tests/data/images/gif/%02d.gif CRC=0x22d67c27
|
||||
63144 ./tests/data/images/gif/02.gif
|
||||
022dc66b5068404e88c618ce79d9eb5f *./tests/data/images/gif/02.gif
|
||||
./tests/data/images/gif/%02d.gif CRC=0x032e0034
|
||||
./tests/data/images/gif/%02d.gif CRC=0x006183fd
|
||||
81538 ./tests/data/images/gif/02.gif
|
||||
022dc66b5068404e88c618ce79d9eb5f *./tests/data/images/gif/02.gif
|
||||
./tests/data/images/gif/%02d.gif CRC=0x51811243
|
||||
81538 ./tests/data/images/gif/02.gif
|
||||
022dc66b5068404e88c618ce79d9eb5f *./tests/data/images/gif/02.gif
|
||||
./tests/data/images/gif/%02d.gif CRC=0x51811243
|
||||
81538 ./tests/data/images/gif/02.gif
|
||||
022dc66b5068404e88c618ce79d9eb5f *./tests/data/images/gif/02.gif
|
||||
./tests/data/images/gif/%02d.gif CRC=0xd742fb02
|
||||
81538 ./tests/data/images/gif/02.gif
|
||||
022dc66b5068404e88c618ce79d9eb5f *./tests/data/images/gif/02.gif
|
||||
./tests/data/images/gif/%02d.gif CRC=0x51811243
|
||||
81538 ./tests/data/images/gif/02.gif
|
||||
|
@ -1,40 +1,40 @@
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret: 0 st:-1 flags:0 ts:-1.000000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret: 0 st:-1 flags:1 ts: 1.894167
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret:-1 st: 0 flags:0 ts: 0.790000
|
||||
ret:-1 st: 0 flags:1 ts:-0.320000
|
||||
ret:-1 st:-1 flags:0 ts: 2.576668
|
||||
ret: 0 st:-1 flags:1 ts: 1.470835
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret:-1 st: 0 flags:0 ts: 0.370000
|
||||
ret:-1 st: 0 flags:1 ts:-0.740000
|
||||
ret:-1 st:-1 flags:0 ts: 2.153336
|
||||
ret: 0 st:-1 flags:1 ts: 1.047503
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret: 0 st: 0 flags:0 ts:-0.060000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret: 0 st: 0 flags:1 ts: 2.840000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret:-1 st:-1 flags:0 ts: 1.730004
|
||||
ret: 0 st:-1 flags:1 ts: 0.624171
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret: 0 st: 0 flags:0 ts:-0.480000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret: 0 st: 0 flags:1 ts: 2.410000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret:-1 st:-1 flags:0 ts: 1.306672
|
||||
ret: 0 st:-1 flags:1 ts: 0.200839
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret: 0 st: 0 flags:0 ts:-0.900000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret: 0 st: 0 flags:1 ts: 1.990000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret:-1 st:-1 flags:0 ts: 0.883340
|
||||
ret:-1 st:-1 flags:1 ts:-0.222493
|
||||
ret:-1 st: 0 flags:0 ts: 2.670000
|
||||
ret: 0 st: 0 flags:1 ts: 1.570000
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size:117024
|
||||
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 81501
|
||||
ret:-1 st:-1 flags:0 ts: 0.460008
|
||||
ret:-1 st:-1 flags:1 ts:-0.645825
|
||||
|
Loading…
Reference in New Issue
Block a user