123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608 |
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/math64.h>
- #include "ark_camera.h"
- #include "ark_isp_exposure.h"
- #include "ark_isp_exposure_cmos.h"
- #define ENABLE_ERROR_RATIO 1
- static void histogram_bands_initialize (histogram_band_t bands[4])
- {
- bands[0].error = 0;
- bands[1].error = 0;
- bands[2].error = 0;
- bands[3].error = 0;
- bands[0].balance = 0;
- bands[1].balance = 0;
- bands[2].balance = 0;
- bands[3].balance = 0;
- }
- static void histogram_initialize (histogram_ptr_t p_hist)
- {
- p_hist->hist_balance = 0;
- p_hist->hist_dark = 0;
- p_hist->hist_dark_shift = 0x100;
- p_hist->hist_error = 0;
- histogram_bands_initialize (p_hist->bands);
- }
- void isp_system_ae_black_target_write (auto_exposure_ptr_t ae, u8_t data)
- {
- ae->ae_black_target = data;
- }
- u8_t isp_system_ae_black_target_read (auto_exposure_ptr_t ae)
- {
- return ae->ae_black_target;
- }
- void isp_system_ae_bright_target_write (auto_exposure_ptr_t ae, u8_t data)
- {
- ae->ae_bright_target = data;
- }
- u8_t isp_system_ae_bright_target_read (auto_exposure_ptr_t ae)
- {
- return ae->ae_bright_target;
- }
- void isp_histogram_thresh_write (auto_exposure_ptr_t ae, u8_t histoBand[4])
- {
- ae->metering_hist_thresh_0_1 = histoBand[0];
- ae->metering_hist_thresh_1_2 = histoBand[1];
- ae->metering_hist_thresh_3_4 = histoBand[2];
- ae->metering_hist_thresh_4_5 = histoBand[3];
- isp_histogram_bands_write (histoBand);
- }
- void isp_system_ae_compensation_write (auto_exposure_ptr_t ae, u8_t data)
- {
- ae->ae_compensation = data;
- }
- u8_t isp_system_ae_compensation_read (auto_exposure_ptr_t ae)
- {
- return ae->ae_compensation;
- }
- void isp_system_ae_ev_write( auto_exposure_ptr_t ae, i8_t data)
- {
- if(data < -6)
- data = -6;
- else if(data > 6)
- data = 6;
- ae->ae_ev = data;
- }
- i8_t isp_system_ae_ev_read (auto_exposure_ptr_t ae)
- {
- return ae->ae_ev;
- }
- void isp_histogram_thread_update (cmos_exposure_ptr_t p_exp)
- {
- histogram_band_t *bands = p_exp->cmos_ae.histogram.bands;
- auto_exposure_ptr_t ae = &p_exp->cmos_ae;
- bands[0].cent = (ae->metering_hist_thresh_0_1 + 0) / 2;
- bands[1].cent = (ae->metering_hist_thresh_0_1 + ae->metering_hist_thresh_1_2) / 2;
- bands[2].cent = (ae->metering_hist_thresh_1_2 + ae->metering_hist_thresh_3_4) / 2;
- bands[3].cent = (ae->metering_hist_thresh_3_4 + ae->metering_hist_thresh_4_5) / 2;
- bands[4].cent = (ae->metering_hist_thresh_4_5 + 255) / 2;
- }
- void isp_auto_exposure_compensation (auto_exposure_ptr_t ae, histogram_band_t bands[5])
- {
- u32_t ae_comp;
- //u8_t ev_value[7] = {32, 39, 50, 64, 83, 107, 128};
- u8_t ev_value[13] = {32, 35, 39, 44, 50, 57, 64, 74, 83, 95, 107, 117, 128};
- u8_t ev;
- if(ae->ae_ev < -6)
- ae->ae_ev = -6;
- else if(ae->ae_ev > 6)
- ae->ae_ev = 6;
- ev = ev_value[ae->ae_ev + 6];
- ae_comp = ae->ae_compensation;
- ae_comp *= ev;
- ae_comp /= ISP_SYSTEM_EV_DEFAULT;
- if(ae_comp < 1)
- ae_comp = 1;
-
- bands[0].target = (ae->ae_black_target << 8) / 2;
- bands[1].target = (ae->ae_black_target << 8);
- bands[2].target = 0x2000;
- bands[3].target = (ae->ae_bright_target << 8) * 2;
- bands[4].target = (ae->ae_bright_target << 8);
-
- if(ae_comp > 64)
- {
- bands[3].target = bands[3].target * ae_comp / 64;
- bands[4].target = bands[4].target * ae_comp / 64;
- }
- else
- {
- bands[0].target = bands[0].target * 64 / ae_comp;
- bands[1].target = bands[1].target * 64 / ae_comp;
- }
-
- bands[0].cent = (ae->metering_hist_thresh_0_1 + 0) / 2;
- bands[1].cent = (ae->metering_hist_thresh_0_1 + ae->metering_hist_thresh_1_2) / 2;
- bands[2].cent = (ae->metering_hist_thresh_1_2 + ae->metering_hist_thresh_3_4) / 2;
- bands[3].cent = (ae->metering_hist_thresh_3_4 + ae->metering_hist_thresh_4_5) / 2;
- bands[4].cent = (ae->metering_hist_thresh_4_5 + 255) / 2;
- }
- static void histogram_data_read (histogram_ptr_t p_hist, isp_ae_ptr_t isp_ae)
- {
- int _i;
- u32_t hacc = 0;
- isp_histogram_bands_read(p_hist->bands, isp_ae);
- for(_i = 0; _i < HISTOGRAM_BANDS; ++_i)
- {
- hacc += p_hist->bands[_i].value;
- }
- if(hacc >= 0xFFFF)
- p_hist->bands[2].value = 0;
- else
- p_hist->bands[2].value = (u16_t)(0xFFFF - hacc);
- }
- static void histogram_error_calculate (auto_exposure_ptr_t ae, histogram_ptr_t p_hist, isp_ae_ptr_t isp_ae)
- {
- u8_t ae_comp;
- //u8_t lum = isp_ae_lum_read ();
- u8_t lum = isp_ae->lumCurr;
- ae_comp = ae->ae_compensation;
- p_hist->hist_error = ae_comp - p_hist->hist_balance;
-
- p_hist->lum_hist[0] = p_hist->lum_hist[1];
- p_hist->lum_hist[1] = p_hist->lum_hist[2];
- p_hist->lum_hist[2] = p_hist->lum_hist[3];
- p_hist->lum_hist[3] = lum;
-
- #if 1
- if(p_hist->hist_error > 0)
- {
- // 曝光不够场景
- int total_lum = 0;
- int i;
- for (i = 0; i < 4; i ++)
- {
- if(p_hist->lum_hist[i] >= 3)
- break;
- total_lum += p_hist->lum_hist[i];
- }
- if(i == 4)
- {
- // 亮度偏暗场景下, 增加曝光
- if(total_lum == 0)
- p_hist->hist_error *= 3;
- else
- p_hist->hist_error = p_hist->hist_error * 3 * 4 / total_lum;
- }
- }
- #else
- // 亮度偏暗场景下, 增加曝光
- if(lum < 3 && p_hist->hist_error > 0)
- {
- if(lum == 0)
- p_hist->hist_error *= 3;
- else
- p_hist->hist_error = p_hist->hist_error * 3 / lum;
- }
- #endif
- }
- static void histogram_balance_calculate (histogram_ptr_t p_hist)
- {
- int _i;
- int64_t hbal;
- int center;
- int64_t temp;
- hbal = p_hist->bands[2].cent;
- for(_i = 0; _i < HISTOGRAM_BANDS; ++_i)
- {
- if(_i == 0)
- center = 0x00;
- else if(_i == HISTOGRAM_BANDS)
- center = 0xff;
- else
- center = p_hist->bands[_i].cent;
- temp = (p_hist->bands[_i].value + p_hist->bands[_i].target/4);
- temp *= (center - p_hist->bands[2].cent);
- temp = div_s64(temp, p_hist->bands[_i].target); // target越大,其对误差的计算影响越小
- hbal += temp;
- }
- p_hist->hist_balance = (int)hbal;
- }
- static void histogram_dark_calculate (histogram_ptr_t p_hist)
- {
- i32_t h_dark = 0;
- h_dark = (p_hist->hist_dark_shift*(p_hist->bands[0].value*2 + p_hist->bands[1].value) + 0x2000) /
- (p_hist->bands[2].value + 0x2000);
- p_hist->hist_dark = h_dark;
- }
- static void histogram_update (auto_exposure_ptr_t ae, histogram_ptr_t p_hist, isp_ae_ptr_t isp_ae)
- {
- histogram_data_read (p_hist, isp_ae);
- histogram_balance_calculate (p_hist);
- histogram_error_calculate (ae, p_hist, isp_ae);
- //histogram_dark_calculate (p_hist);
- }
- // 计算逆光场景的比例因子(>=256),
- static int base_ratio = 36;
- static void calc_bright_error_ratio (isp_ae_ptr_t isp_ae, histogram_ptr_t p_hist)
- {
- unsigned int y_max = 0;
- unsigned int y_total = 0;
- unsigned short *yavg_s = (unsigned short *)isp_ae->yavg_s;
- int i;
- for (i = 0; i < 9; i ++)
- {
- if(yavg_s[i] > y_max)
- y_max = yavg_s[i];
- y_total += yavg_s[i];
- }
- //XM_unlock();
- y_total -= y_max;
- y_total *= base_ratio;
- y_total /= 80;
- if(y_total == 0)
- y_total = 1;
-
- if(y_max > 10 * y_total)
- y_max = 10 * y_total;
-
- if(y_max <= y_total)
- {
- p_hist->hist_error_ratio = 256;
- }
- else
- {
- // 20181019 曝光发生突变,改为逐步逼近,直到稳态
- p_hist->hist_error_ratio = y_max * 256 / y_total;
- // p_hist->hist_error_ratio = (unsigned int)(11*256/10); // 提升10%
- }
- }
- #if ENABLE_ERROR_RATIO
- #define MAX_ERROR_RATIO 16
- static const int histogram_error_ratio[3][3] = {
- 0, 0, 0,
- 3, 5, 3,
- 5, 7, 5
- };
- static const int histogram_error_ratio_2[3][3] = {
- 1, 1, 1,
- 1, 1, 1,
- 1, 1, 1
- };
- #endif
- static void histogram_3x3_update (auto_exposure_ptr_t ae, histogram_ptr_t p_hist, isp_ae_ptr_t isp_ae)
- {
- int i, j;
- static histogram_t hist[3][3];
- unsigned short histogram_s[3][3][5];
- int hist_error_min = 65535;
- int hist_error_max = -65536;
- int last_error = p_hist->hist_error;
- memcpy (histogram_s, isp_ae->histogram_s, sizeof(histogram_s));
-
- for (i = 0; i < 3; i ++)
- {
- for (j = 0; j < 3; j ++)
- {
- memcpy (&hist[i][j], p_hist, sizeof(histogram_t));
- hist[i][j].bands[0].value = histogram_s[i][j][0] << 4;
- hist[i][j].bands[1].value = histogram_s[i][j][1] << 4;
- hist[i][j].bands[2].value = histogram_s[i][j][2] << 4;
- hist[i][j].bands[3].value = histogram_s[i][j][3] << 4;
- hist[i][j].bands[4].value = histogram_s[i][j][4] << 4;
- histogram_balance_calculate (&hist[i][j]);
- histogram_error_calculate (ae, &hist[i][j], isp_ae);
- #if ENABLE_ERROR_RATIO
- hist[i][j].hist_error = hist[i][j].hist_error * histogram_error_ratio[i][j] / MAX_ERROR_RATIO;
- #endif
- if(hist[i][j].hist_error < hist_error_min)
- hist_error_min = hist[i][j].hist_error;
- if(hist[i][j].hist_error > hist_error_max)
- hist_error_max = hist[i][j].hist_error;
- }
- }
-
- // 计算最小值
- histogram_update (ae, p_hist, isp_ae);
-
- p_hist->hist_error_one = p_hist->hist_error;
- p_hist->hist_error_min = hist_error_min;
- p_hist->hist_error_max = hist_error_max;
- p_hist->hist_error_last = last_error;
-
- if(ae->ae_mode == AE_MODE_BRIGHT)
- {
- calc_bright_error_ratio (isp_ae, p_hist);
- if(p_hist->hist_error > 0)
- {
- p_hist->hist_error = p_hist->hist_error * p_hist->hist_error_ratio / 256;
- }
-
- }
- else if(ae->ae_mode == AE_MODE_DARK)
- {
- int curr_error;
- if(hist_error_min < -4)
- {
- curr_error = hist_error_min;
- if(hist_error_min < -4)
- {
- //printf ("he %d --> %d\n", p_hist->hist_error, hist_error_min);
- //int curr_error = hist_error_min + p_hist->hist_error * 4 / abs(hist_error_min);
- p_hist->hist_error = hist_error_min + p_hist->hist_error * 4 / abs(hist_error_min);
- }
- }
- else
- {
- curr_error = p_hist->hist_error;
-
- // 20181113 增加一条正曝光约束条件
- // 当hist_error与hist_error_min均为正值时(曝光不够,增加曝光),若hist_error_min与hist_error差异较大,
- // 为避免hist_error_min翻转导致曝光振荡(明暗交替),此时应约束hist_error的值,
- // hist_error_min值越小,hist_error的变化约束程度越大。
- // hist_error_min值越大,hist_error的变化约束程度越小。
- if(hist_error_min > 0 && curr_error > 0)
- {
- if(hist_error_min < 8)
- {
- curr_error /= 2; // curr_error / 2
- }
- else if( (curr_error / hist_error_min) > 3)
- {
- curr_error = curr_error * 2 / 3; // curr_error / 1.5
- }
-
- if(curr_error < hist_error_min)
- curr_error = hist_error_min;
-
- p_hist->hist_error = curr_error;
- }
-
- if(last_error < 0 && curr_error > 0 || last_error > 0 && curr_error < 0)
- {
- //if(abs(last_error - curr_error) > 128)
- {
- // 避免亮度变化过大
- curr_error = (last_error + curr_error) / 4;
- p_hist->hist_error = curr_error;
- }
- }
-
- }
- }
- }
- extern isp_ae_t p_ae;
- // 暗场景判定规则
- static int check_dark_mode (unsigned int iso, isp_ae_t *ptr_ae)
- {
- int is_dark_mode = 0;
- unsigned int y_max = 0;
- unsigned int y_max_i = 0;
- unsigned int y_max_j = 0;
- int i,j;
-
- if(ptr_ae)
- {
- unsigned short *yavg = (unsigned short *)ptr_ae->yavg_s;
-
- int count = 0;
- for (i = 0; i < 3; i++)
- {
- for (j = 0; j < 3; j ++)
- {
- unsigned int yavg = ptr_ae->yavg_s[i][j];
- if(yavg == 0)
- count ++;
- if(y_max < yavg)
- {
- y_max = yavg;
- y_max_i = i;
- y_max_j = j;
- }
- }
- }
-
- if(count >= 2)
- {
- // 微光区至少2个
- // 检查最大亮度的区域,其高亮区是否小于256。晚上一般为点光源,不同于白天高光区
- unsigned int histo = ptr_ae->histogram_s[y_max_i][y_max_j][3] + ptr_ae->histogram_s[y_max_i][y_max_j][4];
- if(histo < 256)
- is_dark_mode = 1;
-
- }
- }
-
- return is_dark_mode;
- }
- // 逆光
- static int check_bl_mode (unsigned int iso, isp_ae_t *ptr_ae)
- {
- int is_bl_mode = 0;
- int i;
-
- if(ptr_ae && iso < 16)
- {
- unsigned short *yavg = (unsigned short *)ptr_ae->yavg_s;
- int count = 0;
- for (i = 0; i < 9; i++)
- {
- if(yavg[i] == 0)
- return 0;
- if(yavg[i] == 1)
- count ++;
- }
-
- if(count >= 2)
- is_bl_mode = 1;
- }
-
- return is_bl_mode;
- }
- // 判断是否是白天(亮场景)模式
- static int is_bright_mode (unsigned int iso, isp_ae_t *ptr_ae)
- {
- unsigned int y_max = 0;
- unsigned int y_max_i = 0;
- unsigned int y_max_j = 0;
- unsigned int zero_count = 0;
- int i,j;
-
- // 超短曝光
- if(iso <= 4)
- return 1;
- // 短曝光
- if(iso < 16 && ptr_ae->lumCurr >= 8)
- return 1;
-
- // 20190416 涓嬮潰鐨勬潯浠朵細瀹规槗瀵艰嚧鍛ㄦ湡鎬ф槑鏆楁洕鍏夛紝绉昏嚦鏈€涓嬮潰
- // 涓�洕鍏�
- //if(iso < 128 && ptr_ae->lumCurr >= 16)
- // return 1;
-
- // 判断每个块的亮度值均大于某个值
- int count = 0;
- for (i = 0; i < 3; i++)
- {
- for (j = 0; j < 3; j ++)
- {
- unsigned int yavg = ptr_ae->yavg_s[i][j];
- if(yavg == 0)
- zero_count ++;
- if(yavg > y_max)
- {
- y_max = yavg;
- y_max_i = i;
- y_max_j = j;
- }
- if(yavg <= 1)
- count ++;
- }
- }
-
- // 20181023 根据路测结果,增加一条亮场景(白天)的判断规则
- // 1) ISO < 48, 存在至少一个亮区(亮度值大于64,且高光区4+5大于1000)
- // ae_sensor_inttime = 35
- // ae_sensor_again = 1.000000
- // ae_sensor_dgain = 1.000000
- // [0][1]:yavg_s = 72;[0] = 2292; [1] = 25; [2] = 401; [3] = 848; [4] = 529;
- if(iso < 48)
- {
- unsigned int histo = ptr_ae->histogram_s[y_max_i][y_max_j][3] + ptr_ae->histogram_s[y_max_i][y_max_j][4];
- if(y_max >= 64 && histo >= 1000 )
- return 1;
- }
-
-
- // 无微光区
- if(zero_count >= 1)
- return 0;
-
- // 最大亮度值大于100
- if(y_max > 100)
- return 1;
-
- // 弱光区个数
- if(count >= 2)
- return 0;
-
- // 20190416 涓嬮潰鐨勬潯浠朵細瀹规槗瀵艰嚧鍛ㄦ湡鎬ф槑鏆楁洕鍏夛紝绉昏嚦姝ゅ�
- // 涓�洕鍏�
- if(iso < 128 && ptr_ae->lumCurr >= 16)
- return 1;
-
- return 0;
- }
- static int get_y_max (isp_ae_t *ptr_ae)
- {
- unsigned int y_max = 0;
- int i, j;
-
- // 鍒ゆ柇姣忎釜鍧楃殑浜�害鍊煎潎澶т簬鏌愪釜鍊�
- for (i = 0; i < 3; i++)
- {
- for (j = 0; j < 3; j ++)
- {
- unsigned int yavg = ptr_ae->yavg_s[i][j];
- if(yavg > y_max)
- {
- y_max = yavg;
- }
- }
- }
-
- return y_max;
- }
- void isp_auto_exposure_set_iso (cmos_exposure_t *p_isp_exposure, unsigned int iso)
- {
- if(p_isp_exposure->cmos_ae.ae_mode == AE_MODE_BRIGHT)
- {
- //if(iso > p_isp_exposure->cmos_inttime.full_lines * 4/5)
- // 20190407 娴嬭瘯鍙戠幇瀛樺湪鏌愮�鎯呭喌锛屾槑鏆楀弽澶嶏紝姝ゆ椂鐨勬渶澶т寒搴﹀€�150銆�
- // 鍦ㄤ寒鍦烘櫙涓嬶紝澧炲姞涓€涓�潯浠讹紝褰撴渶澶т寒搴﹀€�>=95, 绂佹�鍒囨崲鍒版殫鍦烘櫙妯″紡
- //if(iso > p_isp_exposure->cmos_inttime.full_lines * 1/2)
- if( (iso > p_isp_exposure->cmos_inttime.full_lines)
- || ((iso > p_isp_exposure->cmos_inttime.full_lines * 1/2) && (get_y_max(&p_ae) < 95)) )
- {
- p_isp_exposure->cmos_ae.n_cycle ++;
- p_isp_exposure->cmos_ae.d_cycle = 0;
- if(p_isp_exposure->cmos_ae.n_cycle > 5)
- {
- p_isp_exposure->cmos_ae.ae_mode = AE_MODE_DARK;
- p_isp_exposure->cmos_ae.n_cycle = 0;
- XM_printf ("dark Mode\n");
- }
- }
- else
- {
- p_isp_exposure->cmos_ae.n_cycle = 0;
- p_isp_exposure->cmos_ae.d_cycle = 0;
- }
- }
- else if(p_isp_exposure->cmos_ae.ae_mode == AE_MODE_DARK)
- {
- //if(iso < 16 && p_ae.lumCurr >= 5 || iso <= 3)
- if(is_bright_mode (iso, &p_ae))
- {
- p_isp_exposure->cmos_ae.d_cycle ++;
- p_isp_exposure->cmos_ae.n_cycle = 0;
- if(p_isp_exposure->cmos_ae.d_cycle >= 4)
- {
- p_isp_exposure->cmos_ae.ae_mode = AE_MODE_BRIGHT;
- p_isp_exposure->cmos_ae.d_cycle = 0;
- XM_printf ("short bright Mode\n");
- }
- }
- /*else if(iso < 128 && p_ae.lumCurr >= 8)
- {
- p_isp_exposure->cmos_ae.d_cycle ++;
- p_isp_exposure->cmos_ae.n_cycle = 0;
- if(p_isp_exposure->cmos_ae.d_cycle > 5)
- {
- p_isp_exposure->cmos_ae.ae_mode = AE_MODE_BRIGHT;
- p_isp_exposure->cmos_ae.d_cycle = 0;
- XM_printf ("bright Mode\n");
- }
- }*/
- else
- {
- p_isp_exposure->cmos_ae.n_cycle = 0;
- p_isp_exposure->cmos_ae.d_cycle = 0;
- }
-
- }
-
- // 根据亮度校正特殊场景下的模式
- if(p_isp_exposure->cmos_ae.ae_mode == AE_MODE_BRIGHT)
- {
- // 检查必须为暗场模式的某些极端场景
- if(check_dark_mode(iso, &p_ae))
- {
- p_isp_exposure->cmos_ae.ae_mode = AE_MODE_DARK;
- p_isp_exposure->cmos_ae.n_cycle = 0;
- p_isp_exposure->cmos_ae.d_cycle = 0;
- XM_printf ("dark correct Mode\n");
- }
- }
- else if(p_isp_exposure->cmos_ae.ae_mode == AE_MODE_DARK)
- {
- // 检查逆光模式
- if(check_bl_mode(iso, &p_ae))
- {
- p_isp_exposure->cmos_ae.ae_mode = AE_MODE_BRIGHT;
- p_isp_exposure->cmos_ae.n_cycle = 0;
- p_isp_exposure->cmos_ae.d_cycle = 0;
- XM_printf ("bright correct Mode\n");
- }
- }
- }
- void isp_auto_exposure_initialize (auto_exposure_ptr_t p_ae_block)
- {
- p_ae_block->exposure_quant = 0x0080;
- p_ae_block->increment_offset = (1 << 8) * 16;
- p_ae_block->increment = p_ae_block->increment_offset;
- p_ae_block->increment_damping = 0; // 反相阻尼关闭
- p_ae_block->exposure_target = 0;
- p_ae_block->exposure_steps = 0;
- p_ae_block->exposure_factor = 1;
- p_ae_block->steady_control.enable = 0;
- p_ae_block->steady_control.count = 0;
- histogram_initialize (&(p_ae_block->histogram));
- }
- // 根据当前的直方图误差绝对值计算曝光增量的步长
- // 误差绝对值越大,步长越大
- static u32_t auto_exposure_increment_get (auto_exposure_ptr_t p_ae_block)
- {
- u32_t _step = p_ae_block->exposure_quant;
- if(abs(p_ae_block->histogram.hist_error) <= 0x4)
- {
- _step = p_ae_block->exposure_quant / 64;
- }
- else if(abs(p_ae_block->histogram.hist_error) <= 0x8)
- {
- _step = p_ae_block->exposure_quant / 32;
- //_step = p_ae_block->exposure_quant / 20;
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0x10)
- {
- //_step = p_ae_block->exposure_quant / 16;
- _step = p_ae_block->exposure_quant / 12;
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0x18)
- {
- //_step = p_ae_block->exposure_quant / 10;
- //_step = p_ae_block->exposure_quant / 5;
- _step = p_ae_block->exposure_quant / 3;
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0x20)
- {
- //_step = p_ae_block->exposure_quant / 5;
- //_step = p_ae_block->exposure_quant * 2 / 5; // 0.4
- _step = p_ae_block->exposure_quant * 1 / 2;
- //_step = p_ae_block->exposure_quant * 3 / 4; // 0.75
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0x30) // 48
- {
- //_step = p_ae_block->exposure_quant / 3;
- _step = p_ae_block->exposure_quant * 3 / 4; // 0.75
- //_step = p_ae_block->exposure_quant * 1;
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0x40) // 64
- {
- _step = p_ae_block->exposure_quant * 4 / 5 ;
- //_step = p_ae_block->exposure_quant * 3/2;
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0x50) // 80
- {
- _step = p_ae_block->exposure_quant * 1;
- //_step = p_ae_block->exposure_quant * 2;
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0x60) // 96
- {
- //_step = p_ae_block->exposure_quant * 3 / 2;
- _step = p_ae_block->exposure_quant * 5 / 4;
- //_step = p_ae_block->exposure_quant * 5/2;
- }
- // 定义太大的step可能导致曝光调整过大, 导致直方图错误位翻转(从正到负 或 从负到正), 导致曝光闪烁现象发生
- // 比如 下面实例允许大的步幅控制 (> 0x200)
- // hist_error --> -2357, step = 128(步幅过大), 减少曝光, 步幅调整过大, 新的曝光值 inttime= 61, again=1.000000, dgain=1.000000
- // hist_error --> 115, step = 16, 因为步幅调整过大,需要逐步增加曝光值, 新的曝光值 inttime= 64, again=1.000000, dgain=1.007813
- // ...
- // hist_error --> 5, step = 1, 曝光稳定, inttime= 91, again=1.000000, dgain=1.007813
- /*
- else if(abs(p_ae_block->histogram.hist_error) > 0x200)
- {
- _step = p_ae_block->exposure_quant * 8;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 0x100)
- {
- _step = p_ae_block->exposure_quant * 4;
- }*/
-
- else if(abs(p_ae_block->histogram.hist_error) < 0x70) // 112
- {
- //_step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 3;
- _step = p_ae_block->exposure_quant * 3/2;
- //_step = p_ae_block->exposure_quant * 4/3;
- }
- // 考虑下面的步幅过大,导致画面亮暗明显
- else if(abs(p_ae_block->histogram.hist_error) < 0x80)
- {
- //_step = p_ae_block->exposure_quant * 6/4;
- //_step = p_ae_block->exposure_quant * 7/2;
- _step = p_ae_block->exposure_quant * 2;
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0x90) // 144
- {
- // _step = p_ae_block->exposure_quant * 2;
- _step = p_ae_block->exposure_quant * 5/2;
- //_step = p_ae_block->exposure_quant * 3/2;
- //_step = p_ae_block->exposure_quant * 7/4;
- //_step = p_ae_block->exposure_quant * 4;
- }
-
- else if(abs(p_ae_block->histogram.hist_error) < 0xA0) // 160
- {
- //_step = p_ae_block->exposure_quant * 3/2;
- _step = p_ae_block->exposure_quant * 3;
- //_step = p_ae_block->exposure_quant * 5 / 2;
- //_step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 9/2;
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0xB0) // 176
- {
- //_step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 5;
- _step = p_ae_block->exposure_quant * 7/2;
- //_step = p_ae_block->exposure_quant * 5;
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0xC0) // 192
- {
- //_step = p_ae_block->exposure_quant * 3/2;
- //_step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 8;
- //_step = p_ae_block->exposure_quant * 5/2;
- //_step = p_ae_block->exposure_quant * 3;
- //_step = p_ae_block->exposure_quant * 6;
- _step = p_ae_block->exposure_quant * 4;
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0xD0) // 192
- {
- //_step = p_ae_block->exposure_quant * 3/2;
- //_step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 8;
- //_step = p_ae_block->exposure_quant * 5/2;
- //_step = p_ae_block->exposure_quant * 3;
- //_step = p_ae_block->exposure_quant * 13/2;
- _step = p_ae_block->exposure_quant * 9/2;
- }
- else if(abs(p_ae_block->histogram.hist_error) < 0xE0) // 192
- {
- //_step = p_ae_block->exposure_quant * 3/2;
- //_step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 8;
- //_step = p_ae_block->exposure_quant * 5/2;
- //_step = p_ae_block->exposure_quant * 3;
- //_step = p_ae_block->exposure_quant * 7;
- _step = p_ae_block->exposure_quant * 5;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 3000)
- {
- // _step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 20;
- _step = p_ae_block->exposure_quant * 30;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 2000)
- {
- // _step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 15;
- //_step = p_ae_block->exposure_quant * 25;
- _step = p_ae_block->exposure_quant * 27;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 1000)
- {
- // _step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 11;
- //_step = p_ae_block->exposure_quant * 18;
- _step = p_ae_block->exposure_quant * 21;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 900)
- {
- // _step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 9;
- //_step = p_ae_block->exposure_quant * 16;
- _step = p_ae_block->exposure_quant * 18;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 700)
- {
- // _step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 8;
- //_step = p_ae_block->exposure_quant * 10;
- //_step = p_ae_block->exposure_quant * 16;
- //_step = p_ae_block->exposure_quant * 12;
- _step = p_ae_block->exposure_quant * 15;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 600)
- {
- //_step = p_ae_block->exposure_quant * 6;
- //_step = p_ae_block->exposure_quant * 8;
- //_step = p_ae_block->exposure_quant * 14;
- //_step = p_ae_block->exposure_quant * 10;
- _step = p_ae_block->exposure_quant * 13;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 500)
- {
- //_step = p_ae_block->exposure_quant * 5;
- //_step = p_ae_block->exposure_quant * 7;
- //_step = p_ae_block->exposure_quant * 12;
- //_step = p_ae_block->exposure_quant * 8;
- _step = p_ae_block->exposure_quant * 12;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 400)
- {
- //_step = p_ae_block->exposure_quant * 4;
- //_step = p_ae_block->exposure_quant * 6;
- _step = p_ae_block->exposure_quant * 10;
- //_step = p_ae_block->exposure_quant * 7;
- //_step = p_ae_block->exposure_quant * 11;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 300)
- {
- //_step = p_ae_block->exposure_quant * 3;
- //_step = p_ae_block->exposure_quant * 5;
- //_step = p_ae_block->exposure_quant * 10;
- //_step = p_ae_block->exposure_quant * 6;
- _step = p_ae_block->exposure_quant * 8;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 0x100)
- {
- //_step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 3;
- //_step = p_ae_block->exposure_quant * 9;
- _step = p_ae_block->exposure_quant * 7;
- //_step = p_ae_block->exposure_quant * 5;
- }
- /*
- else if(abs(p_ae_block->histogram.hist_error) > 240)
- {
- //_step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 3;
- _step = p_ae_block->exposure_quant * 5;
- }
- else if(abs(p_ae_block->histogram.hist_error) > 220)
- {
- //_step = p_ae_block->exposure_quant * 2;
- _step = p_ae_block->exposure_quant * 3;
- //_step = p_ae_block->exposure_quant * 4;
- }*/
- else
- {
- // 0xA0 <= x >= 0x100
- // 2 ~ 2.5
- //XM_printf ("error=%d, _step=%d\n", p_ae_block->histogram.hist_error, _step);
- //_step = p_ae_block->exposure_quant * 9;
- //_step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant * 4;
- //_step = p_ae_block->exposure_quant * 8;
- _step = p_ae_block->exposure_quant * 6;
- }
-
- // 以下步幅降低一半会导致隧道进出适应缓慢,重新恢复为原来的步幅.
- //_step /= 2;
- //_step *= 2;
-
- return _step;
- }
- #undef XM_printf
- #define XM_printf(...)
- void auto_exposure_step_calculate (auto_exposure_ptr_t p_ae_block, cmos_exposure_ptr_t exp_cmos_block)
- {
- u32_t _step;
- u32_t _step_1st;
- u32_t ratio = 1;
- u8_t old_steady_enable = p_ae_block->steady_control.enable;
- _step = auto_exposure_increment_get (p_ae_block);
-
- _step_1st = _step;
- // 极端曝光条件修正
- // 1) 该修正在某些光照条件下容易触发振荡, 需要较长时间才能平稳.
- // 增加修正条件的阈值 16 --> 32
- // 2) 减小阶梯值
- if(p_ae_block->histogram.hist_error < (-32))
- {
- // 曝光严重过度, 能量主要集中在最右侧高光区 (0xC0 ~ 0xFF)
- if(p_ae_block->histogram.bands[4].value >= 0xF800)
- {
- // 将曝光量衰减75%, 32*0.75 = 24
- XM_printf ("SC-OV-0 0.75\r\n");
- _step = p_ae_block->exposure_quant * 8 * 3;
- }
- // 能量主要集中在高光区 (0x80 ~ 0xFF)
- else if( (p_ae_block->histogram.bands[3].value + p_ae_block->histogram.bands[4].value) >= 0xF800)
- {
- // 将曝光量衰减50%, 16/32 = 0.5
- XM_printf ("SC-OV-1 0.5\r\n");
- _step = p_ae_block->exposure_quant * 8 * 2 ;
- }
- // 能量主体集中在高光区 (0x80 ~ 0xFF)
- else if( (p_ae_block->histogram.bands[3].value + p_ae_block->histogram.bands[4].value) >= 0xE000)
- {
- // 将曝光量衰减43.75%, 14/32 = 0.4375
- XM_printf ("SC-OV-2 0.4375\r\n");
- _step = p_ae_block->exposure_quant * 7 * 2 ;
- }
- // 能量主体集中在高光区 (0x80 ~ 0xFF)
- else if( (p_ae_block->histogram.bands[3].value + p_ae_block->histogram.bands[4].value) >= 0xD000)
- {
- // 将曝光量衰减31.25%, 10/32 = 0.3125
- XM_printf ("SC-OV-2 0.3125\r\n");
- _step = p_ae_block->exposure_quant * 5 * 2 ;
- }
- // 能量主体集中在高光区 (0x80 ~ 0xFF)
- else if( (p_ae_block->histogram.bands[3].value + p_ae_block->histogram.bands[4].value) >= 0xC000)
- {
- // 将曝光量衰减25%, 8/32 = 0.25
- XM_printf ("SC-OV-2 0.25\r\n");
- _step = p_ae_block->exposure_quant * 4 * 2 ;
- }
- // 能量主体集中在高光区 (0x80 ~ 0xFF)
- else if( (p_ae_block->histogram.bands[3].value + p_ae_block->histogram.bands[4].value) >= 0xB000)
- {
- // 将曝光量衰减12.5%, 4/32 = 0.125
- XM_printf ("SC-OV-2 0.125\r\n");
- _step = p_ae_block->exposure_quant * 2 * 2 ;
- }
- // 能量主体集中在高光区 (0x80 ~ 0xFF)
- else if( (p_ae_block->histogram.bands[3].value + p_ae_block->histogram.bands[4].value) >= 0xA000)
- {
- // 将曝光量衰减9.375%, 3/32 = 0.09375
- XM_printf ("SC-OV-2 0.09375\r\n");
- _step = p_ae_block->exposure_quant * 3 ;
- }
- // 能量主体集中在高光区 (0x80 ~ 0xFF)
- else if( (p_ae_block->histogram.bands[3].value + p_ae_block->histogram.bands[4].value) >= 0x8000)
- {
- // 将曝光量衰减0.0625, 2/32 = 0.0625
- XM_printf ("SC-OV-2 0.0625\r\n");
- _step = p_ae_block->exposure_quant * 2 * 1 ;
- }
- // 低光区(0x00 ~ 0x3F)能量基本不存在, 低于2/256
- else if( (p_ae_block->histogram.bands[0].value + p_ae_block->histogram.bands[1].value) <= 0x0200 )
- {
- // 低光区(0x00 ~ 0x3F)能量基本不存在
- // 将整体曝光量衰减25%, 8 / 32 = 0.25
- XM_printf ("SC-OV-2 0.25\r\n");
- _step = p_ae_block->exposure_quant * 8 ;
- }
- // 低光区能量(0x00 ~ 0x0F)对曝光衰减速度的影响很低
- // 低光区(0x00 ~ 0x0F)能量基本不存在, 低于2/256
- // 这一条规则没有考虑低光区不存在的场景
- else if( (p_ae_block->histogram.bands[0].value ) <= 0x0200 )
- {
- // 低光区(0x00 ~ 0x0F)能量基本不存在
- // 将整体曝光量衰减1/32,
- XM_printf ("SC-OV-3 0.03125\r\n");
- _step = p_ae_block->exposure_quant * 1 ;
- }
- }
- else if(p_ae_block->histogram.hist_error > 32)
- {
- // 以下短曝光,高光处为0, 执行下面的高光曝光正补偿过程,可能导致闪烁问题。
- // 减小曝光阶梯为exposure_quant / 2,避免闪烁
- // ae_hist_error = 29
- // ae_sensor_inttime = 22
- // ae_sensor_again = 1.000000
- // ae_sensor_dgain = 1.000000
- // ae info histoGram :
- // [0] = 2789;
- // [1] = 923;
- // [2] = 383;
- // [3] = 0;
- // [4] = 0;
-
- // 曝光严重不足, 能量主要集中在低光区(0x00 ~ 0x3F)
- if( (p_ae_block->histogram.bands[0].value + p_ae_block->histogram.bands[1].value) >= 0xFF80 )
- {
- // 曝光量增加2倍 (*3), 即使溢出, 溢出的比例较低
- if(p_ae_block->histogram.bands[1].value <= 0x4000)
- {
- // 0x10 ~ 0x3F区域的能量较小
- //ratio = 8; // 1024 * 8
- _step = p_ae_block->exposure_quant * 4;
- //_step = p_ae_block->exposure_quant / 2;
- XM_printf ("SC-UE-0 2.00\r\n");
- }
- else
- {
- //ratio = 4; // 1024 * 4
- _step = p_ae_block->exposure_quant * 2;
- //_step = p_ae_block->exposure_quant / 2;
- XM_printf ("SC-UE-0 1.00\r\n");
- }
- }
- // 高光区 (0x80 ~ 0xFF)的比例很低
- // 将 中色调的区域(0x40~0x7F)映射到(0x80~0xC0)
- else if( (p_ae_block->histogram.bands[4].value + p_ae_block->histogram.bands[3].value) < 0x00C0 )
- {
- // 曝光量增加0.5倍. (*1.5)
- // 根据 中色调/低光 的比例决定放大倍数
- if(p_ae_block->histogram.bands[2].value <= 0x1000)
- {
- // 0.375
- //ratio = 3; // 2048
- _step = p_ae_block->exposure_quant * 4; // 1024
- //_step = p_ae_block->exposure_quant / 2;
- XM_printf ("SC-UE-1 0.375\r\n");
- }
- else if(p_ae_block->histogram.bands[2].value <= 0x2000)
- {
- // 0.25
- //ratio = 1; // 2048
- _step = p_ae_block->exposure_quant * 4; // 1024
- //_step = p_ae_block->exposure_quant / 2;
- XM_printf ("SC-UE-1 0.250\r\n");
- }
- else if(p_ae_block->histogram.bands[2].value <= 0x4000)
- {
- // 0.125
- //ratio = 1; // 2048
- _step = p_ae_block->exposure_quant * 2; // 512
- //_step = p_ae_block->exposure_quant / 2;
- XM_printf ("SC-UE-1 0.125\r\n");
- }
- else if(p_ae_block->histogram.bands[2].value <= 0x8000)
- {
- // 0.0625
- //ratio = 1; // 2048
- _step = p_ae_block->exposure_quant * 1; // 256
- //_step = p_ae_block->exposure_quant / 2;
- XM_printf ("SC-UE-1 0.0625\r\n");
- }
- else
- {
- }
- }
-
- // 最右侧高光区 (0xC0 ~ 0xFF)的比例很低
- // 高光区 (0xC0 ~ 0xFF)对曝光增强速度的影响非常有限
- else if( p_ae_block->histogram.bands[4].value < 0x00C0)
- {
- if(p_ae_block->increment < p_ae_block->increment_offset)
- {
- //
- }
- else
- {
- // 曝光量增加1/64
- //ratio = 1; // 2048
- _step = p_ae_block->exposure_quant/2; // 64
- XM_printf ("SC-UE-2 0.016\r\n");
- }
- }
-
- }
-
- if(_step < _step_1st)
- _step = _step_1st;
- /*
- // 曝光逆转过程增量衰减控制
- if(p_ae_block->increment > p_ae_block->increment_offset && p_ae_block->histogram.hist_error < 0)
- {
- // 曝光增加过程中,检测到曝光过度. (即曝光过程逆转, 曝光反相衰减中)
- // 将步长缩至计算增量的1/4
- _step = _step/4;
- // 进一步检查上面修正的步长是否大于最近的步长, 因为最近的步长导致曝光过程逆转,
- // 那么新的曝光反相衰减过程中, 步长应不大于最近的步长
- if(_step > (u32_t)p_ae_block->increment_step/2)
- _step = p_ae_block->increment_step/2;
- // 使能增量阻尼
- p_ae_block->increment_damping = 1;
- if(p_ae_block->steady_control.enable == 0)
- {
- if(p_ae_block->steady_control.count == 0)
- {
- // 保留当前的曝光参考
- p_ae_block->steady_control.steady_error = p_ae_block->histogram.hist_error;
- p_ae_block->steady_control.exposure = exp_cmos_block->last_exposure;
- }
- else if(abs(p_ae_block->steady_control.steady_error) > abs(p_ae_block->histogram.hist_error))
- {
- // 保留绝对值下的曝光参考
- p_ae_block->steady_control.steady_error = p_ae_block->histogram.hist_error;
- p_ae_block->steady_control.exposure = exp_cmos_block->last_exposure;
- }
- p_ae_block->steady_control.count ++;
- if(p_ae_block->steady_control.count >= 3)
- {
- p_ae_block->steady_control.count = 0;
- p_ae_block->steady_control.enable = 1;
- XM_printf ("\t\t Steady Enabel 0, error=%d, exposure=%d\r\n",
- p_ae_block->steady_control.steady_error,
- p_ae_block->steady_control.exposure);
- }
- }
- }
- else if(p_ae_block->increment < p_ae_block->increment_offset && p_ae_block->histogram.hist_error > 0)
- {
- // 曝光减少过程中,检测到曝光不够. (即曝光过程逆转, 曝光反相增加中)
- // 将步长缩至计算增量的1/4
- _step = _step/4;
- // 进一步检查上面修正的步长是否大于最近的步长, 因为最近的步长导致曝光过程逆转,
- // 那么新的曝光反相增长过程中, 步长应不大于最近的步长
- if(_step > (u32_t)p_ae_block->increment_step/2)
- _step = p_ae_block->increment_step/2;
- // 使能增量阻尼
- p_ae_block->increment_damping = 1;
- if(p_ae_block->steady_control.enable == 0)
- {
- if(p_ae_block->steady_control.count == 0)
- {
- // 保留当前的曝光参考
- p_ae_block->steady_control.steady_error = p_ae_block->histogram.hist_error;
- p_ae_block->steady_control.exposure = exp_cmos_block->last_exposure;
- }
- else if(abs(p_ae_block->steady_control.steady_error) > abs(p_ae_block->histogram.hist_error))
- {
- // 保留绝对值下的曝光参考
- p_ae_block->steady_control.steady_error = p_ae_block->histogram.hist_error;
- p_ae_block->steady_control.exposure = exp_cmos_block->last_exposure;
- }
- p_ae_block->steady_control.count ++;
- if(p_ae_block->steady_control.count >= 3)
- {
- p_ae_block->steady_control.count = 0;
- p_ae_block->steady_control.enable = 1;
-
- XM_printf ("\t\t Steady Enabel 1, error=%d, exposure=%d\r\n",
- p_ae_block->steady_control.steady_error,
- p_ae_block->steady_control.exposure);
- }
- }
- }
- else if(p_ae_block->increment_damping)
- {
- // 关闭增量阻尼
- _step = _step/2;
- p_ae_block->increment_damping = 0;
- if(p_ae_block->steady_control.enable == 0)
- p_ae_block->steady_control.count = 0;
- }
- else
- {
- if(p_ae_block->steady_control.enable == 0)
- p_ae_block->steady_control.count = 0;
- }
- */
- #if 0
- _step = _step / 16;
- if(_step < 1)
- _step = 1;
- #else
- //_step = (_step + 8) / 16;
- // _step = (_step + 4) / 8;
- if(_step < 1)
- _step = 1;
- #endif
- p_ae_block->increment_step = (u16_t)_step;
- p_ae_block->increment_ratio = (u16_t)ratio;
- if(p_ae_block->increment_offset < _step)
- p_ae_block->increment_min = 1;
- else
- p_ae_block->increment_min = p_ae_block->increment_offset - _step;
- p_ae_block->increment_max = p_ae_block->increment_offset + _step * ratio;
- if(p_ae_block->histogram.hist_error > 8)
- //if(p_ae_block->histogram.hist_error > 4)
- //if(p_ae_block->histogram.hist_error > 2)
- {
- // 直方图整体偏左, 增加曝光
- p_ae_block->increment = p_ae_block->increment_max;
- }
- else if(p_ae_block->histogram.hist_error < -8)
- //else if(p_ae_block->histogram.hist_error < -4)
- //else if(p_ae_block->histogram.hist_error < -2)
- {
- // 直方图整体偏右, 减少曝光
- p_ae_block->increment = p_ae_block->increment_min;
- }
- else
- {
- // 直方图整体平衡, 保持当前曝光值
- p_ae_block->increment = p_ae_block->increment_offset;
- }
- /*
- // 稳态控制过程下的解除稳态控制检查
- if(p_ae_block->steady_control.enable)
- {
- // 检查是否是进入稳态控制过程后的第一次曝光
- if(old_steady_enable == 1)
- {
- // 进入稳态控制过程后的非第一次曝光
- // 检查稳态控制曝光错误的边界阈值是否超出
- if( abs(p_ae_block->steady_control.steady_error - p_ae_block->histogram.hist_error) >= STEADY_CONTROL_AE_ERR_THREAD )
- {
- // 曝光错误误差已超出稳态控制的范围, 解除稳态控制
- // 关闭稳态控制
- p_ae_block->steady_control.enable = 0;
- p_ae_block->steady_control.count = 0;
- XM_printf ("\t\t Steady disable\r\n");
- }
- }
- }
- // 稳态控制过程下的曝光值及增量设定
- if(p_ae_block->steady_control.enable)
- {
- // 进入稳态状态过程后, 锁定稳态过程的每次曝光的曝光值为同一个曝光值设定, 这样避免曝光值非稳态导致的闪烁
- exp_cmos_block->exposure = p_ae_block->steady_control.exposure;
- // 锁定曝光增量为1
- p_ae_block->increment = p_ae_block->increment_offset;
- // XM_printf ("\t\t Steady Control, exposure=%d, inc=%d\r\n", exp_cmos_block->exposure, p_ae_block->increment);
- }
- */
- /*
- XM_printf ("\t\tstep = %4d, offset = %10d, max = %10d, min = %10d\n",
- _step,
- p_ae_block->increment_offset,
- p_ae_block->increment_max,
- p_ae_block->increment_min);
- */
- }
- static int cmos_exposure_get_error (cmos_exposure_ptr_t exp_cmos_block, int index)
- {
- if(exp_cmos_block->stat_count < AE_STAT_COUNT)
- return 0;
- index = exp_cmos_block->stat_index - 1 - index;
- if(index < 0)
- index += AE_STAT_COUNT;
- return exp_cmos_block->stat_error[index];
- }
- #define min(a,b) ((a < b) ? a : b)
- #define max(a,b) ((a > b) ? a : b)
- static int steady_ae_enable = 1; // AE稳态控制使能, 消除曝光振荡现象
- void cmos_exposure_set_steady_ae (int enable)
- {
- steady_ae_enable = enable;
- }
- extern isp_ae_t p_ae;
- static int auto_exposure_increment_calculate (auto_exposure_ptr_t p_ae_block, cmos_exposure_ptr_t exp_cmos_block)
- {
- //histogram_update(p_ae_block, &(p_ae_block->histogram), &p_ae);
- histogram_3x3_update (p_ae_block, &(p_ae_block->histogram), &p_ae);
-
- //isp_auto_exposure_compensation(p_ae_block, p_ae_block->histogram.bands);
-
- if(steady_ae_enable)
- {
- if(exp_cmos_block->stat_count < AE_STAT_COUNT)
- {
- exp_cmos_block->stat_error[exp_cmos_block->stat_count] = p_ae_block->histogram.hist_error;
- exp_cmos_block->stat_lum[exp_cmos_block->stat_count] = p_ae.lumCurr; // isp_ae_lum_read ();
- exp_cmos_block->stat_count ++;
- }
- else
- {
- unsigned int index = exp_cmos_block->stat_index;
- int error_0, error_1, error_2;
- int diff, min_error, max_error;
- exp_cmos_block->stat_error[index] = p_ae_block->histogram.hist_error;
- exp_cmos_block->stat_lum[index] = p_ae.lumCurr; //isp_ae_lum_read ();
- index ++;
- if(index >= AE_STAT_COUNT)
- index = 0;
- exp_cmos_block->stat_index = index;
-
- // 读取最近的AE错误值
- error_0 = cmos_exposure_get_error(exp_cmos_block, 0);
- error_1 = cmos_exposure_get_error(exp_cmos_block, 1);
- error_2 = cmos_exposure_get_error(exp_cmos_block, 2);
-
- // 20181023 检查异常情况
- // 1) 若整体hist_error_one与极小值hist_error_min极性一致,画面应存在较明显的过曝或者曝光不够,此时应立刻解除稳态控制,
- // 否则画面会出现明显偏暗的场景
- if(p_ae_block->histogram.hist_error_min < -6 && p_ae_block->histogram.hist_error_one < -6)
- {
- // 解除稳态控制
- exp_cmos_block->locked = 0;
- exp_cmos_block->locked_threshhold = 0;
- goto step_calc;
- }
- else if(p_ae_block->histogram.hist_error_min > 6 && p_ae_block->histogram.hist_error_one > 6)
- {
- // 解除稳态控制
- exp_cmos_block->locked = 0;
- exp_cmos_block->locked_threshhold = 0;
- goto step_calc;
- }
-
-
- // 检查稳态控制是否已应用
- if(exp_cmos_block->locked)
- {
- // 振荡保护中
- if(exp_cmos_block->locked_threshhold > 0)
- {
- if(error_0 > 0 && error_0 <= exp_cmos_block->locked_threshhold)
- {
- // 小于阈值, 被阻止
- XM_printf ("error = %d, locked_threshhold = %d, blocking\n", error_0, exp_cmos_block->locked_threshhold);
- return 1;
- }
- else
- {
- // 阻止解除
- XM_printf ("error = %d, locked_threshhold = %d, blocking leave\n", error_0, exp_cmos_block->locked_threshhold);
- exp_cmos_block->locked = 0;
- exp_cmos_block->locked_threshhold = 0;
- }
- }
- else
- {
- if(error_0 < 0 && error_0 >= exp_cmos_block->locked_threshhold)
- {
- // 大于阈值, 被阻止
- XM_printf ("error = %d, locked_threshhold = %d, blocking\n", error_0, exp_cmos_block->locked_threshhold);
- return 1;
- }
- else
- {
- // 阻止解除
- XM_printf ("error = %d, locked_threshhold = %d, blocking leave\n", error_0, exp_cmos_block->locked_threshhold);
- exp_cmos_block->locked = 0;
- exp_cmos_block->locked_threshhold = 0;
- }
- }
- }
- else
- {
- // 判断是否存在振荡
- if(error_0 > 0 && error_1 < 0 && error_2 > 0 )
- {
- // 振荡, 11, -29, 10
- exp_cmos_block->locked = 1;
- diff = abs(error_0 - error_2);
- max_error = max(error_0, error_2);
- exp_cmos_block->locked_threshhold = max_error + max(3, diff);
- if(exp_cmos_block->locked_threshhold > 255)
- {
- // 复位
- exp_cmos_block->stat_count = 0;
- exp_cmos_block->locked = 0;
- exp_cmos_block->locked_threshhold = 0;
- goto step_calc;
- }
- XM_printf ("error = %d, locked_threshhold = %d, blocking enter\n", error_0, exp_cmos_block->locked_threshhold);
- return 1;
- }
- else if(error_0 < 0 && error_1 > 0 && error_2 < 0 )
- {
- // 振荡, -9, 11, -11
- exp_cmos_block->locked = 1;
- diff = abs(error_0 - error_2);
- min_error = min(error_0, error_2);
- exp_cmos_block->locked_threshhold = min_error - max(3, diff);
- if(exp_cmos_block->locked_threshhold < -255)
- {
- // 复位
- exp_cmos_block->stat_count = 0;
- exp_cmos_block->locked = 0;
- exp_cmos_block->locked_threshhold = 0;
- goto step_calc;
- }
- XM_printf ("error = %d, locked_threshhold = %d, blocking enter\n", error_0, exp_cmos_block->locked_threshhold);
- return 1;
- }
- }
-
- }
- }
- step_calc:
- auto_exposure_step_calculate(p_ae_block, exp_cmos_block);
-
- return 0;
- }
- int isp_auto_exposure_run (auto_exposure_ptr_t ae_block, cmos_exposure_ptr_t exp_cmos_block, int man_exp)
- {
- i64_t i64_temp;
- u32_t new_physical_exposure; // 新的绝对(物理)曝光量
- int ae_stable = 1;
- if(man_exp == 1)
- {
- exp_cmos_block->exposure = ae_block->exposure_target;
- }
-
- exp_cmos_block->last_exposure = exp_cmos_block->exposure;
- // 估计曝光量
- int blocking = auto_exposure_increment_calculate(ae_block, exp_cmos_block);
- if(blocking)
- {
- return ae_stable;
- }
-
- if(man_exp == 1)
- {
- ae_block->increment = ae_block->increment_offset;
- }
- // 根据曝光量, 重新计算sensor的曝光参数
- isp_exposure_cmos_calculate (
- exp_cmos_block,
- ae_block->increment,
- ae_block->increment_max,
- ae_block->increment_min,
- ae_block->increment_offset
- );
- i64_temp = exp_cmos_block->cmos_inttime.exposure_ashort * exp_cmos_block->sys_factor;
- i64_temp *= exp_cmos_block->cmos_gain.again * exp_cmos_block->cmos_gain.dgain;
- i64_temp >>= (exp_cmos_block->cmos_gain.again_shift + exp_cmos_block->cmos_gain.dgain_shift);
- new_physical_exposure = (u32_t)i64_temp;
- // 20170102 zhuoyonghong
- // 为避免出现曝光不稳的现象, 不再执行逻辑曝光加速过程(循环执行逻辑曝光过程直至物理曝光出现差异).
- // 逻辑曝光过程的理论曝光值不等于实际的物理曝光量, 会引入误差(物理曝光量-理论曝光量).
- // 连续多次逻辑曝光过程产生的物理曝光量误差(物理曝光量-理论曝光量)会更大.
- // 因此取消该逻辑曝光加速过程, 每次逐步执行
- // 1)逻辑曝光量计算-->2)物理曝光量计算-->3)物理曝光 -->4曝光反馈
- // 的过程, 避免较大曝光量误差的引入. 较大曝光量误差会导致画面亮度抖动
- #if 0
- if(man_exp == 0)
- {
- // 自动曝光模式下
- //int loop = 16;
- int loop = 1;
- int same_exp = 0;
- // 循环直到物理曝光量存在变化
- while (loop > 0 && new_physical_exposure == exp_cmos_block->physical_exposure)
- {
- if(new_physical_exposure == exp_cmos_block->exp_llimit) // 最小曝光量
- break;
- // 使用与进入时同样的曝光量增量参数, 计算下一个理论的曝光量
- // auto_exposure_step_calculate (ae_block, exp_cmos_block);
- // 根据计算的理论曝光量, 重新计算sensor的曝光参数
- same_exp = isp_exposure_cmos_calculate (
- exp_cmos_block,
- ae_block->increment,
- ae_block->increment_max,
- ae_block->increment_min,
- ae_block->increment_offset
- );
- if(same_exp)
- break;
- //
- i64_temp = exp_cmos_block->cmos_inttime.exposure_ashort * exp_cmos_block->sys_factor;
- i64_temp *= exp_cmos_block->cmos_gain.again * exp_cmos_block->cmos_gain.dgain;
- i64_temp >>= (exp_cmos_block->cmos_gain.again_shift + exp_cmos_block->cmos_gain.dgain_shift);
- new_physical_exposure = (u32_t)i64_temp;
- loop --;
- }
- if(new_physical_exposure == exp_cmos_block->physical_exposure)
- {
- // 连续的绝对曝光量相同
- if( (ae_block->increment == ae_block->increment_offset)
- || (new_physical_exposure == exp_cmos_block->exp_llimit)
- || (exp_cmos_block->exposure == exp_cmos_block->exp_tlimit)
- || (same_exp == 1)
- )
- ae_stable = 1;
- else
- ae_stable = 0;
- }
- else
- ae_stable = 0;
- }
- #else
- // 比较新的物理曝光值与最近的值比较. 相同则认为曝光稳定
- if(exp_cmos_block->physical_exposure == new_physical_exposure)
- ae_stable = 1;
- else
- ae_stable = 0;
- #endif
- exp_cmos_block->physical_exposure = new_physical_exposure;
-
- /*
- XM_printf ("\t\tlog_exposure=%10d, inttime=%5d, again=%f, dgain=%f\n",
- (u32_t)new_physical_exposure,
- exp_cmos_block->cmos_inttime.exposure_ashort,
- ((float)exp_cmos_block->cmos_gain.again) / (1 << exp_cmos_block->cmos_gain.again_shift),
- ((float)exp_cmos_block->cmos_gain.dgain) / (1 << exp_cmos_block->cmos_gain.dgain_shift));
- */
- // 调整sensor的曝光参数
- exp_cmos_block->exposure_delay_cycle = isp_cmos_inttime_update (exp_cmos_block);
- return ae_stable;
- }
- #define MAX_EXPOSURE_LUTS 3
- static u16_t exposure_luts_defaults[MAX_EXPOSURE_LUTS][4] =
- {
- {0xA000, 0x1400, 0x0180, 0x0110 },
- {0x8000, 0x4000, 0x0800, 0x0100 },
- {0x2000, 0x3000, 0x0700, 0x0220 }
- };
- void auto_exposure_lut_load (auto_exposure_ptr_t p_ae_block, u8_t lut)
- {
- int i;
- if(MAX_EXPOSURE_LUTS <= lut)
- {
- return;
- }
- for(i=0;i<HISTOGRAM_BANDS;++i)
- {
- p_ae_block->histogram.bands[i].target = exposure_luts_defaults[lut][i];
- }
- }
|