Mercurial > libavcodec.hg
comparison ffv1.c @ 1300:e18667d1e94d libavcodec
FFV1 codec (our very simple lossless intra only codec, compresses much better then huffyuv)
author | michaelni |
---|---|
date | Mon, 09 Jun 2003 02:24:51 +0000 |
parents | |
children | c41f51b5d5d6 |
comparison
equal
deleted
inserted
replaced
1299:9c3bfa79631f | 1300:e18667d1e94d |
---|---|
1 /* | |
2 * FFV1 codec for libavcodec | |
3 * | |
4 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> | |
5 * | |
6 * This library is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2 of the License, or (at your option) any later version. | |
10 * | |
11 * This library is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with this library; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 | |
22 /** | |
23 * @file ffv1.c | |
24 * FF Video Codec 1 (a experimental lossless codec) | |
25 */ | |
26 | |
27 #include "common.h" | |
28 #include "avcodec.h" | |
29 #include "dsputil.h" | |
30 #include "cabac.h" | |
31 | |
32 #define MAX_PLANES 4 | |
33 #if 0 | |
34 #define DEFAULT_QDIFF_COUNT (9) | |
35 | |
36 static const uint8_t default_quant_table[512]={ | |
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
44 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, | |
45 4, | |
46 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, | |
47 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | |
48 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | |
49 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | |
50 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | |
51 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | |
52 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | |
53 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | |
54 }; | |
55 #else | |
56 #define DEFAULT_QDIFF_COUNT (16) | |
57 | |
58 static const uint8_t default_quant_table[256]={ | |
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
63 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
64 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
65 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
66 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, | |
67 8, | |
68 9,10,11,11,12,12,12,12,13,13,13,13,13,13,13,13, | |
69 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, | |
70 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, | |
71 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, | |
72 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, | |
73 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, | |
74 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, | |
75 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, | |
76 }; | |
77 #endif | |
78 | |
79 static const int to8[16]={ | |
80 0,1,1,1, | |
81 1,2,2,3, | |
82 4,5,6,6, | |
83 7,7,7,7 | |
84 }; | |
85 | |
86 typedef struct PlaneContext{ | |
87 uint8_t quant_table[256]; | |
88 int qdiff_count; | |
89 int context_count; | |
90 uint8_t (*state)[64]; //FIXME 64 | |
91 uint8_t interlace_bit_state[2]; | |
92 } PlaneContext; | |
93 | |
94 typedef struct FFV1Context{ | |
95 AVCodecContext *avctx; | |
96 CABACContext c; | |
97 int version; | |
98 int width, height; | |
99 int chroma_h_shift, chroma_v_shift; | |
100 int flags; | |
101 int picture_number; | |
102 AVFrame picture; | |
103 int plane_count; | |
104 PlaneContext plane[MAX_PLANES]; | |
105 | |
106 DSPContext dsp; | |
107 }FFV1Context; | |
108 | |
109 //1.774215 | |
110 static inline int predict(FFV1Context *s, uint8_t *src, int stride, int x, int y){ | |
111 if(x && y){ | |
112 // const int RT= src[+1-stride]; | |
113 const int LT= src[-1-stride]; | |
114 const int T= src[ -stride]; | |
115 const int L = src[-1 ]; | |
116 uint8_t *cm = cropTbl + MAX_NEG_CROP; | |
117 const int gradient= cm[L + T - LT]; | |
118 | |
119 // return gradient; | |
120 return mid_pred(L, gradient, T); | |
121 }else{ | |
122 if(y){ | |
123 return src[ -stride]; | |
124 }else if(x){ | |
125 return src[-1 ]; | |
126 }else{ | |
127 return 128; | |
128 } | |
129 } | |
130 } | |
131 | |
132 | |
133 #if 0 | |
134 static inline void put_symbol(CABACContext, uint8_t *state, int v){ | |
135 put_cabac_ueg(c, state, v, 32, 1, 4 , 32); | |
136 } | |
137 | |
138 static inline int get_symbol(CABACContext, uint8_t *state){ | |
139 return get_cabac_ueg(c, state, 32, 1, 4 , 32); | |
140 } | |
141 #elif 0 | |
142 static inline void put_symbol(CABACContext *c, uint8_t *state, int v){ | |
143 if(v==0) | |
144 put_cabac(c, state+0, 1); | |
145 else{ | |
146 put_cabac(c, state+0, 0); | |
147 put_cabac(c, state+1, v<0); | |
148 if(v<0) state += 64; | |
149 put_cabac_ueg(c, state+2, ABS(v)-1, 32, 0, 4 , 32); | |
150 } | |
151 } | |
152 | |
153 static inline int get_symbol(CABACContext *c, uint8_t *state){ | |
154 if(get_cabac(c, state+0)) | |
155 return 0; | |
156 else{ | |
157 int sign= get_cabac(c, state+1); | |
158 if(sign) | |
159 return -1-get_cabac_ueg(c, state+66, 32, 0, 4 , 32); | |
160 else | |
161 return 1+get_cabac_ueg(c, state+2 , 32, 0, 4 , 32); | |
162 } | |
163 } | |
164 #else | |
165 /** | |
166 * put | |
167 */ | |
168 static inline void put_symbol(CABACContext *c, uint8_t *state, int v, int is_signed){ | |
169 int i; | |
170 #if 0 | |
171 const int a= ABS(v); | |
172 const int e= av_log2(a+1); | |
173 | |
174 put_cabac_u(c, state+0, e, 7, 6, 1); //0..6 | |
175 if(e){ | |
176 put_cabac(c, state+6 + e, v < 0); //7..13 | |
177 | |
178 for(i=; i<e; i++){ | |
179 | |
180 } | |
181 } | |
182 #else | |
183 // 0 1 2 3 4 5 6 | |
184 // 0 1 2 3 4 5 6 | |
185 // 0 0 1 3 6 10 15 21 | |
186 if(v){ | |
187 const int a= ABS(v); | |
188 const int e= av_log2(a); | |
189 | |
190 put_cabac(c, state+0, 0); | |
191 put_cabac_u(c, state+1, e, 7, 6, 1); //1..7 | |
192 if(e<7){ | |
193 for(i=e-1; i>=0; i--){ | |
194 static const int offset[7]= {14+0, 14+0, 14+1, 14+3, 14+6, 14+10, 14+15}; | |
195 // put_cabac(c, state+14+e-i, (a>>i)&1); //14..20 | |
196 put_cabac(c, state+offset[e]+i, (a>>i)&1); //14..34 | |
197 } | |
198 | |
199 if(is_signed) | |
200 put_cabac(c, state+8 + e, v < 0); //8..14 | |
201 } | |
202 }else{ | |
203 put_cabac(c, state+0, 1); | |
204 } | |
205 #endif | |
206 } | |
207 | |
208 static inline int get_symbol(CABACContext *c, uint8_t *state, int is_signed){ | |
209 int i; | |
210 | |
211 if(get_cabac(c, state+0)) | |
212 return 0; | |
213 else{ | |
214 const int e= get_cabac_u(c, state+1, 7, 6, 1); //1..7 | |
215 | |
216 if(e<7){ | |
217 int a= 1<<e; | |
218 | |
219 for(i=e-1; i>=0; i--){ | |
220 static const int offset[7]= {14+0, 14+0, 14+1, 14+3, 14+6, 14+10, 14+15}; | |
221 a += get_cabac(c, state+offset[e]+i)<<i; //14..34 | |
222 } | |
223 | |
224 if(is_signed && get_cabac(c, state+8 + e)) //8..14 | |
225 return -a; | |
226 else | |
227 return a; | |
228 }else | |
229 return -128; | |
230 } | |
231 } | |
232 #endif | |
233 | |
234 static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ | |
235 PlaneContext * const p= &s->plane[plane_index]; | |
236 CABACContext * const c= &s->c; | |
237 int x,y; | |
238 uint8_t pred_diff_buffer[4][w+6]; | |
239 uint8_t *pred_diff[4]= {pred_diff_buffer[0]+3, pred_diff_buffer[1]+3, pred_diff_buffer[2]+3, pred_diff_buffer[3]+3}; | |
240 // uint8_t temp_buf[3*w], *temp= temp_buf + 3*w; | |
241 | |
242 memset(pred_diff_buffer, 0, sizeof(pred_diff_buffer)); | |
243 | |
244 for(y=0; y<h; y++){ | |
245 uint8_t *temp= pred_diff[0]; //FIXME try a normal buffer | |
246 | |
247 pred_diff[0]= pred_diff[1]; | |
248 pred_diff[1]= pred_diff[2]; | |
249 pred_diff[2]= pred_diff[3]; | |
250 pred_diff[3]= temp; | |
251 | |
252 for(x=0; x<w; x++){ | |
253 uint8_t *temp_src= src + x + stride*y; | |
254 int diff, context, qdiff; | |
255 | |
256 if(p->context_count == 256) | |
257 context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0]; | |
258 else | |
259 context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0] | |
260 + 16*16*to8[pred_diff[3-1][x+1]] + 16*16*8*to8[pred_diff[3-0][x-2]] + 16*16*8*8*to8[pred_diff[3-2][x+0]]; | |
261 | |
262 diff = (int8_t)(temp_src[0] - predict(s, temp_src, stride, x, y)); | |
263 | |
264 qdiff= p->quant_table[128+diff]; | |
265 | |
266 put_symbol(c, p->state[context], diff, 1); | |
267 | |
268 pred_diff[3][x]= qdiff; | |
269 } | |
270 } | |
271 } | |
272 | |
273 static void write_quant_table(CABACContext *c, uint8_t *quant_table){ | |
274 int last=0; | |
275 int i; | |
276 uint8_t state[64]={0}; | |
277 | |
278 for(i=1; i<256 ; i++){ | |
279 if(quant_table[i] != quant_table[i-1]){ | |
280 put_symbol(c, state, i-last-1, 0); | |
281 last= i; | |
282 } | |
283 } | |
284 put_symbol(c, state, i-last-1, 0); | |
285 } | |
286 | |
287 static void write_header(FFV1Context *f){ | |
288 uint8_t state[64]={0}; | |
289 int i; | |
290 CABACContext * const c= &f->c; | |
291 | |
292 put_symbol(c, state, f->version, 0); | |
293 put_symbol(c, state, 0, 0); //YUV cs type | |
294 put_cabac(c, state, 1); //chroma planes | |
295 put_symbol(c, state, f->chroma_h_shift, 0); | |
296 put_symbol(c, state, f->chroma_v_shift, 0); | |
297 put_cabac(c, state, 0); //no transparency plane | |
298 | |
299 for(i=0; i<3; i++){ //FIXME chroma & trasparency decission | |
300 PlaneContext * const p= &f->plane[i]; | |
301 | |
302 put_symbol(c, state, av_log2(p->context_count), 0); | |
303 write_quant_table(c, p->quant_table); | |
304 } | |
305 } | |
306 | |
307 static int common_init(AVCodecContext *avctx){ | |
308 FFV1Context *s = avctx->priv_data; | |
309 int i, j, width, height; | |
310 | |
311 s->avctx= avctx; | |
312 s->flags= avctx->flags; | |
313 | |
314 dsputil_init(&s->dsp, avctx); | |
315 | |
316 width= s->width= avctx->width; | |
317 height= s->height= avctx->height; | |
318 | |
319 assert(width && height); | |
320 | |
321 for(i=0; i<s->plane_count; i++){ | |
322 PlaneContext *p= &s->plane[i]; | |
323 } | |
324 | |
325 return 0; | |
326 } | |
327 | |
328 static int encode_init(AVCodecContext *avctx) | |
329 { | |
330 FFV1Context *s = avctx->priv_data; | |
331 int i; | |
332 | |
333 common_init(avctx); | |
334 | |
335 s->version=0; | |
336 | |
337 s->plane_count=3; | |
338 | |
339 for(i=0; i<s->plane_count; i++){ | |
340 PlaneContext * const p= &s->plane[i]; | |
341 memcpy(p->quant_table, default_quant_table, sizeof(uint8_t)*256); | |
342 p->qdiff_count= DEFAULT_QDIFF_COUNT; | |
343 | |
344 #if 1 | |
345 p->context_count= 256; | |
346 p->state= av_malloc(64*p->context_count*sizeof(uint8_t)); | |
347 #else | |
348 p->context_count= 16*16*8*8*8; //256*16; | |
349 p->state= av_malloc(64*p->context_count*sizeof(uint8_t)); | |
350 #endif | |
351 } | |
352 | |
353 avctx->coded_frame= &s->picture; | |
354 switch(avctx->pix_fmt){ | |
355 case PIX_FMT_YUV444P: | |
356 case PIX_FMT_YUV422P: | |
357 case PIX_FMT_YUV420P: | |
358 case PIX_FMT_YUV411P: | |
359 case PIX_FMT_YUV410P: | |
360 avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); | |
361 break; | |
362 default: | |
363 fprintf(stderr, "format not supported\n"); | |
364 return -1; | |
365 } | |
366 | |
367 | |
368 s->picture_number=0; | |
369 | |
370 return 0; | |
371 } | |
372 | |
373 | |
374 static void clear_state(FFV1Context *f){ | |
375 int i; | |
376 | |
377 for(i=0; i<f->plane_count; i++){ | |
378 PlaneContext *p= &f->plane[i]; | |
379 | |
380 p->interlace_bit_state[0]= 0; | |
381 p->interlace_bit_state[1]= 0; | |
382 | |
383 memset(p->state, 0, p->context_count*sizeof(uint8_t)*64); | |
384 } | |
385 } | |
386 | |
387 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ | |
388 FFV1Context *f = avctx->priv_data; | |
389 CABACContext * const c= &f->c; | |
390 AVFrame *pict = data; | |
391 const int width= f->width; | |
392 const int height= f->height; | |
393 AVFrame * const p= &f->picture; | |
394 | |
395 if(avctx->strict_std_compliance >= 0){ | |
396 printf("this codec is under development, files encoded with it wont be decodeable with future versions!!!\n" | |
397 "use vstrict=-1 to use it anyway\n"); | |
398 return -1; | |
399 } | |
400 | |
401 ff_init_cabac_encoder(c, buf, buf_size); | |
402 ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); | |
403 | |
404 *p = *pict; | |
405 p->pict_type= FF_I_TYPE; | |
406 | |
407 if(avctx->gop_size==0 || f->picture_number % avctx->gop_size == 0){ | |
408 put_cabac_bypass(c, 1); | |
409 p->key_frame= 1; | |
410 write_header(f); | |
411 clear_state(f); | |
412 }else{ | |
413 put_cabac_bypass(c, 0); | |
414 p->key_frame= 0; | |
415 } | |
416 | |
417 if(1){ | |
418 const int chroma_width = -((-width )>>f->chroma_h_shift); | |
419 const int chroma_height= -((-height)>>f->chroma_v_shift); | |
420 | |
421 encode_plane(f, p->data[0], width, height, p->linesize[0], 0); | |
422 | |
423 encode_plane(f, p->data[1], chroma_width, chroma_height, p->linesize[1], 1); | |
424 encode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 2); | |
425 } | |
426 emms_c(); | |
427 | |
428 f->picture_number++; | |
429 | |
430 return put_cabac_terminate(c, 1); | |
431 } | |
432 | |
433 static void common_end(FFV1Context *s){ | |
434 int i; | |
435 | |
436 for(i=0; i<s->plane_count; i++){ | |
437 PlaneContext *p= &s->plane[i]; | |
438 | |
439 av_freep(&p->state); | |
440 } | |
441 } | |
442 | |
443 static int encode_end(AVCodecContext *avctx) | |
444 { | |
445 FFV1Context *s = avctx->priv_data; | |
446 | |
447 common_end(s); | |
448 | |
449 return 0; | |
450 } | |
451 | |
452 static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ | |
453 PlaneContext * const p= &s->plane[plane_index]; | |
454 CABACContext * const c= &s->c; | |
455 int x,y; | |
456 uint8_t pred_diff_buffer[4][w+6]; | |
457 uint8_t *pred_diff[4]= {pred_diff_buffer[0]+3, pred_diff_buffer[1]+3, pred_diff_buffer[2]+3, pred_diff_buffer[3]+3}; | |
458 // uint8_t temp_buf[3*w], *temp= temp_buf + 3*w; | |
459 | |
460 memset(pred_diff_buffer, 0, sizeof(pred_diff_buffer)); | |
461 | |
462 for(y=0; y<h; y++){ | |
463 uint8_t *temp= pred_diff[0]; //FIXME try a normal buffer | |
464 | |
465 pred_diff[0]= pred_diff[1]; | |
466 pred_diff[1]= pred_diff[2]; | |
467 pred_diff[2]= pred_diff[3]; | |
468 pred_diff[3]= temp; | |
469 | |
470 for(x=0; x<w; x++){ | |
471 uint8_t *temp_src= src + x + stride*y; | |
472 int diff, context, qdiff; | |
473 | |
474 if(p->context_count == 256) | |
475 context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0]; | |
476 else | |
477 context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0] | |
478 + 16*16*to8[pred_diff[3-1][x+1]] + 16*16*8*to8[pred_diff[3-0][x-2]] + 16*16*8*8*to8[pred_diff[3-2][x+0]]; | |
479 | |
480 diff= get_symbol(c, p->state[context], 1); | |
481 | |
482 temp_src[0] = predict(s, temp_src, stride, x, y) + diff; | |
483 | |
484 assert(diff>= -128 && diff <= 127); | |
485 | |
486 qdiff= p->quant_table[128+diff]; | |
487 | |
488 pred_diff[3][x]= qdiff; | |
489 } | |
490 } | |
491 } | |
492 | |
493 static int read_quant_table(CABACContext *c, uint8_t *quant_table){ | |
494 int v; | |
495 int i=0; | |
496 uint8_t state[64]={0}; | |
497 | |
498 for(v=0; i<256 ; v++){ | |
499 int len= get_symbol(c, state, 0) + 1; | |
500 | |
501 if(len + i > 256) return -1; | |
502 | |
503 while(len--){ | |
504 quant_table[i++] = v; | |
505 //printf("%2d ",v); | |
506 //if(i%16==0) printf("\n"); | |
507 } | |
508 } | |
509 | |
510 return v; | |
511 } | |
512 | |
513 static int read_header(FFV1Context *f){ | |
514 uint8_t state[64]={0}; | |
515 int i; | |
516 CABACContext * const c= &f->c; | |
517 | |
518 f->version= get_symbol(c, state, 0); | |
519 get_symbol(c, state, 0); //YUV cs type | |
520 get_cabac(c, state); //no chroma = false | |
521 f->chroma_h_shift= get_symbol(c, state, 0); | |
522 f->chroma_v_shift= get_symbol(c, state, 0); | |
523 get_cabac(c, state); //transparency plane | |
524 f->plane_count= 3; | |
525 | |
526 for(i=0; i<f->plane_count; i++){ | |
527 PlaneContext * const p= &f->plane[i]; | |
528 | |
529 p->context_count= 1<<get_symbol(c, state, 0); | |
530 p->qdiff_count= read_quant_table(c, p->quant_table); | |
531 if(p->qdiff_count < 0) return -1; | |
532 | |
533 if(!p->state) | |
534 p->state= av_malloc(64*p->context_count*sizeof(uint8_t)); | |
535 } | |
536 | |
537 return 0; | |
538 } | |
539 | |
540 static int decode_init(AVCodecContext *avctx) | |
541 { | |
542 FFV1Context *s = avctx->priv_data; | |
543 | |
544 common_init(avctx); | |
545 | |
546 #if 0 | |
547 switch(s->bitstream_bpp){ | |
548 case 12: | |
549 avctx->pix_fmt = PIX_FMT_YUV420P; | |
550 break; | |
551 case 16: | |
552 avctx->pix_fmt = PIX_FMT_YUV422P; | |
553 break; | |
554 case 24: | |
555 case 32: | |
556 if(s->bgr32){ | |
557 avctx->pix_fmt = PIX_FMT_RGBA32; | |
558 }else{ | |
559 avctx->pix_fmt = PIX_FMT_BGR24; | |
560 } | |
561 break; | |
562 default: | |
563 assert(0); | |
564 } | |
565 #endif | |
566 | |
567 return 0; | |
568 } | |
569 | |
570 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){ | |
571 FFV1Context *f = avctx->priv_data; | |
572 CABACContext * const c= &f->c; | |
573 const int width= f->width; | |
574 const int height= f->height; | |
575 AVFrame * const p= &f->picture; | |
576 int bytes_read; | |
577 | |
578 AVFrame *picture = data; | |
579 | |
580 *data_size = 0; | |
581 | |
582 /* no supplementary picture */ | |
583 if (buf_size == 0) | |
584 return 0; | |
585 | |
586 ff_init_cabac_decoder(c, buf, buf_size); | |
587 ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); | |
588 | |
589 p->reference= 0; | |
590 if(avctx->get_buffer(avctx, p) < 0){ | |
591 fprintf(stderr, "get_buffer() failed\n"); | |
592 return -1; | |
593 } | |
594 | |
595 p->pict_type= FF_I_TYPE; //FIXME I vs. P | |
596 if(get_cabac_bypass(c)){ | |
597 p->key_frame= 1; | |
598 read_header(f); | |
599 clear_state(f); | |
600 }else{ | |
601 p->key_frame= 0; | |
602 } | |
603 if(avctx->debug&FF_DEBUG_PICT_INFO) | |
604 printf("keyframe:%d\n", p->key_frame); | |
605 | |
606 | |
607 if(1){ | |
608 const int chroma_width = -((-width )>>f->chroma_h_shift); | |
609 const int chroma_height= -((-height)>>f->chroma_v_shift); | |
610 decode_plane(f, p->data[0], width, height, p->linesize[0], 0); | |
611 | |
612 decode_plane(f, p->data[1], chroma_width, chroma_height, p->linesize[1], 1); | |
613 decode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 2); | |
614 } | |
615 | |
616 emms_c(); | |
617 | |
618 f->picture_number++; | |
619 | |
620 *picture= *p; | |
621 | |
622 avctx->release_buffer(avctx, p); //FIXME | |
623 | |
624 *data_size = sizeof(AVFrame); | |
625 | |
626 bytes_read= get_cabac_terminate(c); | |
627 if(bytes_read ==0) printf("error at end of frame\n"); | |
628 | |
629 return bytes_read; | |
630 } | |
631 | |
632 static int decode_end(AVCodecContext *avctx) | |
633 { | |
634 FFV1Context *s = avctx->priv_data; | |
635 int i; | |
636 | |
637 if(avctx->get_buffer == avcodec_default_get_buffer){ | |
638 for(i=0; i<4; i++){ | |
639 av_freep(&s->picture.base[i]); | |
640 s->picture.data[i]= NULL; | |
641 } | |
642 av_freep(&s->picture.opaque); | |
643 } | |
644 | |
645 return 0; | |
646 } | |
647 | |
648 AVCodec ffv1_decoder = { | |
649 "ffv1", | |
650 CODEC_TYPE_VIDEO, | |
651 CODEC_ID_FFV1, | |
652 sizeof(FFV1Context), | |
653 decode_init, | |
654 NULL, | |
655 decode_end, | |
656 decode_frame, | |
657 /*CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND*/ 0, | |
658 NULL | |
659 }; | |
660 | |
661 AVCodec ffv1_encoder = { | |
662 "ffv1", | |
663 CODEC_TYPE_VIDEO, | |
664 CODEC_ID_FFV1, | |
665 sizeof(FFV1Context), | |
666 encode_init, | |
667 encode_frame, | |
668 encode_end, | |
669 }; |