comparison libpostproc/postprocess.c @ 2037:98d8283534bb libavcodec

accurate/slow (per line instead of per block) deblock filter spport which is identical to what is recommanded in the mpeg4 spec
author michael
date Thu, 27 May 2004 15:57:20 +0000
parents 6a6c678517b3
children 02b59a3c62cd
comparison
equal deleted inserted replaced
2036:6a6c678517b3 2037:98d8283534bb
106 #define TEMP_STRIDE 8 106 #define TEMP_STRIDE 8
107 //#define NUM_BLOCKS_AT_ONCE 16 //not used yet 107 //#define NUM_BLOCKS_AT_ONCE 16 //not used yet
108 108
109 #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) 109 #if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
110 # define attribute_used __attribute__((used)) 110 # define attribute_used __attribute__((used))
111 # define always_inline __attribute__((always_inline)) inline
111 #else 112 #else
112 # define attribute_used 113 # define attribute_used
114 # define always_inline inline
113 #endif 115 #endif
114 116
115 #ifdef ARCH_X86 117 #ifdef ARCH_X86
116 static uint64_t __attribute__((aligned(8))) attribute_used w05= 0x0005000500050005LL; 118 static uint64_t __attribute__((aligned(8))) attribute_used w05= 0x0005000500050005LL;
117 static uint64_t __attribute__((aligned(8))) attribute_used w20= 0x0020002000200020LL; 119 static uint64_t __attribute__((aligned(8))) attribute_used w20= 0x0020002000200020LL;
120 static uint64_t __attribute__((aligned(8))) attribute_used b02= 0x0202020202020202LL; 122 static uint64_t __attribute__((aligned(8))) attribute_used b02= 0x0202020202020202LL;
121 static uint64_t __attribute__((aligned(8))) attribute_used b08= 0x0808080808080808LL; 123 static uint64_t __attribute__((aligned(8))) attribute_used b08= 0x0808080808080808LL;
122 static uint64_t __attribute__((aligned(8))) attribute_used b80= 0x8080808080808080LL; 124 static uint64_t __attribute__((aligned(8))) attribute_used b80= 0x8080808080808080LL;
123 #endif 125 #endif
124 126
125
126 static uint8_t clip_table[3*256]; 127 static uint8_t clip_table[3*256];
127 static uint8_t * const clip_tab= clip_table + 256; 128 static uint8_t * const clip_tab= clip_table + 256;
128 129
129 static const int verbose= 0; 130 static const int verbose= 0;
130 131
137 {"vb", "vdeblock", 1, 2, 4, V_DEBLOCK}, 138 {"vb", "vdeblock", 1, 2, 4, V_DEBLOCK},
138 /* {"hr", "rkhdeblock", 1, 1, 3, H_RK1_FILTER}, 139 /* {"hr", "rkhdeblock", 1, 1, 3, H_RK1_FILTER},
139 {"vr", "rkvdeblock", 1, 2, 4, V_RK1_FILTER},*/ 140 {"vr", "rkvdeblock", 1, 2, 4, V_RK1_FILTER},*/
140 {"h1", "x1hdeblock", 1, 1, 3, H_X1_FILTER}, 141 {"h1", "x1hdeblock", 1, 1, 3, H_X1_FILTER},
141 {"v1", "x1vdeblock", 1, 2, 4, V_X1_FILTER}, 142 {"v1", "x1vdeblock", 1, 2, 4, V_X1_FILTER},
143 {"ha", "ahdeblock", 1, 1, 3, H_A_DEBLOCK},
144 {"va", "avdeblock", 1, 2, 4, V_A_DEBLOCK},
142 {"dr", "dering", 1, 5, 6, DERING}, 145 {"dr", "dering", 1, 5, 6, DERING},
143 {"al", "autolevels", 0, 1, 2, LEVEL_FIX}, 146 {"al", "autolevels", 0, 1, 2, LEVEL_FIX},
144 {"lb", "linblenddeint", 1, 1, 4, LINEAR_BLEND_DEINT_FILTER}, 147 {"lb", "linblenddeint", 1, 1, 4, LINEAR_BLEND_DEINT_FILTER},
145 {"li", "linipoldeint", 1, 1, 4, LINEAR_IPOL_DEINT_FILTER}, 148 {"li", "linipoldeint", 1, 1, 4, LINEAR_IPOL_DEINT_FILTER},
146 {"ci", "cubicipoldeint", 1, 1, 4, CUBIC_IPOL_DEINT_FILTER}, 149 {"ci", "cubicipoldeint", 1, 1, 4, CUBIC_IPOL_DEINT_FILTER},
152 {NULL, NULL,0,0,0,0} //End Marker 155 {NULL, NULL,0,0,0,0} //End Marker
153 }; 156 };
154 157
155 static char *replaceTable[]= 158 static char *replaceTable[]=
156 { 159 {
157 "default", "hdeblock:a,vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400", 160 "default", "hdeblock:a,vdeblock:a,dering:a",
158 "de", "hdeblock:a,vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400", 161 "de", "hdeblock:a,vdeblock:a,dering:a",
159 "fast", "x1hdeblock:a,x1vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400", 162 "fast", "x1hdeblock:a,x1vdeblock:a,dering:a",
160 "fa", "x1hdeblock:a,x1vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400", 163 "fa", "x1hdeblock:a,x1vdeblock:a,dering:a",
164 "ac", "ha:a:128:7,va:a,dering:a",
161 NULL //End Marker 165 NULL //End Marker
162 }; 166 };
163 167
164 168
165 #ifdef ARCH_X86 169 #ifdef ARCH_X86
467 } 471 }
468 src+=stride; 472 src+=stride;
469 } 473 }
470 } 474 }
471 475
476 /**
477 * accurate deblock filter
478 */
479 static always_inline void do_a_deblock(uint8_t *src, int step, int stride, PPContext *c){
480 int y;
481 const int QP= c->QP;
482 const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1;
483 const int dcThreshold= dcOffset*2 + 1;
484 //START_TIMER
485 src+= step*4; // src points to begin of the 8x8 Block
486 for(y=0; y<8; y++){
487 int numEq= 0;
488
489 if(((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold) numEq++;
490 if(((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold) numEq++;
491 if(((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold) numEq++;
492 if(((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold) numEq++;
493 if(((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold) numEq++;
494 if(((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold) numEq++;
495 if(((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold) numEq++;
496 if(((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold) numEq++;
497 if(((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold) numEq++;
498 if(numEq > c->ppMode.flatnessThreshold){
499 int min, max, x;
500
501 if(src[0] > src[step]){
502 max= src[0];
503 min= src[step];
504 }else{
505 max= src[step];
506 min= src[0];
507 }
508 for(x=2; x<8; x+=2){
509 if(src[x*step] > src[(x+1)*step]){
510 if(src[x *step] > max) max= src[ x *step];
511 if(src[(x+1)*step] < min) min= src[(x+1)*step];
512 }else{
513 if(src[(x+1)*step] > max) max= src[(x+1)*step];
514 if(src[ x *step] < min) min= src[ x *step];
515 }
516 }
517 if(max-min < 2*QP){
518 const int first= ABS(src[-1*step] - src[0]) < QP ? src[-1*step] : src[0];
519 const int last= ABS(src[8*step] - src[7*step]) < QP ? src[8*step] : src[7*step];
520
521 int sums[10];
522 sums[0] = 4*first + src[0*step] + src[1*step] + src[2*step] + 4;
523 sums[1] = sums[0] - first + src[3*step];
524 sums[2] = sums[1] - first + src[4*step];
525 sums[3] = sums[2] - first + src[5*step];
526 sums[4] = sums[3] - first + src[6*step];
527 sums[5] = sums[4] - src[0*step] + src[7*step];
528 sums[6] = sums[5] - src[1*step] + last;
529 sums[7] = sums[6] - src[2*step] + last;
530 sums[8] = sums[7] - src[3*step] + last;
531 sums[9] = sums[8] - src[4*step] + last;
532
533 src[0*step]= (sums[0] + sums[2] + 2*src[0*step])>>4;
534 src[1*step]= (sums[1] + sums[3] + 2*src[1*step])>>4;
535 src[2*step]= (sums[2] + sums[4] + 2*src[2*step])>>4;
536 src[3*step]= (sums[3] + sums[5] + 2*src[3*step])>>4;
537 src[4*step]= (sums[4] + sums[6] + 2*src[4*step])>>4;
538 src[5*step]= (sums[5] + sums[7] + 2*src[5*step])>>4;
539 src[6*step]= (sums[6] + sums[8] + 2*src[6*step])>>4;
540 src[7*step]= (sums[7] + sums[9] + 2*src[7*step])>>4;
541 }
542 }else{
543 const int middleEnergy= 5*(src[4*step] - src[3*step]) + 2*(src[2*step] - src[5*step]);
544
545 if(ABS(middleEnergy) < 8*QP)
546 {
547 const int q=(src[3*step] - src[4*step])/2;
548 const int leftEnergy= 5*(src[2*step] - src[1*step]) + 2*(src[0*step] - src[3*step]);
549 const int rightEnergy= 5*(src[6*step] - src[5*step]) + 2*(src[4*step] - src[7*step]);
550
551 int d= ABS(middleEnergy) - MIN( ABS(leftEnergy), ABS(rightEnergy) );
552 d= MAX(d, 0);
553
554 d= (5*d + 32) >> 6;
555 d*= SIGN(-middleEnergy);
556
557 if(q>0)
558 {
559 d= d<0 ? 0 : d;
560 d= d>q ? q : d;
561 }
562 else
563 {
564 d= d>0 ? 0 : d;
565 d= d<q ? q : d;
566 }
567
568 src[3*step]-= d;
569 src[4*step]+= d;
570 }
571 }
572
573 src += stride;
574 }
575 /*if(step==16){
576 STOP_TIMER("step16")
577 }else{
578 STOP_TIMER("stepX")
579 }*/
580 }
472 581
473 //Note: we have C, MMX, MMX2, 3DNOW version there is no 3DNOW+MMX2 one 582 //Note: we have C, MMX, MMX2, 3DNOW version there is no 3DNOW+MMX2 one
474 //Plain C versions 583 //Plain C versions
475 #if !defined (HAVE_MMX) || defined (RUNTIME_CPUDETECT) 584 #if !defined (HAVE_MMX) || defined (RUNTIME_CPUDETECT)
476 #define COMPILE_C 585 #define COMPILE_C
630 " 1. difference factor: default=32, higher -> more deblocking\n" 739 " 1. difference factor: default=32, higher -> more deblocking\n"
631 " 2. flatness threshold: default=39, lower -> more deblocking\n" 740 " 2. flatness threshold: default=39, lower -> more deblocking\n"
632 " the h & v deblocking filters share these\n" 741 " the h & v deblocking filters share these\n"
633 " so you can't set different thresholds for h / v\n" 742 " so you can't set different thresholds for h / v\n"
634 "vb vdeblock (2 threshold) vertical deblocking filter\n" 743 "vb vdeblock (2 threshold) vertical deblocking filter\n"
744 "ha hadeblock (2 threshold) horizontal deblocking filter\n"
745 "va vadeblock (2 threshold) vertical deblocking filter\n"
635 "h1 x1hdeblock experimental h deblock filter 1\n" 746 "h1 x1hdeblock experimental h deblock filter 1\n"
636 "v1 x1vdeblock experimental v deblock filter 1\n" 747 "v1 x1vdeblock experimental v deblock filter 1\n"
637 "dr dering deringing filter\n" 748 "dr dering deringing filter\n"
638 "al autolevels automatic brightness / contrast\n" 749 "al autolevels automatic brightness / contrast\n"
639 " f fullyrange stretch luminance to (0..255)\n" 750 " f fullyrange stretch luminance to (0..255)\n"
640 "lb linblenddeint linear blend deinterlacer\n" 751 "lb linblenddeint linear blend deinterlacer\n"
641 "li linipoldeint linear interpolating deinterlace\n" 752 "li linipoldeint linear interpolating deinterlace\n"
642 "ci cubicipoldeint cubic interpolating deinterlacer\n" 753 "ci cubicipoldeint cubic interpolating deinterlacer\n"
643 "md mediandeint median deinterlacer\n" 754 "md mediandeint median deinterlacer\n"
644 "fd ffmpegdeint ffmpeg deinterlacer\n" 755 "fd ffmpegdeint ffmpeg deinterlacer\n"
645 "de default hb:a,vb:a,dr:a,al\n" 756 "de default hb:a,vb:a,dr:a\n"
646 "fa fast h1:a,v1:a,dr:a,al\n" 757 "fa fast h1:a,v1:a,dr:a\n"
647 "tn tmpnoise (3 threshold) temporal noise reducer\n" 758 "tn tmpnoise (3 threshold) temporal noise reducer\n"
648 " 1. <= 2. <= 3. larger -> stronger filtering\n" 759 " 1. <= 2. <= 3. larger -> stronger filtering\n"
649 "fq forceQuant <quantizer> force quantizer\n" 760 "fq forceQuant <quantizer> force quantizer\n"
650 ; 761 ;
651 762
791 numOfUnknownOptions--; 902 numOfUnknownOptions--;
792 if(numOfNoises >= 3) break; 903 if(numOfNoises >= 3) break;
793 } 904 }
794 } 905 }
795 } 906 }
796 else if(filters[i].mask == V_DEBLOCK || filters[i].mask == H_DEBLOCK) 907 else if(filters[i].mask == V_DEBLOCK || filters[i].mask == H_DEBLOCK
908 || filters[i].mask == V_A_DEBLOCK || filters[i].mask == H_A_DEBLOCK)
797 { 909 {
798 int o; 910 int o;
799 911
800 for(o=0; options[o]!=NULL && o<2; o++) 912 for(o=0; options[o]!=NULL && o<2; o++)
801 { 913 {