comparison ffv1.c @ 1336:c16ac5b7ac79 libavcodec

20% less memory needed for 8bit AC state (worst compression rate loss was 0.2%, all other files had <=0.1% loss)
author michaelni
date Wed, 02 Jul 2003 10:45:04 +0000
parents 1cbc2380d172
children c4e6ed5319e7
comparison
equal deleted inserted replaced
1335:b4a72edb3a71 1336:c16ac5b7ac79
207 } 207 }
208 208
209 /** 209 /**
210 * put 210 * put
211 */ 211 */
212 static inline void put_symbol(CABACContext *c, uint8_t *state, int v, int is_signed){ 212 static inline void put_symbol(CABACContext *c, uint8_t *state, int v, int is_signed, int max_exp){
213 int i; 213 int i;
214 214
215 if(v){ 215 if(v){
216 const int a= ABS(v); 216 const int a= ABS(v);
217 const int e= av_log2(a); 217 const int e= av_log2(a);
218 218
219 put_cabac(c, state+0, 0); 219 put_cabac(c, state+0, 0);
220 put_cabac_u(c, state+1, e, 7, 6, 1); //1..7 220
221 if(e<7){ 221 for(i=0; i<e; i++){
222 put_cabac(c, state+1+i, 1); //1..8
223 }
224
225 if(e<max_exp){
226 put_cabac(c, state+1+i, 0); //1..8
227
222 for(i=e-1; i>=0; i--){ 228 for(i=e-1; i>=0; i--){
223 static const int offset[7]= {15+0, 15+0, 15+1, 15+3, 15+6, 15+10, 15+11}; 229 put_cabac(c, state+16+e+i, (a>>i)&1); //17..29
224 put_cabac(c, state+offset[e]+i, (a>>i)&1); //15..31
225 } 230 }
226 if(is_signed) 231 if(is_signed)
227 put_cabac(c, state+8 + e, v < 0); //8..14 232 put_cabac(c, state+9 + e, v < 0); //9..16
228 } 233 }
229 }else{ 234 }else{
230 put_cabac(c, state+0, 1); 235 put_cabac(c, state+0, 1);
231 } 236 }
232 } 237 }
233 238
234 static inline int get_symbol(CABACContext *c, uint8_t *state, int is_signed){ 239 static inline int get_symbol(CABACContext *c, uint8_t *state, int is_signed, int max_exp){
235 int i;
236
237 if(get_cabac(c, state+0)) 240 if(get_cabac(c, state+0))
238 return 0; 241 return 0;
239 else{ 242 else{
240 const int e= get_cabac_u(c, state+1, 7, 6, 1); //1..7 243 int i, e;
241 244
242 if(e<7){ 245 for(e=0; e<max_exp; e++){
243 int a= 1<<e; 246 int a= 1<<e;
244 247
245 for(i=e-1; i>=0; i--){ 248 if(get_cabac(c, state + 1 + e)==0){ // 1..8
246 static const int offset[7]= {15+0, 15+0, 15+1, 15+3, 15+6, 15+10, 15+11}; 249 for(i=e-1; i>=0; i--){
247 a += get_cabac(c, state+offset[e]+i)<<i; //14..31 250 a += get_cabac(c, state+16+e+i)<<i; //17..29
251 }
252
253 if(is_signed && get_cabac(c, state+9 + e)) //9..16
254 return -a;
255 else
256 return a;
248 } 257 }
249 258 }
250 if(is_signed && get_cabac(c, state+8 + e)) //8..14 259 return -(1<<e);
251 return -a;
252 else
253 return a;
254 }else
255 return -128;
256 } 260 }
257 } 261 }
258 262
259 static inline void update_vlc_state(VlcState * const state, const int v){ 263 static inline void update_vlc_state(VlcState * const state, const int v){
260 int drift= state->drift; 264 int drift= state->drift;
380 diff= -diff; 384 diff= -diff;
381 } 385 }
382 386
383 diff= (int8_t)diff; 387 diff= (int8_t)diff;
384 388
385 if(s->ac) 389 if(s->ac){
386 put_symbol(c, p->state[context], diff, 1); 390 put_symbol(c, p->state[context], diff, 1, 7);
387 else{ 391 }else{
388 if(context == 0) run_mode=1; 392 if(context == 0) run_mode=1;
389 393
390 if(run_mode){ 394 if(run_mode){
391 395
392 if(diff){ 396 if(diff){
432 int i; 436 int i;
433 uint8_t state[CONTEXT_SIZE]={0}; 437 uint8_t state[CONTEXT_SIZE]={0};
434 438
435 for(i=1; i<128 ; i++){ 439 for(i=1; i<128 ; i++){
436 if(quant_table[i] != quant_table[i-1]){ 440 if(quant_table[i] != quant_table[i-1]){
437 put_symbol(c, state, i-last-1, 0); 441 put_symbol(c, state, i-last-1, 0, 7);
438 last= i; 442 last= i;
439 } 443 }
440 } 444 }
441 put_symbol(c, state, i-last-1, 0); 445 put_symbol(c, state, i-last-1, 0, 7);
442 } 446 }
443 447
444 static void write_header(FFV1Context *f){ 448 static void write_header(FFV1Context *f){
445 uint8_t state[CONTEXT_SIZE]={0}; 449 uint8_t state[CONTEXT_SIZE]={0};
446 int i; 450 int i;
447 CABACContext * const c= &f->c; 451 CABACContext * const c= &f->c;
448 452
449 put_symbol(c, state, f->version, 0); 453 put_symbol(c, state, f->version, 0, 7);
450 put_symbol(c, state, f->avctx->coder_type, 0); 454 put_symbol(c, state, f->avctx->coder_type, 0, 7);
451 put_symbol(c, state, 0, 0); //YUV cs type 455 put_symbol(c, state, 0, 0, 7); //YUV cs type
452 put_cabac(c, state, 1); //chroma planes 456 put_cabac(c, state, 1); //chroma planes
453 put_symbol(c, state, f->chroma_h_shift, 0); 457 put_symbol(c, state, f->chroma_h_shift, 0, 7);
454 put_symbol(c, state, f->chroma_v_shift, 0); 458 put_symbol(c, state, f->chroma_v_shift, 0, 7);
455 put_cabac(c, state, 0); //no transparency plane 459 put_cabac(c, state, 0); //no transparency plane
456 460
457 for(i=0; i<5; i++) 461 for(i=0; i<5; i++)
458 write_quant_table(c, f->quant_table[i]); 462 write_quant_table(c, f->quant_table[i]);
459 } 463 }
671 }else 675 }else
672 sign=0; 676 sign=0;
673 677
674 678
675 if(s->ac) 679 if(s->ac)
676 diff= get_symbol(c, p->state[context], 1); 680 diff= get_symbol(c, p->state[context], 1, 7);
677 else{ 681 else{
678 if(context == 0 && run_mode==0) run_mode=1; 682 if(context == 0 && run_mode==0) run_mode=1;
679 683
680 if(run_mode){ 684 if(run_mode){
681 if(run_count==0 && run_mode==1){ 685 if(run_count==0 && run_mode==1){
717 int v; 721 int v;
718 int i=0; 722 int i=0;
719 uint8_t state[CONTEXT_SIZE]={0}; 723 uint8_t state[CONTEXT_SIZE]={0};
720 724
721 for(v=0; i<128 ; v++){ 725 for(v=0; i<128 ; v++){
722 int len= get_symbol(c, state, 0) + 1; 726 int len= get_symbol(c, state, 0, 7) + 1;
723 727
724 if(len + i > 128) return -1; 728 if(len + i > 128) return -1;
725 729
726 while(len--){ 730 while(len--){
727 quant_table[i] = scale*v; 731 quant_table[i] = scale*v;
742 static int read_header(FFV1Context *f){ 746 static int read_header(FFV1Context *f){
743 uint8_t state[CONTEXT_SIZE]={0}; 747 uint8_t state[CONTEXT_SIZE]={0};
744 int i, context_count; 748 int i, context_count;
745 CABACContext * const c= &f->c; 749 CABACContext * const c= &f->c;
746 750
747 f->version= get_symbol(c, state, 0); 751 f->version= get_symbol(c, state, 0, 7);
748 f->ac= f->avctx->coder_type= get_symbol(c, state, 0); 752 f->ac= f->avctx->coder_type= get_symbol(c, state, 0, 7);
749 get_symbol(c, state, 0); //YUV cs type 753 get_symbol(c, state, 0, 7); //YUV cs type
750 get_cabac(c, state); //no chroma = false 754 get_cabac(c, state); //no chroma = false
751 f->chroma_h_shift= get_symbol(c, state, 0); 755 f->chroma_h_shift= get_symbol(c, state, 0, 7);
752 f->chroma_v_shift= get_symbol(c, state, 0); 756 f->chroma_v_shift= get_symbol(c, state, 0, 7);
753 get_cabac(c, state); //transparency plane 757 get_cabac(c, state); //transparency plane
754 f->plane_count= 3; 758 f->plane_count= 3;
755 759
760 switch(16*f->chroma_h_shift + f->chroma_v_shift){
761 case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break;
762 case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P; break;
763 case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P; break;
764 case 0x20: f->avctx->pix_fmt= PIX_FMT_YUV411P; break;
765 case 0x33: f->avctx->pix_fmt= PIX_FMT_YUV410P; break;
766 default:
767 fprintf(stderr, "format not supported\n");
768 return -1;
769 }
770 //printf("%d %d %d\n", f->chroma_h_shift, f->chroma_v_shift,f->avctx->pix_fmt);
771
756 context_count=1; 772 context_count=1;
757 for(i=0; i<5; i++){ 773 for(i=0; i<5; i++){
758 context_count*= read_quant_table(c, f->quant_table[i], context_count); 774 context_count*= read_quant_table(c, f->quant_table[i], context_count);
775 if(context_count < 0){
776 printf("read_quant_table error\n");
777 return -1;
778 }
759 } 779 }
760 context_count= (context_count+1)/2; 780 context_count= (context_count+1)/2;
761 781
762 for(i=0; i<f->plane_count; i++){ 782 for(i=0; i<f->plane_count; i++){
763 PlaneContext * const p= &f->plane[i]; 783 PlaneContext * const p= &f->plane[i];
821 return 0; 841 return 0;
822 842
823 ff_init_cabac_decoder(c, buf, buf_size); 843 ff_init_cabac_decoder(c, buf, buf_size);
824 ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); 844 ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
825 845
826 p->reference= 0;
827 if(avctx->get_buffer(avctx, p) < 0){
828 fprintf(stderr, "get_buffer() failed\n");
829 return -1;
830 }
831
832 p->pict_type= FF_I_TYPE; //FIXME I vs. P 846 p->pict_type= FF_I_TYPE; //FIXME I vs. P
833 if(get_cabac_bypass(c)){ 847 if(get_cabac_bypass(c)){
834 p->key_frame= 1; 848 p->key_frame= 1;
835 read_header(f); 849 read_header(f);
836 clear_state(f); 850 clear_state(f);
837 }else{ 851 }else{
838 p->key_frame= 0; 852 p->key_frame= 0;
839 } 853 }
854
855 p->reference= 0;
856 if(avctx->get_buffer(avctx, p) < 0){
857 fprintf(stderr, "get_buffer() failed\n");
858 return -1;
859 }
860
840 if(avctx->debug&FF_DEBUG_PICT_INFO) 861 if(avctx->debug&FF_DEBUG_PICT_INFO)
841 printf("keyframe:%d\n", p->key_frame); 862 printf("keyframe:%d coder:%d\n", p->key_frame, f->ac);
842 863
843 if(!f->ac){ 864 if(!f->ac){
844 bytes_read = get_cabac_terminate(c); 865 bytes_read = get_cabac_terminate(c);
845 if(bytes_read ==0) printf("error at end of AC stream\n"); 866 if(bytes_read ==0) printf("error at end of AC stream\n");
846 //printf("pos=%d\n", bytes_read); 867 //printf("pos=%d\n", bytes_read);