00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "autoexposure.h"
00034 void initAexpCorr(void) {
00035 GLOBALPARS(G_NEXT_AE_FRAME)=0;
00036 }
00046
00047
00054
00055
00056 int aexpCorr(int color, int frame, int target_frame) {
00057
00058 int rslt;
00059
00060 unsigned long write_data[4];
00061 short * ae_err;
00062 int frac;
00063 int level,level_gamma;
00064 int perc;
00065 int old_vexpos;
00066 int new_vexpos;
00067 float fvexpos;
00068 int error_thresh;
00069 int max_vexpos;
00070 int dim;
00071 int diff;
00072
00073 int target_frame8=target_frame & PARS_FRAMES_MASK;
00074 int ae_period_change=framePars[target_frame8].pars[P_AE_PERIOD] & 0xff;
00075 int ae_period_nochange=(framePars[target_frame8].pars[P_AE_PERIOD] >> 8 ) & 0xff;
00076 int ae_dont_sync=(framePars[target_frame8].pars[P_AE_PERIOD] & 0x10000);
00077 int i, aerr;
00078
00079 if (!ae_period_change) ae_period_change=DEFAULT_AE_PERIOD_CHANGE;
00080 if (!ae_period_nochange) ae_period_nochange=DEFAULT_AE_PERIOD_NOCHANGE;
00081
00082 if (!framePars[target_frame & PARS_FRAMES_MASK].pars[P_AUTOEXP_ON]) {
00083 GLOBALPARS(G_NEXT_AE_FRAME)=frame+ae_period_change;
00084 return 0;
00085 }
00086 if (GLOBALPARS(G_NEXT_AE_FRAME)>frame) return 0;
00087
00088 ae_err= (short *) &(GLOBALPARS(G_AE_INTEGERR));
00089 MDF3(fprintf(stderr,"ae_err[0]=0x%04x, ae_err[1]=0x%04x\n",(int)ae_err[0],(int)ae_err[1]));
00090
00091 frac=framePars[target_frame & PARS_FRAMES_MASK].pars[P_AEXP_FRACPIX];
00092
00094 dim=(GLOBALPARS((color>1)?G_HIST_DIM_23:G_HIST_DIM_01) >> ((color & 1)? 16 : 0)) & 0xffff;
00096 perc=getPercentile(frame-1,color, frac, 1 << color);
00097
00098 if (histogram_cache[hist_index].frame < (frame-1)) {
00099 GLOBALPARS(G_NEXT_AE_FRAME)=frame+1;
00100 if (ae_dont_sync) return 0;
00101
00102 for (i=0; i<8; i++) {
00103 frame++;
00104 MDF3(fprintf(stderr,"Skipping frame trying to synchronize, frame will be 0x%x\n",frame));
00105 lseek(fd_fparmsall, frame +LSEEK_FRAME_WAIT_ABS, SEEK_END);
00106 this_frame=frame;
00107 perc=getPercentile(frame-1,color, frac, 1 << color);
00108 if (histogram_cache[hist_index].frame == (frame-1)) break;
00109 }
00110 if (histogram_cache[hist_index].frame < (frame-1)) {
00111 GLOBALPARS(G_NEXT_AE_FRAME)=frame+1;
00112 return 0;
00113 }
00114 }
00115 level_gamma=framePars[target_frame & PARS_FRAMES_MASK].pars[P_AEXP_LEVEL];
00117 level=gammaReverse (level_gamma);
00118 MDF3(fprintf(stderr,"->>> frame=0x%x, target_frame=0x%x,dim=0x%04x, frac=0x%04x, level=0x%x,level_gamma=0x%x, perc=0x%04x\n",frame,target_frame,dim,frac,level,level_gamma,perc));
00119 if (perc <0) {
00120 GLOBALPARS(G_NEXT_AE_FRAME)=frame+ae_period_change;
00121 return -1;
00122 }
00126
00127 if ((perc > ((level_gamma+0x1ffff)>>2))&& (perc>0xf000) ) {
00128 aex_recover_cntr++;
00129
00130
00131 MDF1(fprintf(stderr,"--- Triggered overexposure recovery:perc=0x%x, level_gamma=0x%x,aex_recover_cntr=0x%x\n",perc,level_gamma,aex_recover_cntr));
00132
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 } else {
00149 aex_recover_cntr=0;
00150 }
00151
00152
00153 old_vexpos= get_imageParamsThatValid(P_VEXPOS, frame-1);
00154 if (old_vexpos <0) {
00155 GLOBALPARS(G_NEXT_AE_FRAME)=frame+ae_period_change;
00156 return -2;
00157 }
00158 if (old_vexpos==1) {
00159 fvexpos=old_vexpos;
00160 new_vexpos= (fvexpos*level)/perc;
00161 } else {
00162 fvexpos=(old_vexpos-1);
00163 if (perc < (dim>>1)) {
00164 new_vexpos= (fvexpos*level)/perc;
00165 } else {
00166 new_vexpos= (fvexpos*(level-dim))/(perc-dim);
00167 }
00168 if (aex_recover_cntr > 3) {
00169 MDF1(fprintf(stderr,">>>> Reducing new_vexpos twice\n"));
00170 new_vexpos=(new_vexpos>>1)+1;
00171 }
00172 }
00173
00174
00175 MDF3(fprintf(stderr,"old_vexpos=0x%x, new_vexpos=0x%x,\n",old_vexpos,new_vexpos));
00177 max_vexpos= framePars[target_frame & PARS_FRAMES_MASK].pars[P_AUTOEXP_EXP_MAX];
00178 if (!max_vexpos) max_vexpos=0x4000;
00179 if (new_vexpos < 1) new_vexpos=1;
00180 else {
00181 if (new_vexpos > max_vexpos) new_vexpos=max_vexpos;
00182 if (new_vexpos > (old_vexpos*4)) new_vexpos=(old_vexpos*4);
00183 }
00184 diff=poorLog(new_vexpos) - poorLog(old_vexpos);
00185 ae_err[0]+=diff;
00186
00187 MDF3(fprintf(stderr,"old_vexpos=0x%x, new_vexpos=0x%x, poorLog(new_vexpos)=0x%x, poorLog(old_vexpos)=0x%x, diff=%d, ae_err=%d\n", old_vexpos, new_vexpos, poorLog(new_vexpos), poorLog(old_vexpos), diff, ae_err[0]));
00188 error_thresh=framePars[target_frame & PARS_FRAMES_MASK].pars[P_AE_THRESH];
00189 aerr=abs (ae_err[0]);
00190 if (aerr>error_thresh) aerr=error_thresh;
00191 new_vexpos=(old_vexpos*(error_thresh-aerr)+new_vexpos*aerr)/error_thresh;
00192 if (new_vexpos==old_vexpos) {
00193 MDF3(fprintf(stderr,"No correction: thrshold=%d, aerr=%d\n",error_thresh,aerr));
00194 GLOBALPARS(G_NEXT_AE_FRAME)=frame+ae_period_nochange;
00195 return 0;
00196 }
00197 ae_err[0]=0;
00198
00199
00200 write_data[0]= FRAMEPARS_SETFRAME;
00201 write_data[1]= target_frame;
00202 write_data[2]= P_VEXPOS;
00203 write_data[3]= new_vexpos;
00204
00205
00206 rslt=write(fd_fparmsall, write_data, sizeof(write_data));
00207 if (rslt < sizeof(write_data)) return -errno;
00208 GLOBALPARS(G_NEXT_AE_FRAME)=frame+ae_period_change;
00209 return 1;
00210 }
00211