Mercurial > libavcodec.hg
annotate lcl.c @ 2429:4b350cc506a7 libavcodec
Use avcodec_check_dimensions instead of custom hack
author | rtognimp |
---|---|
date | Sat, 15 Jan 2005 00:07:38 +0000 |
parents | 82af834636c2 |
children | f67b63ed036d |
rev | line source |
---|---|
1743 | 1 /* |
2 * LCL (LossLess Codec Library) Codec | |
3 * Copyright (c) 2002-2004 Roberto Togni | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 * | |
19 */ | |
20 | |
21 /** | |
22 * @file lcl.c | |
23 * LCL (LossLess Codec Library) Video Codec | |
24 * Decoder for MSZH and ZLIB codecs | |
25 * Experimental encoder for ZLIB RGB24 | |
26 * | |
27 * Fourcc: MSZH, ZLIB | |
28 * | |
29 * Original Win32 dll: | |
30 * Ver2.23 By Kenji Oshima 2000.09.20 | |
31 * avimszh.dll, avizlib.dll | |
32 * | |
33 * A description of the decoding algorithm can be found here: | |
34 * http://www.pcisys.net/~melanson/codecs | |
35 * | |
36 * Supports: BGR24 (RGB 24bpp) | |
37 * | |
38 */ | |
39 | |
40 #include <stdio.h> | |
41 #include <stdlib.h> | |
42 | |
43 #include "common.h" | |
2398
582e635cfa08
common.c -> bitstream.c (and the single non bitstream func -> utils.c)
michael
parents:
2250
diff
changeset
|
44 #include "bitstream.h" |
1743 | 45 #include "avcodec.h" |
46 | |
47 #ifdef CONFIG_ZLIB | |
48 #include <zlib.h> | |
49 #endif | |
50 | |
51 | |
52 #define BMPTYPE_YUV 1 | |
53 #define BMPTYPE_RGB 2 | |
54 | |
55 #define IMGTYPE_YUV111 0 | |
56 #define IMGTYPE_YUV422 1 | |
57 #define IMGTYPE_RGB24 2 | |
58 #define IMGTYPE_YUV411 3 | |
59 #define IMGTYPE_YUV211 4 | |
60 #define IMGTYPE_YUV420 5 | |
61 | |
62 #define COMP_MSZH 0 | |
63 #define COMP_MSZH_NOCOMP 1 | |
64 #define COMP_ZLIB_HISPEED 1 | |
65 #define COMP_ZLIB_HICOMP 9 | |
66 #define COMP_ZLIB_NORMAL -1 | |
67 | |
68 #define FLAG_MULTITHREAD 1 | |
69 #define FLAG_NULLFRAME 2 | |
70 #define FLAG_PNGFILTER 4 | |
71 #define FLAGMASK_UNUSED 0xf8 | |
72 | |
73 #define CODEC_MSZH 1 | |
74 #define CODEC_ZLIB 3 | |
75 | |
76 #define FOURCC_MSZH mmioFOURCC('M','S','Z','H') | |
77 #define FOURCC_ZLIB mmioFOURCC('Z','L','I','B') | |
78 | |
79 /* | |
80 * Decoder context | |
81 */ | |
82 typedef struct LclContext { | |
83 | |
84 AVCodecContext *avctx; | |
85 AVFrame pic; | |
86 PutBitContext pb; | |
87 | |
88 // Image type | |
89 int imgtype; | |
90 // Compression type | |
91 int compression; | |
92 // Flags | |
93 int flags; | |
94 // Decompressed data size | |
95 unsigned int decomp_size; | |
96 // Decompression buffer | |
97 unsigned char* decomp_buf; | |
98 // Maximum compressed data size | |
99 unsigned int max_comp_size; | |
100 // Compression buffer | |
101 unsigned char* comp_buf; | |
102 #ifdef CONFIG_ZLIB | |
103 z_stream zstream; | |
104 #endif | |
105 } LclContext; | |
106 | |
107 | |
108 /* | |
109 * | |
110 * Helper functions | |
111 * | |
112 */ | |
113 static inline unsigned char fix (int pix14) | |
114 { | |
115 int tmp; | |
116 | |
117 tmp = (pix14 + 0x80000) >> 20; | |
118 if (tmp < 0) | |
119 return 0; | |
120 if (tmp > 255) | |
121 return 255; | |
122 return tmp; | |
123 } | |
124 | |
125 | |
126 | |
127 static inline unsigned char get_b (unsigned char yq, signed char bq) | |
128 { | |
129 return fix((yq << 20) + bq * 1858076); | |
130 } | |
131 | |
132 | |
133 | |
134 static inline unsigned char get_g (unsigned char yq, signed char bq, signed char rq) | |
135 { | |
136 return fix((yq << 20) - bq * 360857 - rq * 748830); | |
137 } | |
138 | |
139 | |
140 | |
141 static inline unsigned char get_r (unsigned char yq, signed char rq) | |
142 { | |
143 return fix((yq << 20) + rq * 1470103); | |
144 } | |
145 | |
146 | |
147 | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
148 static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) |
1743 | 149 { |
150 unsigned char *destptr_bak = destptr; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
151 unsigned char *destptr_end = destptr + destsize; |
1743 | 152 unsigned char mask = 0; |
153 unsigned char maskbit = 0; | |
154 unsigned int ofs, cnt; | |
155 | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
156 while ((srclen > 0) && (destptr < destptr_end)) { |
1743 | 157 if (maskbit == 0) { |
158 mask = *(srcptr++); | |
159 maskbit = 8; | |
160 srclen--; | |
161 continue; | |
162 } | |
163 if ((mask & (1 << (--maskbit))) == 0) { | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
164 if (destptr + 4 > destptr_end) |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
165 break; |
1743 | 166 *(int*)destptr = *(int*)srcptr; |
167 srclen -= 4; | |
168 destptr += 4; | |
169 srcptr += 4; | |
170 } else { | |
171 ofs = *(srcptr++); | |
172 cnt = *(srcptr++); | |
173 ofs += cnt * 256;; | |
174 cnt = ((cnt >> 3) & 0x1f) + 1; | |
175 ofs &= 0x7ff; | |
176 srclen -= 2; | |
177 cnt *= 4; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
178 if (destptr + cnt > destptr_end) { |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
179 cnt = destptr_end - destptr; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
180 } |
1743 | 181 for (; cnt > 0; cnt--) { |
182 *(destptr) = *(destptr - ofs); | |
183 destptr++; | |
184 } | |
185 } | |
186 } | |
187 | |
188 return (destptr - destptr_bak); | |
189 } | |
190 | |
191 | |
192 | |
193 | |
194 /* | |
195 * | |
196 * Decode a frame | |
197 * | |
198 */ | |
199 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) | |
200 { | |
201 LclContext * const c = (LclContext *)avctx->priv_data; | |
202 unsigned char *encoded = (unsigned char *)buf; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
203 unsigned int pixel_ptr; |
1743 | 204 int row, col; |
205 unsigned char *outptr; | |
206 unsigned int width = avctx->width; // Real image width | |
207 unsigned int height = avctx->height; // Real image height | |
208 unsigned int mszh_dlen; | |
209 unsigned char yq, y1q, uq, vq; | |
210 int uqvq; | |
211 unsigned int mthread_inlen, mthread_outlen; | |
212 #ifdef CONFIG_ZLIB | |
213 int zret; // Zlib return code | |
214 #endif | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
215 unsigned int len = buf_size; |
1743 | 216 |
217 /* no supplementary picture */ | |
218 if (buf_size == 0) | |
219 return 0; | |
220 | |
221 if(c->pic.data[0]) | |
222 avctx->release_buffer(avctx, &c->pic); | |
223 | |
224 c->pic.reference = 0; | |
225 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; | |
226 if(avctx->get_buffer(avctx, &c->pic) < 0){ | |
227 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
228 return -1; | |
229 } | |
230 | |
231 outptr = c->pic.data[0]; // Output image pointer | |
232 | |
233 /* Decompress frame */ | |
234 switch (avctx->codec_id) { | |
235 case CODEC_ID_MSZH: | |
236 switch (c->compression) { | |
237 case COMP_MSZH: | |
238 if (c->flags & FLAG_MULTITHREAD) { | |
239 mthread_inlen = *((unsigned int*)encoded); | |
240 mthread_outlen = *((unsigned int*)(encoded+4)); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
241 if (mthread_outlen > c->decomp_size) // this should not happen |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
242 mthread_outlen = c->decomp_size; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
243 mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size); |
1743 | 244 if (mthread_outlen != mszh_dlen) { |
245 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n", | |
246 mthread_outlen, mszh_dlen); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
247 return -1; |
1743 | 248 } |
249 mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - mthread_inlen, | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
250 c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen); |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
251 if (mthread_outlen != mszh_dlen) { |
1743 | 252 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n", |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
253 mthread_outlen, mszh_dlen); |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
254 return -1; |
1743 | 255 } |
256 encoded = c->decomp_buf; | |
257 len = c->decomp_size; | |
258 } else { | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
259 mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size); |
1743 | 260 if (c->decomp_size != mszh_dlen) { |
261 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n", | |
262 c->decomp_size, mszh_dlen); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
263 return -1; |
1743 | 264 } |
265 encoded = c->decomp_buf; | |
266 len = mszh_dlen; | |
267 } | |
268 break; | |
269 case COMP_MSZH_NOCOMP: | |
270 break; | |
271 default: | |
272 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); | |
273 return -1; | |
274 } | |
275 break; | |
276 case CODEC_ID_ZLIB: | |
277 #ifdef CONFIG_ZLIB | |
278 /* Using the original dll with normal compression (-1) and RGB format | |
279 * gives a file with ZLIB fourcc, but frame is really uncompressed. | |
280 * To be sure that's true check also frame size */ | |
281 if ((c->compression == COMP_ZLIB_NORMAL) && (c->imgtype == IMGTYPE_RGB24) && | |
282 (len == width * height * 3)) | |
283 break; | |
284 zret = inflateReset(&(c->zstream)); | |
285 if (zret != Z_OK) { | |
286 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); | |
287 return -1; | |
288 } | |
289 if (c->flags & FLAG_MULTITHREAD) { | |
290 mthread_inlen = *((unsigned int*)encoded); | |
291 mthread_outlen = *((unsigned int*)(encoded+4)); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
292 if (mthread_outlen > c->decomp_size) |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
293 mthread_outlen = c->decomp_size; |
1743 | 294 c->zstream.next_in = encoded + 8; |
295 c->zstream.avail_in = mthread_inlen; | |
296 c->zstream.next_out = c->decomp_buf; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
297 c->zstream.avail_out = c->decomp_size; |
1743 | 298 zret = inflate(&(c->zstream), Z_FINISH); |
299 if ((zret != Z_OK) && (zret != Z_STREAM_END)) { | |
300 av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret); | |
301 return -1; | |
302 } | |
303 if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { | |
304 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n", | |
305 mthread_outlen, c->zstream.total_out); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
306 return -1; |
1743 | 307 } |
308 zret = inflateReset(&(c->zstream)); | |
309 if (zret != Z_OK) { | |
310 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate reset error: %d\n", zret); | |
311 return -1; | |
312 } | |
313 c->zstream.next_in = encoded + 8 + mthread_inlen; | |
314 c->zstream.avail_in = len - mthread_inlen; | |
315 c->zstream.next_out = c->decomp_buf + mthread_outlen; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
316 c->zstream.avail_out = c->decomp_size - mthread_outlen; |
1743 | 317 zret = inflate(&(c->zstream), Z_FINISH); |
318 if ((zret != Z_OK) && (zret != Z_STREAM_END)) { | |
319 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret); | |
320 return -1; | |
321 } | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
322 if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { |
1743 | 323 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n", |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
324 mthread_outlen, c->zstream.total_out); |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
325 return -1; |
1743 | 326 } |
327 } else { | |
328 c->zstream.next_in = encoded; | |
329 c->zstream.avail_in = len; | |
330 c->zstream.next_out = c->decomp_buf; | |
331 c->zstream.avail_out = c->decomp_size; | |
332 zret = inflate(&(c->zstream), Z_FINISH); | |
333 if ((zret != Z_OK) && (zret != Z_STREAM_END)) { | |
334 av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); | |
335 return -1; | |
336 } | |
337 if (c->decomp_size != (unsigned int)(c->zstream.total_out)) { | |
338 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", | |
339 c->decomp_size, c->zstream.total_out); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
340 return -1; |
1743 | 341 } |
342 } | |
343 encoded = c->decomp_buf; | |
344 len = c->decomp_size;; | |
345 #else | |
346 av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n"); | |
347 return -1; | |
348 #endif | |
349 break; | |
350 default: | |
351 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n"); | |
352 return -1; | |
353 } | |
354 | |
355 | |
356 /* Apply PNG filter */ | |
357 if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) { | |
358 switch (c->imgtype) { | |
359 case IMGTYPE_YUV111: | |
360 case IMGTYPE_RGB24: | |
361 for (row = 0; row < height; row++) { | |
362 pixel_ptr = row * width * 3; | |
363 yq = encoded[pixel_ptr++]; | |
364 uqvq = encoded[pixel_ptr++]; | |
365 uqvq+=(encoded[pixel_ptr++] << 8); | |
366 for (col = 1; col < width; col++) { | |
367 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
368 uqvq -= (encoded[pixel_ptr+1] | (encoded[pixel_ptr+2]<<8)); | |
369 encoded[pixel_ptr+1] = (uqvq) & 0xff; | |
370 encoded[pixel_ptr+2] = ((uqvq)>>8) & 0xff; | |
371 pixel_ptr += 3; | |
372 } | |
373 } | |
374 break; | |
375 case IMGTYPE_YUV422: | |
376 for (row = 0; row < height; row++) { | |
377 pixel_ptr = row * width * 2; | |
378 yq = uq = vq =0; | |
379 for (col = 0; col < width/4; col++) { | |
380 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
381 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
382 encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; | |
383 encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; | |
384 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
385 encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5]; | |
386 encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6]; | |
387 encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7]; | |
388 pixel_ptr += 8; | |
389 } | |
390 } | |
391 break; | |
392 case IMGTYPE_YUV411: | |
393 for (row = 0; row < height; row++) { | |
394 pixel_ptr = row * width / 2 * 3; | |
395 yq = uq = vq =0; | |
396 for (col = 0; col < width/4; col++) { | |
397 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
398 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
399 encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; | |
400 encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; | |
401 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
402 encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; | |
403 pixel_ptr += 6; | |
404 } | |
405 } | |
406 break; | |
407 case IMGTYPE_YUV211: | |
408 for (row = 0; row < height; row++) { | |
409 pixel_ptr = row * width * 2; | |
410 yq = uq = vq =0; | |
411 for (col = 0; col < width/2; col++) { | |
412 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
413 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
414 encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2]; | |
415 encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3]; | |
416 pixel_ptr += 4; | |
417 } | |
418 } | |
419 break; | |
420 case IMGTYPE_YUV420: | |
421 for (row = 0; row < height/2; row++) { | |
422 pixel_ptr = row * width * 3; | |
423 yq = y1q = uq = vq =0; | |
424 for (col = 0; col < width/2; col++) { | |
425 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
426 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
427 encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2]; | |
428 encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3]; | |
429 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
430 encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; | |
431 pixel_ptr += 6; | |
432 } | |
433 } | |
434 break; | |
435 default: | |
436 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n"); | |
437 return -1; | |
438 } | |
439 } | |
440 | |
441 /* Convert colorspace */ | |
442 switch (c->imgtype) { | |
443 case IMGTYPE_YUV111: | |
444 for (row = height - 1; row >= 0; row--) { | |
445 pixel_ptr = row * c->pic.linesize[0]; | |
446 for (col = 0; col < width; col++) { | |
447 outptr[pixel_ptr++] = get_b(encoded[0], encoded[1]); | |
448 outptr[pixel_ptr++] = get_g(encoded[0], encoded[1], encoded[2]); | |
449 outptr[pixel_ptr++] = get_r(encoded[0], encoded[2]); | |
450 encoded += 3; | |
451 } | |
452 } | |
453 break; | |
454 case IMGTYPE_YUV422: | |
455 for (row = height - 1; row >= 0; row--) { | |
456 pixel_ptr = row * c->pic.linesize[0]; | |
457 for (col = 0; col < width/4; col++) { | |
458 outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); | |
459 outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[6]); | |
460 outptr[pixel_ptr++] = get_r(encoded[0], encoded[6]); | |
461 outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); | |
462 outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[6]); | |
463 outptr[pixel_ptr++] = get_r(encoded[1], encoded[6]); | |
464 outptr[pixel_ptr++] = get_b(encoded[2], encoded[5]); | |
465 outptr[pixel_ptr++] = get_g(encoded[2], encoded[5], encoded[7]); | |
466 outptr[pixel_ptr++] = get_r(encoded[2], encoded[7]); | |
467 outptr[pixel_ptr++] = get_b(encoded[3], encoded[5]); | |
468 outptr[pixel_ptr++] = get_g(encoded[3], encoded[5], encoded[7]); | |
469 outptr[pixel_ptr++] = get_r(encoded[3], encoded[7]); | |
470 encoded += 8; | |
471 } | |
472 } | |
473 break; | |
474 case IMGTYPE_RGB24: | |
475 for (row = height - 1; row >= 0; row--) { | |
476 pixel_ptr = row * c->pic.linesize[0]; | |
477 for (col = 0; col < width; col++) { | |
478 outptr[pixel_ptr++] = encoded[0]; | |
479 outptr[pixel_ptr++] = encoded[1]; | |
480 outptr[pixel_ptr++] = encoded[2]; | |
481 encoded += 3; | |
482 } | |
483 } | |
484 break; | |
485 case IMGTYPE_YUV411: | |
486 for (row = height - 1; row >= 0; row--) { | |
487 pixel_ptr = row * c->pic.linesize[0]; | |
488 for (col = 0; col < width/4; col++) { | |
489 outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); | |
490 outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[5]); | |
491 outptr[pixel_ptr++] = get_r(encoded[0], encoded[5]); | |
492 outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); | |
493 outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[5]); | |
494 outptr[pixel_ptr++] = get_r(encoded[1], encoded[5]); | |
495 outptr[pixel_ptr++] = get_b(encoded[2], encoded[4]); | |
496 outptr[pixel_ptr++] = get_g(encoded[2], encoded[4], encoded[5]); | |
497 outptr[pixel_ptr++] = get_r(encoded[2], encoded[5]); | |
498 outptr[pixel_ptr++] = get_b(encoded[3], encoded[4]); | |
499 outptr[pixel_ptr++] = get_g(encoded[3], encoded[4], encoded[5]); | |
500 outptr[pixel_ptr++] = get_r(encoded[3], encoded[5]); | |
501 encoded += 6; | |
502 } | |
503 } | |
504 break; | |
505 case IMGTYPE_YUV211: | |
506 for (row = height - 1; row >= 0; row--) { | |
507 pixel_ptr = row * c->pic.linesize[0]; | |
508 for (col = 0; col < width/2; col++) { | |
509 outptr[pixel_ptr++] = get_b(encoded[0], encoded[2]); | |
510 outptr[pixel_ptr++] = get_g(encoded[0], encoded[2], encoded[3]); | |
511 outptr[pixel_ptr++] = get_r(encoded[0], encoded[3]); | |
512 outptr[pixel_ptr++] = get_b(encoded[1], encoded[2]); | |
513 outptr[pixel_ptr++] = get_g(encoded[1], encoded[2], encoded[3]); | |
514 outptr[pixel_ptr++] = get_r(encoded[1], encoded[3]); | |
515 encoded += 4; | |
516 } | |
517 } | |
518 break; | |
519 case IMGTYPE_YUV420: | |
520 for (row = height / 2 - 1; row >= 0; row--) { | |
521 pixel_ptr = 2 * row * c->pic.linesize[0]; | |
522 for (col = 0; col < width/2; col++) { | |
523 outptr[pixel_ptr] = get_b(encoded[0], encoded[4]); | |
524 outptr[pixel_ptr+1] = get_g(encoded[0], encoded[4], encoded[5]); | |
525 outptr[pixel_ptr+2] = get_r(encoded[0], encoded[5]); | |
526 outptr[pixel_ptr+3] = get_b(encoded[1], encoded[4]); | |
527 outptr[pixel_ptr+4] = get_g(encoded[1], encoded[4], encoded[5]); | |
528 outptr[pixel_ptr+5] = get_r(encoded[1], encoded[5]); | |
529 outptr[pixel_ptr-c->pic.linesize[0]] = get_b(encoded[2], encoded[4]); | |
530 outptr[pixel_ptr-c->pic.linesize[0]+1] = get_g(encoded[2], encoded[4], encoded[5]); | |
531 outptr[pixel_ptr-c->pic.linesize[0]+2] = get_r(encoded[2], encoded[5]); | |
532 outptr[pixel_ptr-c->pic.linesize[0]+3] = get_b(encoded[3], encoded[4]); | |
533 outptr[pixel_ptr-c->pic.linesize[0]+4] = get_g(encoded[3], encoded[4], encoded[5]); | |
534 outptr[pixel_ptr-c->pic.linesize[0]+5] = get_r(encoded[3], encoded[5]); | |
535 pixel_ptr += 6; | |
536 encoded += 6; | |
537 } | |
538 } | |
539 break; | |
540 default: | |
541 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); | |
542 return -1; | |
543 } | |
544 | |
545 *data_size = sizeof(AVFrame); | |
546 *(AVFrame*)data = c->pic; | |
547 | |
548 /* always report that the buffer was completely consumed */ | |
549 return buf_size; | |
550 } | |
551 | |
552 | |
553 | |
554 /* | |
555 * | |
556 * Encode a frame | |
557 * | |
558 */ | |
559 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ | |
560 LclContext *c = avctx->priv_data; | |
561 AVFrame *pict = data; | |
562 AVFrame * const p = &c->pic; | |
563 int i; | |
564 int zret; // Zlib return code | |
565 | |
566 #ifndef CONFIG_ZLIB | |
567 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled in.\n"); | |
568 return -1; | |
569 #else | |
570 | |
571 init_put_bits(&c->pb, buf, buf_size); | |
572 | |
573 *p = *pict; | |
574 p->pict_type= FF_I_TYPE; | |
575 p->key_frame= 1; | |
576 | |
577 if(avctx->pix_fmt != PIX_FMT_BGR24){ | |
578 av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); | |
579 return -1; | |
580 } | |
581 | |
582 zret = deflateReset(&(c->zstream)); | |
583 if (zret != Z_OK) { | |
584 av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret); | |
585 return -1; | |
586 } | |
587 c->zstream.next_out = c->comp_buf; | |
588 c->zstream.avail_out = c->max_comp_size; | |
589 | |
2250
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
590 for(i = avctx->height - 1; i >= 0; i--) { |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
591 c->zstream.next_in = p->data[0]+p->linesize[0]*i; |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
592 c->zstream.avail_in = avctx->width*3; |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
593 zret = deflate(&(c->zstream), Z_NO_FLUSH); |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
594 if (zret != Z_OK) { |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
595 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
596 return -1; |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
597 } |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
598 } |
1743 | 599 zret = deflate(&(c->zstream), Z_FINISH); |
2250
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
600 if (zret != Z_STREAM_END) { |
1743 | 601 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); |
602 return -1; | |
603 } | |
604 | |
605 for (i = 0; i < c->zstream.total_out; i++) | |
606 put_bits(&c->pb, 8, c->comp_buf[i]); | |
607 flush_put_bits(&c->pb); | |
608 | |
609 return c->zstream.total_out; | |
610 #endif | |
611 } | |
612 | |
613 | |
614 | |
615 /* | |
616 * | |
617 * Init lcl decoder | |
618 * | |
619 */ | |
620 static int decode_init(AVCodecContext *avctx) | |
621 { | |
622 LclContext * const c = (LclContext *)avctx->priv_data; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
623 unsigned int basesize = avctx->width * avctx->height; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
624 unsigned int max_basesize = ((avctx->width + 3) & ~3) * ((avctx->height + 3) & ~3); |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
625 unsigned int max_decomp_size; |
1743 | 626 int zret; // Zlib return code |
627 | |
628 c->avctx = avctx; | |
629 avctx->has_b_frames = 0; | |
630 | |
631 c->pic.data[0] = NULL; | |
632 | |
633 #ifdef CONFIG_ZLIB | |
634 // Needed if zlib unused or init aborted before inflateInit | |
635 memset(&(c->zstream), 0, sizeof(z_stream)); | |
636 #endif | |
637 | |
638 if (avctx->extradata_size < 8) { | |
639 av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); | |
640 return 1; | |
641 } | |
642 | |
2429
4b350cc506a7
Use avcodec_check_dimensions instead of custom hack
rtognimp
parents:
2418
diff
changeset
|
643 if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
644 return 1; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
645 } |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
646 |
1743 | 647 /* Check codec type */ |
648 if (((avctx->codec_id == CODEC_ID_MSZH) && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) || | |
649 ((avctx->codec_id == CODEC_ID_ZLIB) && (*((char *)avctx->extradata + 7) != CODEC_ZLIB))) { | |
650 av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n"); | |
651 } | |
652 | |
653 /* Detect image type */ | |
654 switch (c->imgtype = *((char *)avctx->extradata + 4)) { | |
655 case IMGTYPE_YUV111: | |
656 c->decomp_size = basesize * 3; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
657 max_decomp_size = max_basesize * 3; |
1743 | 658 av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n"); |
659 break; | |
660 case IMGTYPE_YUV422: | |
661 c->decomp_size = basesize * 2; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
662 max_decomp_size = max_basesize * 2; |
1743 | 663 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n"); |
664 break; | |
665 case IMGTYPE_RGB24: | |
666 c->decomp_size = basesize * 3; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
667 max_decomp_size = max_basesize * 3; |
1743 | 668 av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n"); |
669 break; | |
670 case IMGTYPE_YUV411: | |
671 c->decomp_size = basesize / 2 * 3; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
672 max_decomp_size = max_basesize / 2 * 3; |
1743 | 673 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n"); |
674 break; | |
675 case IMGTYPE_YUV211: | |
676 c->decomp_size = basesize * 2; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
677 max_decomp_size = max_basesize * 2; |
1743 | 678 av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n"); |
679 break; | |
680 case IMGTYPE_YUV420: | |
681 c->decomp_size = basesize / 2 * 3; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
682 max_decomp_size = max_basesize / 2 * 3; |
1743 | 683 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n"); |
684 break; | |
685 default: | |
686 av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); | |
687 return 1; | |
688 } | |
689 | |
690 /* Detect compression method */ | |
691 c->compression = *((char *)avctx->extradata + 5); | |
692 switch (avctx->codec_id) { | |
693 case CODEC_ID_MSZH: | |
694 switch (c->compression) { | |
695 case COMP_MSZH: | |
696 av_log(avctx, AV_LOG_INFO, "Compression enabled.\n"); | |
697 break; | |
698 case COMP_MSZH_NOCOMP: | |
699 c->decomp_size = 0; | |
700 av_log(avctx, AV_LOG_INFO, "No compression.\n"); | |
701 break; | |
702 default: | |
703 av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); | |
704 return 1; | |
705 } | |
706 break; | |
707 case CODEC_ID_ZLIB: | |
708 #ifdef CONFIG_ZLIB | |
709 switch (c->compression) { | |
710 case COMP_ZLIB_HISPEED: | |
711 av_log(avctx, AV_LOG_INFO, "High speed compression.\n"); | |
712 break; | |
713 case COMP_ZLIB_HICOMP: | |
714 av_log(avctx, AV_LOG_INFO, "High compression.\n"); | |
715 break; | |
716 case COMP_ZLIB_NORMAL: | |
717 av_log(avctx, AV_LOG_INFO, "Normal compression.\n"); | |
718 break; | |
719 default: | |
720 if ((c->compression < Z_NO_COMPRESSION) || (c->compression > Z_BEST_COMPRESSION)) { | |
721 av_log(avctx, AV_LOG_ERROR, "Unusupported compression level for ZLIB: (%d).\n", c->compression); | |
722 return 1; | |
723 } | |
724 av_log(avctx, AV_LOG_INFO, "Compression level for ZLIB: (%d).\n", c->compression); | |
725 } | |
726 #else | |
727 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); | |
728 return 1; | |
729 #endif | |
730 break; | |
731 default: | |
732 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); | |
733 return 1; | |
734 } | |
735 | |
736 /* Allocate decompression buffer */ | |
737 if (c->decomp_size) { | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
738 if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { |
1743 | 739 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); |
740 return 1; | |
741 } | |
742 } | |
743 | |
744 /* Detect flags */ | |
745 c->flags = *((char *)avctx->extradata + 6); | |
746 if (c->flags & FLAG_MULTITHREAD) | |
747 av_log(avctx, AV_LOG_INFO, "Multithread encoder flag set.\n"); | |
748 if (c->flags & FLAG_NULLFRAME) | |
749 av_log(avctx, AV_LOG_INFO, "Nullframe insertion flag set.\n"); | |
750 if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) | |
751 av_log(avctx, AV_LOG_INFO, "PNG filter flag set.\n"); | |
752 if (c->flags & FLAGMASK_UNUSED) | |
753 av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags); | |
754 | |
755 /* If needed init zlib */ | |
756 if (avctx->codec_id == CODEC_ID_ZLIB) { | |
757 #ifdef CONFIG_ZLIB | |
758 c->zstream.zalloc = Z_NULL; | |
759 c->zstream.zfree = Z_NULL; | |
760 c->zstream.opaque = Z_NULL; | |
761 zret = inflateInit(&(c->zstream)); | |
762 if (zret != Z_OK) { | |
763 av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); | |
764 return 1; | |
765 } | |
766 #else | |
767 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); | |
768 return 1; | |
769 #endif | |
770 } | |
771 | |
772 avctx->pix_fmt = PIX_FMT_BGR24; | |
773 | |
774 return 0; | |
775 } | |
776 | |
777 | |
778 | |
779 /* | |
780 * | |
781 * Init lcl encoder | |
782 * | |
783 */ | |
784 static int encode_init(AVCodecContext *avctx) | |
785 { | |
786 LclContext *c = avctx->priv_data; | |
787 int zret; // Zlib return code | |
788 | |
789 #ifndef CONFIG_ZLIB | |
790 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); | |
791 return 1; | |
792 #else | |
793 | |
794 c->avctx= avctx; | |
795 | |
796 assert(avctx->width && avctx->height); | |
797 | |
798 avctx->extradata= av_mallocz(8); | |
799 avctx->coded_frame= &c->pic; | |
800 | |
801 // Will be user settable someday | |
802 c->compression = 6; | |
803 c->flags = 0; | |
804 | |
805 switch(avctx->pix_fmt){ | |
806 case PIX_FMT_BGR24: | |
807 c->imgtype = IMGTYPE_RGB24; | |
808 c->decomp_size = avctx->width * avctx->height * 3; | |
809 avctx->bits_per_sample= 24; | |
810 break; | |
811 default: | |
812 av_log(avctx, AV_LOG_ERROR, "Format %d not supported\n", avctx->pix_fmt); | |
813 return -1; | |
814 } | |
815 | |
816 ((uint8_t*)avctx->extradata)[0]= 4; | |
817 ((uint8_t*)avctx->extradata)[1]= 0; | |
818 ((uint8_t*)avctx->extradata)[2]= 0; | |
819 ((uint8_t*)avctx->extradata)[3]= 0; | |
820 ((uint8_t*)avctx->extradata)[4]= c->imgtype; | |
821 ((uint8_t*)avctx->extradata)[5]= c->compression; | |
822 ((uint8_t*)avctx->extradata)[6]= c->flags; | |
2250
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
823 ((uint8_t*)avctx->extradata)[7]= CODEC_ZLIB; |
1743 | 824 c->avctx->extradata_size= 8; |
825 | |
826 c->zstream.zalloc = Z_NULL; | |
827 c->zstream.zfree = Z_NULL; | |
828 c->zstream.opaque = Z_NULL; | |
829 zret = deflateInit(&(c->zstream), c->compression); | |
830 if (zret != Z_OK) { | |
831 av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret); | |
832 return 1; | |
833 } | |
834 | |
835 /* Conservative upper bound taken from zlib v1.2.1 source */ | |
836 c->max_comp_size = c->decomp_size + ((c->decomp_size + 7) >> 3) + | |
837 ((c->decomp_size + 63) >> 6) + 11; | |
838 if ((c->comp_buf = av_malloc(c->max_comp_size)) == NULL) { | |
839 av_log(avctx, AV_LOG_ERROR, "Can't allocate compression buffer.\n"); | |
840 return 1; | |
841 } | |
842 | |
843 return 0; | |
844 #endif | |
845 } | |
846 | |
847 | |
848 | |
849 | |
850 | |
851 /* | |
852 * | |
853 * Uninit lcl decoder | |
854 * | |
855 */ | |
856 static int decode_end(AVCodecContext *avctx) | |
857 { | |
858 LclContext * const c = (LclContext *)avctx->priv_data; | |
859 | |
860 if (c->pic.data[0]) | |
861 avctx->release_buffer(avctx, &c->pic); | |
862 #ifdef CONFIG_ZLIB | |
863 inflateEnd(&(c->zstream)); | |
864 #endif | |
865 | |
866 return 0; | |
867 } | |
868 | |
869 | |
870 | |
871 /* | |
872 * | |
873 * Uninit lcl encoder | |
874 * | |
875 */ | |
876 static int encode_end(AVCodecContext *avctx) | |
877 { | |
878 LclContext *c = avctx->priv_data; | |
879 | |
880 av_freep(&avctx->extradata); | |
2248
e4e1b4f31db6
segfault fix by (Kostya <cannonball at bw-team dot com>)
michael
parents:
1744
diff
changeset
|
881 av_freep(&c->comp_buf); |
1743 | 882 #ifdef CONFIG_ZLIB |
883 deflateEnd(&(c->zstream)); | |
884 #endif | |
885 | |
886 return 0; | |
887 } | |
888 | |
889 AVCodec mszh_decoder = { | |
890 "mszh", | |
891 CODEC_TYPE_VIDEO, | |
892 CODEC_ID_MSZH, | |
893 sizeof(LclContext), | |
894 decode_init, | |
895 NULL, | |
896 decode_end, | |
897 decode_frame, | |
898 CODEC_CAP_DR1, | |
899 }; | |
900 | |
901 | |
902 AVCodec zlib_decoder = { | |
903 "zlib", | |
904 CODEC_TYPE_VIDEO, | |
905 CODEC_ID_ZLIB, | |
906 sizeof(LclContext), | |
907 decode_init, | |
908 NULL, | |
909 decode_end, | |
910 decode_frame, | |
911 CODEC_CAP_DR1, | |
912 }; | |
913 | |
914 #ifdef CONFIG_ENCODERS | |
915 | |
916 AVCodec zlib_encoder = { | |
917 "zlib", | |
918 CODEC_TYPE_VIDEO, | |
919 CODEC_ID_ZLIB, | |
920 sizeof(LclContext), | |
921 encode_init, | |
922 encode_frame, | |
923 encode_end, | |
924 // .options = lcl_options, | |
925 }; | |
926 | |
927 #endif //CONFIG_ENCODERS |