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 };