comparison mpegvideo.c @ 1784:65f7bd09f37b libavcodec

quantizer noise shaping optimization
author michael
date Fri, 06 Feb 2004 02:12:37 +0000
parents 34466835920f
children 14d918d0ef42
comparison
equal deleted inserted replaced
1783:66ae3c109d90 1784:65f7bd09f37b
4913 } 4913 }
4914 4914
4915 return last_non_zero; 4915 return last_non_zero;
4916 } 4916 }
4917 4917
4918 #define BASIS_SHIFT 16
4919 #define RECON_SHIFT 6
4920 //#define REFINE_STATS 1 4918 //#define REFINE_STATS 1
4921 static int16_t basis[64][64]; 4919 static int16_t basis[64][64];
4922 4920
4923 static void build_basis(uint8_t *perm){ 4921 static void build_basis(uint8_t *perm){
4924 int i, j, x, y; 4922 int i, j, x, y;
4935 basis[perm_index][8*x + y]= lrintf(s * cos((M_PI/8.0)*i*(x+0.5)) * cos((M_PI/8.0)*j*(y+0.5))); 4933 basis[perm_index][8*x + y]= lrintf(s * cos((M_PI/8.0)*i*(x+0.5)) * cos((M_PI/8.0)*j*(y+0.5)));
4936 } 4934 }
4937 } 4935 }
4938 } 4936 }
4939 } 4937 }
4940 }
4941
4942 static int try_basis(int16_t rem[64], int16_t weight[64], int index, int scale){
4943 int i;
4944 unsigned int sum=0;
4945
4946 for(i=0; i<8*8; i++){
4947 int b= rem[i] - ((basis[index][i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT));
4948 int w= weight[i];
4949 b= (b + (1<<(RECON_SHIFT-1))) >> RECON_SHIFT;
4950 assert(-512<b && b<512);
4951
4952 sum += (w*b)*(w*b)>>4;
4953 }
4954 return sum>>2;
4955 }
4956
4957 static void add_basis(int16_t rem[64], int index, int scale){
4958 int i;
4959
4960 for(i=0; i<8*8; i++){
4961 rem[i] -= (basis[index][i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT);
4962 }
4963 } 4938 }
4964 4939
4965 static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise? 4940 static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?
4966 DCTELEM *block, int16_t *weight, DCTELEM *orig, 4941 DCTELEM *block, int16_t *weight, DCTELEM *orig,
4967 int n, int qscale){ 4942 int n, int qscale){
5026 last_non_zero = s->block_last_index[n]; 5001 last_non_zero = s->block_last_index[n];
5027 5002
5028 #ifdef REFINE_STATS 5003 #ifdef REFINE_STATS
5029 {START_TIMER 5004 {START_TIMER
5030 #endif 5005 #endif
5031 for(i=0; i<64; i++){ //FIXME memsetw or similar 5006 dc += (1<<(RECON_SHIFT-1));
5032 rem[i]= (orig[i]<<RECON_SHIFT) - dc; //FIXME use orig dirrectly insteadof copying to rem[] 5007 for(i=0; i<64; i++){
5008 rem[i]= dc - (orig[i]<<RECON_SHIFT); //FIXME use orig dirrectly insteadof copying to rem[]
5033 } 5009 }
5034 #ifdef REFINE_STATS 5010 #ifdef REFINE_STATS
5035 STOP_TIMER("memset rem[]")} 5011 STOP_TIMER("memset rem[]")}
5036 #endif 5012 #endif
5037 sum=0; 5013 sum=0;
5065 if(level<0) coeff= qmul*level - qadd; 5041 if(level<0) coeff= qmul*level - qadd;
5066 else coeff= qmul*level + qadd; 5042 else coeff= qmul*level + qadd;
5067 run_tab[rle_index++]=run; 5043 run_tab[rle_index++]=run;
5068 run=0; 5044 run=0;
5069 5045
5070 add_basis(rem, j, coeff); 5046 s->dsp.add_8x8basis(rem, basis[j], coeff);
5071 }else{ 5047 }else{
5072 run++; 5048 run++;
5073 } 5049 }
5074 } 5050 }
5075 #ifdef REFINE_STATS 5051 #ifdef REFINE_STATS
5079 } 5055 }
5080 5056
5081 {START_TIMER 5057 {START_TIMER
5082 #endif 5058 #endif
5083 for(;;){ 5059 for(;;){
5084 int best_score=try_basis(rem, weight, 0, 0); 5060 int best_score=s->dsp.try_8x8basis(rem, weight, basis[0], 0);
5085 int nochange_score= best_score; 5061 int nochange_score= best_score;
5086 int best_coeff=0; 5062 int best_coeff=0;
5087 int best_change=0; 5063 int best_change=0;
5088 int run2, best_unquant_change; 5064 int run2, best_unquant_change;
5089 #ifdef REFINE_STATS 5065 #ifdef REFINE_STATS
5103 5079
5104 new_coeff= q*new_level; 5080 new_coeff= q*new_level;
5105 if(new_coeff >= 2048 || new_coeff < 0) 5081 if(new_coeff >= 2048 || new_coeff < 0)
5106 continue; 5082 continue;
5107 5083
5108 score= try_basis(rem, weight, 0, new_coeff - old_coeff); 5084 score= s->dsp.try_8x8basis(rem, weight, basis[0], new_coeff - old_coeff);
5109 if(score<best_score){ 5085 if(score<best_score){
5110 best_score= score; 5086 best_score= score;
5111 best_coeff= 0; 5087 best_coeff= 0;
5112 best_change= change; 5088 best_change= change;
5113 best_unquant_change= new_coeff - old_coeff; 5089 best_unquant_change= new_coeff - old_coeff;
5219 score *= lambda; 5195 score *= lambda;
5220 5196
5221 unquant_change= new_coeff - old_coeff; 5197 unquant_change= new_coeff - old_coeff;
5222 assert((score < 100*lambda && score > -100*lambda) || lambda==0); 5198 assert((score < 100*lambda && score > -100*lambda) || lambda==0);
5223 5199
5224 score+= try_basis(rem, weight, j, unquant_change); 5200 score+= s->dsp.try_8x8basis(rem, weight, basis[j], unquant_change);
5225 if(score<best_score){ 5201 if(score<best_score){
5226 best_score= score; 5202 best_score= score;
5227 best_coeff= i; 5203 best_coeff= i;
5228 best_change= change; 5204 best_change= change;
5229 best_unquant_change= unquant_change; 5205 best_unquant_change= unquant_change;
5293 }else{ 5269 }else{
5294 run++; 5270 run++;
5295 } 5271 }
5296 } 5272 }
5297 5273
5298 add_basis(rem, j, best_unquant_change); 5274 s->dsp.add_8x8basis(rem, basis[j], best_unquant_change);
5299 }else{ 5275 }else{
5300 break; 5276 break;
5301 } 5277 }
5302 } 5278 }
5303 #ifdef REFINE_STATS 5279 #ifdef REFINE_STATS