Mercurial > libavcodec.hg
annotate gif.c @ 8991:ca768cb2bfb6 libavcodec
Use last decoded SPS as current SPS in order to parse picture timing SEI
correctly. This works around an apparent H.264 standard deficiency.
Patch by Ivan Schreter, schreter gmx net
author | cehoyos |
---|---|
date | Fri, 20 Feb 2009 16:20:01 +0000 |
parents | 7c60077e7380 |
children | 4cb7c65fc775 |
rev | line source |
---|---|
4125 | 1 /* |
2 * GIF encoder. | |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8591
diff
changeset
|
3 * Copyright (c) 2000 Fabrice Bellard |
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8591
diff
changeset
|
4 * Copyright (c) 2002 Francois Revol |
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8591
diff
changeset
|
5 * Copyright (c) 2006 Baptiste Coudurier |
4125 | 6 * |
7 * This file is part of FFmpeg. | |
8 * | |
9 * FFmpeg is free software; you can redistribute it and/or | |
10 * modify it under the terms of the GNU Lesser General Public | |
11 * License as published by the Free Software Foundation; either | |
12 * version 2.1 of the License, or (at your option) any later version. | |
13 * | |
14 * FFmpeg is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * Lesser General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU Lesser General Public | |
20 * License along with FFmpeg; if not, write to the Free Software | |
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
22 */ | |
23 | |
24 /* | |
25 * First version by Francois Revol revol@free.fr | |
26 * | |
27 * Features and limitations: | |
28 * - currently no compression is performed, | |
29 * in fact the size of the data is 9/8 the size of the image in 8bpp | |
30 * - uses only a global standard palette | |
31 * - tested with IE 5.0, Opera for BeOS, NetPositive (BeOS), and Mozilla (BeOS). | |
32 * | |
33 * Reference documents: | |
34 * http://www.goice.co.jp/member/mo/formats/gif.html | |
35 * http://astronomy.swin.edu.au/pbourke/dataformats/gif/ | |
36 * http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/GIF89a.txt | |
37 * | |
38 * this url claims to have an LZW algorithm not covered by Unisys patent: | |
39 * http://www.msg.net/utility/whirlgif/gifencod.html | |
40 * could help reduce the size of the files _a lot_... | |
41 * some sites mentions an RLE type compression also. | |
42 */ | |
43 | |
44 #include "avcodec.h" | |
45 #include "bytestream.h" | |
8591 | 46 |
47 /* The GIF format uses reversed order for bitstreams... */ | |
48 /* at least they don't use PDP_ENDIAN :) */ | |
49 #define BITSTREAM_WRITER_LE | |
50 | |
4125 | 51 #include "bitstream.h" |
52 | |
53 /* bitstream minipacket size */ | |
54 #define GIF_CHUNKS 100 | |
55 | |
56 /* GIF header */ | |
57 static int gif_image_write_header(uint8_t **bytestream, | |
8773
80a01d448b45
remove dead netscape loop header code in gif encoder, patch by Daniel Verkamp, daniel at drv dot nu
bcoudurier
parents:
8749
diff
changeset
|
58 int width, int height, |
4125 | 59 uint32_t *palette) |
60 { | |
61 int i; | |
62 unsigned int v; | |
63 | |
64 bytestream_put_buffer(bytestream, "GIF", 3); | |
65 bytestream_put_buffer(bytestream, "89a", 3); | |
66 bytestream_put_le16(bytestream, width); | |
67 bytestream_put_le16(bytestream, height); | |
68 | |
69 bytestream_put_byte(bytestream, 0xf7); /* flags: global clut, 256 entries */ | |
70 bytestream_put_byte(bytestream, 0x1f); /* background color index */ | |
71 bytestream_put_byte(bytestream, 0); /* aspect ratio */ | |
72 | |
73 /* the global palette */ | |
8774
0a8166d20fd3
remove dead rgb24 code, gif encoder now directly takes palette, patch by Daniel Verkamp, daniel at drv dot nu
bcoudurier
parents:
8773
diff
changeset
|
74 for(i=0;i<256;i++) { |
0a8166d20fd3
remove dead rgb24 code, gif encoder now directly takes palette, patch by Daniel Verkamp, daniel at drv dot nu
bcoudurier
parents:
8773
diff
changeset
|
75 v = palette[i]; |
0a8166d20fd3
remove dead rgb24 code, gif encoder now directly takes palette, patch by Daniel Verkamp, daniel at drv dot nu
bcoudurier
parents:
8773
diff
changeset
|
76 bytestream_put_be24(bytestream, v); |
4125 | 77 } |
78 | |
79 return 0; | |
80 } | |
81 | |
82 static int gif_image_write_image(uint8_t **bytestream, | |
83 int x1, int y1, int width, int height, | |
84 const uint8_t *buf, int linesize, int pix_fmt) | |
85 { | |
86 PutBitContext p; | |
87 uint8_t buffer[200]; /* 100 * 9 / 8 = 113 */ | |
8774
0a8166d20fd3
remove dead rgb24 code, gif encoder now directly takes palette, patch by Daniel Verkamp, daniel at drv dot nu
bcoudurier
parents:
8773
diff
changeset
|
88 int i, left, w; |
4125 | 89 const uint8_t *ptr; |
90 /* image block */ | |
91 | |
92 bytestream_put_byte(bytestream, 0x2c); | |
93 bytestream_put_le16(bytestream, x1); | |
94 bytestream_put_le16(bytestream, y1); | |
95 bytestream_put_le16(bytestream, width); | |
96 bytestream_put_le16(bytestream, height); | |
97 bytestream_put_byte(bytestream, 0x00); /* flags */ | |
98 /* no local clut */ | |
99 | |
100 bytestream_put_byte(bytestream, 0x08); | |
101 | |
102 left= width * height; | |
103 | |
104 init_put_bits(&p, buffer, 130); | |
105 | |
106 /* | |
107 * the thing here is the bitstream is written as little packets, with a size byte before | |
108 * but it's still the same bitstream between packets (no flush !) | |
109 */ | |
110 ptr = buf; | |
111 w = width; | |
112 while(left>0) { | |
113 | |
8591 | 114 put_bits(&p, 9, 0x0100); /* clear code */ |
4125 | 115 |
116 for(i=(left<GIF_CHUNKS)?left:GIF_CHUNKS;i;i--) { | |
8774
0a8166d20fd3
remove dead rgb24 code, gif encoder now directly takes palette, patch by Daniel Verkamp, daniel at drv dot nu
bcoudurier
parents:
8773
diff
changeset
|
117 put_bits(&p, 9, *ptr++); |
4125 | 118 if (--w == 0) { |
119 w = width; | |
120 buf += linesize; | |
121 ptr = buf; | |
122 } | |
123 } | |
124 | |
125 if(left<=GIF_CHUNKS) { | |
8591 | 126 put_bits(&p, 9, 0x101); /* end of stream */ |
127 flush_put_bits(&p); | |
4125 | 128 } |
129 if(pbBufPtr(&p) - p.buf > 0) { | |
130 bytestream_put_byte(bytestream, pbBufPtr(&p) - p.buf); /* byte count of the packet */ | |
131 bytestream_put_buffer(bytestream, p.buf, pbBufPtr(&p) - p.buf); /* the actual buffer */ | |
132 p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */ | |
133 } | |
134 left-=GIF_CHUNKS; | |
135 } | |
136 bytestream_put_byte(bytestream, 0x00); /* end of image block */ | |
137 bytestream_put_byte(bytestream, 0x3b); | |
138 return 0; | |
139 } | |
140 | |
141 typedef struct { | |
142 AVFrame picture; | |
143 } GIFContext; | |
144 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6152
diff
changeset
|
145 static av_cold int gif_encode_init(AVCodecContext *avctx) |
4125 | 146 { |
147 GIFContext *s = avctx->priv_data; | |
148 | |
149 avctx->coded_frame = &s->picture; | |
150 return 0; | |
151 } | |
152 | |
153 /* better than nothing gif encoder */ | |
154 static int gif_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data) | |
155 { | |
156 GIFContext *s = avctx->priv_data; | |
157 AVFrame *pict = data; | |
158 AVFrame *const p = (AVFrame *)&s->picture; | |
159 uint8_t *outbuf_ptr = outbuf; | |
160 | |
161 *p = *pict; | |
162 p->pict_type = FF_I_TYPE; | |
163 p->key_frame = 1; | |
8773
80a01d448b45
remove dead netscape loop header code in gif encoder, patch by Daniel Verkamp, daniel at drv dot nu
bcoudurier
parents:
8749
diff
changeset
|
164 gif_image_write_header(&outbuf_ptr, avctx->width, avctx->height, (uint32_t *)pict->data[1]); |
4125 | 165 gif_image_write_image(&outbuf_ptr, 0, 0, avctx->width, avctx->height, pict->data[0], pict->linesize[0], PIX_FMT_PAL8); |
166 return outbuf_ptr - outbuf; | |
167 } | |
168 | |
169 AVCodec gif_encoder = { | |
170 "gif", | |
171 CODEC_TYPE_VIDEO, | |
172 CODEC_ID_GIF, | |
173 sizeof(GIFContext), | |
174 gif_encode_init, | |
175 gif_encode_frame, | |
176 NULL, //encode_end, | |
8749
21a41fd79033
Fix list of input pix_fmts supported by GIF. This makes it work with swscale.
michael
parents:
8629
diff
changeset
|
177 .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB8, PIX_FMT_BGR8, PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, PIX_FMT_GRAY8, PIX_FMT_PAL8, PIX_FMT_NONE}, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6788
diff
changeset
|
178 .long_name= NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"), |
4125 | 179 }; |