comparison ffv1.c @ 1302:c41f51b5d5d6 libavcodec

reducing memory consumption (reducing number of contexts and other stuff, no noticeable loss in compression rate)
author michaelni
date Mon, 09 Jun 2003 23:55:16 +0000
parents e18667d1e94d
children 799839d1e2e1
comparison
equal deleted inserted replaced
1301:9d02a1859891 1302:c41f51b5d5d6
28 #include "avcodec.h" 28 #include "avcodec.h"
29 #include "dsputil.h" 29 #include "dsputil.h"
30 #include "cabac.h" 30 #include "cabac.h"
31 31
32 #define MAX_PLANES 4 32 #define MAX_PLANES 4
33 #define CONTEXT_SIZE 32
34
33 #if 0 35 #if 0
34 #define DEFAULT_QDIFF_COUNT (9) 36 #define DEFAULT_QDIFF_COUNT (9)
35 37
36 static const uint8_t default_quant_table[512]={ 38 static const uint8_t default_quant_table[512]={
37 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,
74 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 76 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, 77 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
76 }; 78 };
77 #endif 79 #endif
78 80
79 static const int to8[16]={ 81 static const int to5[16]={
80 0,1,1,1, 82 0,0,0,0,
81 1,2,2,3, 83 0,0,0,1,
82 4,5,6,6, 84 2,3,4,4,
83 7,7,7,7 85 4,4,4,4,
84 }; 86 };
85 87
86 typedef struct PlaneContext{ 88 typedef struct PlaneContext{
87 uint8_t quant_table[256]; 89 uint8_t quant_table[256];
88 int qdiff_count; 90 int qdiff_count;
89 int context_count; 91 int context_count;
90 uint8_t (*state)[64]; //FIXME 64 92 uint8_t (*state)[CONTEXT_SIZE];
91 uint8_t interlace_bit_state[2]; 93 uint8_t interlace_bit_state[2];
92 } PlaneContext; 94 } PlaneContext;
93 95
94 typedef struct FFV1Context{ 96 typedef struct FFV1Context{
95 AVCodecContext *avctx; 97 AVCodecContext *avctx;
160 else 162 else
161 return 1+get_cabac_ueg(c, state+2 , 32, 0, 4 , 32); 163 return 1+get_cabac_ueg(c, state+2 , 32, 0, 4 , 32);
162 } 164 }
163 } 165 }
164 #else 166 #else
167
165 /** 168 /**
166 * put 169 * put
167 */ 170 */
168 static inline void put_symbol(CABACContext *c, uint8_t *state, int v, int is_signed){ 171 static inline void put_symbol(CABACContext *c, uint8_t *state, int v, int is_signed){
169 int i; 172 int i;
170 #if 0 173
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){ 174 if(v){
187 const int a= ABS(v); 175 const int a= ABS(v);
188 const int e= av_log2(a); 176 const int e= av_log2(a);
189 177
190 put_cabac(c, state+0, 0); 178 put_cabac(c, state+0, 0);
191 put_cabac_u(c, state+1, e, 7, 6, 1); //1..7 179 put_cabac_u(c, state+1, e, 7, 6, 1); //1..7
192 if(e<7){ 180 if(e<7){
193 for(i=e-1; i>=0; i--){ 181 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}; 182 static const int offset[7]= {15+0, 15+0, 15+1, 15+3, 15+6, 15+10, 15+11};
195 // put_cabac(c, state+14+e-i, (a>>i)&1); //14..20 183 put_cabac(c, state+offset[e]+i, (a>>i)&1); //15..31
196 put_cabac(c, state+offset[e]+i, (a>>i)&1); //14..34
197 } 184 }
198
199 if(is_signed) 185 if(is_signed)
200 put_cabac(c, state+8 + e, v < 0); //8..14 186 put_cabac(c, state+8 + e, v < 0); //8..14
201 } 187 }
202 }else{ 188 }else{
203 put_cabac(c, state+0, 1); 189 put_cabac(c, state+0, 1);
204 } 190 }
205 #endif
206 } 191 }
207 192
208 static inline int get_symbol(CABACContext *c, uint8_t *state, int is_signed){ 193 static inline int get_symbol(CABACContext *c, uint8_t *state, int is_signed){
209 int i; 194 int i;
210 195
215 200
216 if(e<7){ 201 if(e<7){
217 int a= 1<<e; 202 int a= 1<<e;
218 203
219 for(i=e-1; i>=0; i--){ 204 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}; 205 static const int offset[7]= {15+0, 15+0, 15+1, 15+3, 15+6, 15+10, 15+11};
221 a += get_cabac(c, state+offset[e]+i)<<i; //14..34 206 a += get_cabac(c, state+offset[e]+i)<<i; //14..31
222 } 207 }
223 208
224 if(is_signed && get_cabac(c, state+8 + e)) //8..14 209 if(is_signed && get_cabac(c, state+8 + e)) //8..14
225 return -a; 210 return -a;
226 else 211 else
255 240
256 if(p->context_count == 256) 241 if(p->context_count == 256)
257 context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0]; 242 context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0];
258 else 243 else
259 context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0] 244 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]]; 245 + 16*16*to5[pred_diff[3-1][x+1]] + 16*16*5*to5[pred_diff[3-0][x-2]] + 16*16*5*5*to5[pred_diff[3-2][x+0]];
261 246
262 diff = (int8_t)(temp_src[0] - predict(s, temp_src, stride, x, y)); 247 diff = (int8_t)(temp_src[0] - predict(s, temp_src, stride, x, y));
263 248
264 qdiff= p->quant_table[128+diff]; 249 qdiff= p->quant_table[128+diff];
265 250
266 put_symbol(c, p->state[context], diff, 1); 251 put_symbol(c, p->state[context], diff, 1);
267 252
268 pred_diff[3][x]= qdiff; 253 pred_diff[3][x]= qdiff;
269 } 254 }
270 } 255 }
271 } 256 }
272 257
273 static void write_quant_table(CABACContext *c, uint8_t *quant_table){ 258 static void write_quant_table(CABACContext *c, uint8_t *quant_table){
274 int last=0; 259 int last=0;
275 int i; 260 int i;
276 uint8_t state[64]={0}; 261 uint8_t state[CONTEXT_SIZE]={0};
277 262
278 for(i=1; i<256 ; i++){ 263 for(i=1; i<256 ; i++){
279 if(quant_table[i] != quant_table[i-1]){ 264 if(quant_table[i] != quant_table[i-1]){
280 put_symbol(c, state, i-last-1, 0); 265 put_symbol(c, state, i-last-1, 0);
281 last= i; 266 last= i;
283 } 268 }
284 put_symbol(c, state, i-last-1, 0); 269 put_symbol(c, state, i-last-1, 0);
285 } 270 }
286 271
287 static void write_header(FFV1Context *f){ 272 static void write_header(FFV1Context *f){
288 uint8_t state[64]={0}; 273 uint8_t state[CONTEXT_SIZE]={0};
289 int i; 274 int i;
290 CABACContext * const c= &f->c; 275 CABACContext * const c= &f->c;
291 276
292 put_symbol(c, state, f->version, 0); 277 put_symbol(c, state, f->version, 0);
293 put_symbol(c, state, 0, 0); //YUV cs type 278 put_symbol(c, state, 0, 0); //YUV cs type
304 } 289 }
305 } 290 }
306 291
307 static int common_init(AVCodecContext *avctx){ 292 static int common_init(AVCodecContext *avctx){
308 FFV1Context *s = avctx->priv_data; 293 FFV1Context *s = avctx->priv_data;
309 int i, j, width, height; 294 int width, height;
310 295
311 s->avctx= avctx; 296 s->avctx= avctx;
312 s->flags= avctx->flags; 297 s->flags= avctx->flags;
313 298
314 dsputil_init(&s->dsp, avctx); 299 dsputil_init(&s->dsp, avctx);
315 300
316 width= s->width= avctx->width; 301 width= s->width= avctx->width;
317 height= s->height= avctx->height; 302 height= s->height= avctx->height;
318 303
319 assert(width && height); 304 assert(width && height);
320
321 for(i=0; i<s->plane_count; i++){
322 PlaneContext *p= &s->plane[i];
323 }
324 305
325 return 0; 306 return 0;
326 } 307 }
327 308
328 static int encode_init(AVCodecContext *avctx) 309 static int encode_init(AVCodecContext *avctx)
341 memcpy(p->quant_table, default_quant_table, sizeof(uint8_t)*256); 322 memcpy(p->quant_table, default_quant_table, sizeof(uint8_t)*256);
342 p->qdiff_count= DEFAULT_QDIFF_COUNT; 323 p->qdiff_count= DEFAULT_QDIFF_COUNT;
343 324
344 #if 1 325 #if 1
345 p->context_count= 256; 326 p->context_count= 256;
346 p->state= av_malloc(64*p->context_count*sizeof(uint8_t)); 327 p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
347 #else 328 #else
348 p->context_count= 16*16*8*8*8; //256*16; 329 p->context_count= 16*16*128 /*5*5*5*/;
349 p->state= av_malloc(64*p->context_count*sizeof(uint8_t)); 330 p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
350 #endif 331 #endif
351 } 332 }
352 333
353 avctx->coded_frame= &s->picture; 334 avctx->coded_frame= &s->picture;
354 switch(avctx->pix_fmt){ 335 switch(avctx->pix_fmt){
370 return 0; 351 return 0;
371 } 352 }
372 353
373 354
374 static void clear_state(FFV1Context *f){ 355 static void clear_state(FFV1Context *f){
375 int i; 356 int i, j;
376 357
377 for(i=0; i<f->plane_count; i++){ 358 for(i=0; i<f->plane_count; i++){
378 PlaneContext *p= &f->plane[i]; 359 PlaneContext *p= &f->plane[i];
379 360
380 p->interlace_bit_state[0]= 0; 361 p->interlace_bit_state[0]= 0;
381 p->interlace_bit_state[1]= 0; 362 p->interlace_bit_state[1]= 0;
382 363
383 memset(p->state, 0, p->context_count*sizeof(uint8_t)*64); 364 for(j=0; j<p->context_count; j++){
365 memset(p->state[j], 0, sizeof(uint8_t)*CONTEXT_SIZE);
366 p->state[j][7] = 2*62;
367 }
384 } 368 }
385 } 369 }
386 370
387 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ 371 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
388 FFV1Context *f = avctx->priv_data; 372 FFV1Context *f = avctx->priv_data;
473 457
474 if(p->context_count == 256) 458 if(p->context_count == 256)
475 context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0]; 459 context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0];
476 else 460 else
477 context= pred_diff[3+0][x-1] + 16*pred_diff[3-1][x+0] 461 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]]; 462 + 16*16*to5[pred_diff[3-1][x+1]] + 16*16*5*to5[pred_diff[3-0][x-2]] + 16*16*5*5*to5[pred_diff[3-2][x+0]];
479 463
480 diff= get_symbol(c, p->state[context], 1); 464 diff= get_symbol(c, p->state[context], 1);
481 465
482 temp_src[0] = predict(s, temp_src, stride, x, y) + diff; 466 temp_src[0] = predict(s, temp_src, stride, x, y) + diff;
483 467
491 } 475 }
492 476
493 static int read_quant_table(CABACContext *c, uint8_t *quant_table){ 477 static int read_quant_table(CABACContext *c, uint8_t *quant_table){
494 int v; 478 int v;
495 int i=0; 479 int i=0;
496 uint8_t state[64]={0}; 480 uint8_t state[CONTEXT_SIZE]={0};
497 481
498 for(v=0; i<256 ; v++){ 482 for(v=0; i<256 ; v++){
499 int len= get_symbol(c, state, 0) + 1; 483 int len= get_symbol(c, state, 0) + 1;
500 484
501 if(len + i > 256) return -1; 485 if(len + i > 256) return -1;
509 493
510 return v; 494 return v;
511 } 495 }
512 496
513 static int read_header(FFV1Context *f){ 497 static int read_header(FFV1Context *f){
514 uint8_t state[64]={0}; 498 uint8_t state[CONTEXT_SIZE]={0};
515 int i; 499 int i;
516 CABACContext * const c= &f->c; 500 CABACContext * const c= &f->c;
517 501
518 f->version= get_symbol(c, state, 0); 502 f->version= get_symbol(c, state, 0);
519 get_symbol(c, state, 0); //YUV cs type 503 get_symbol(c, state, 0); //YUV cs type
529 p->context_count= 1<<get_symbol(c, state, 0); 513 p->context_count= 1<<get_symbol(c, state, 0);
530 p->qdiff_count= read_quant_table(c, p->quant_table); 514 p->qdiff_count= read_quant_table(c, p->quant_table);
531 if(p->qdiff_count < 0) return -1; 515 if(p->qdiff_count < 0) return -1;
532 516
533 if(!p->state) 517 if(!p->state)
534 p->state= av_malloc(64*p->context_count*sizeof(uint8_t)); 518 p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
535 } 519 }
536 520
537 return 0; 521 return 0;
538 } 522 }
539 523
652 sizeof(FFV1Context), 636 sizeof(FFV1Context),
653 decode_init, 637 decode_init,
654 NULL, 638 NULL,
655 decode_end, 639 decode_end,
656 decode_frame, 640 decode_frame,
657 /*CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND*/ 0, 641 CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
658 NULL 642 NULL
659 }; 643 };
660 644
661 AVCodec ffv1_encoder = { 645 AVCodec ffv1_encoder = {
662 "ffv1", 646 "ffv1",