[Camera效果] 高通 429 AF 调试简述

本文来自于我的前同事-小卢,一个很有个性,能力又不错的年轻小伙子!
(文章已经得他本人同意分享)

高通 429 AF 调试简述

本文从 OTP、actuator driver、AF algo 多个方面阐述 429 AF 的原理,并对平台的相关原理表达自己的看法

反差对焦(Contract Auto Focus)

反差对焦三要素
1、对焦范围
2、对焦结束条件
3、对焦重新触发条件

1、对焦范围

1.1 AF Driver & EEPROM

马达的最大行程为 1~1024(dac),actuator driver 中由 initial_code 和 step_bound[1]、step_bound[0] 共同决定。
即 actuator search range = [initial_code+step_bound[1], initial_code+step_bound[0]]

step_bound 越大,initial_code 越小,那么搜索范围就越大。但是搜索范围越大,会造成对焦时间越长。因此高通通过 OTP/EEPROM 实现模组对焦范围的差异控制。

OTP/EEPROM 中会(水平/垂直)烧录 infinity code 和 macro code,距离由客户定义,这里假定 infinity 取 10M 距离,macro 取 7cm 距离,烧录方向为水平烧录。且对于 golden 模组,infinity = 400,macro = 800。

那么该 golden 模组的对焦范围就是 400~800;由于烧录方向为水平,因此考虑到垂直向上、垂直向下的极限对焦情况,建议扩大 10% 对焦范围。

1、使用 Golden 模组填写 actuator driver 的 initial_code 和 step_bound
2、填写对应 eeprom_lib.h 的 inf_margin 和 mac_margin

inf_margin = -0.1, mac_margin = 0.1
total_steps = macro - infinity

initial_code = infinity + total_steps * inf_margin

step_bound = total_steps * (1+ |inf_margin| + |mac_margin|)

eeprom.c 会根据 margin 改变 infinity,eeprom_util.c 会再根据 infinity 重写 initial_code,以此来达到 eeprom 较正的目的

dac_range = afcalib_data->macro_dac - afcalib_data->infinity_dac;
afcalib_data->infinity_dac +=
              afcalib_data->infinity_margin * (float)dac_range;
afcalib_data->macro_dac +=
              afcalib_data->macro_margin * (float)dac_range;
......
af_driver_tune->initial_code = ectrl->eeprom_data.afc.infinity_dac;

这里提个伏笔,高通老架构(包括SDM660、SDM429等)都是只改变了 initial_code,而不改变 step_bound,个人看法这里是有问题的。因为 step_bound 代表对焦范围,每个模组的对焦范围都应根据烧录值作出改变。

1.2 AF Chromatix

驱动中的 infinity、mac 等等都是电流的逻辑表示,即 dac 值,其与 kernel 中的 current 是一 一对应的。高通在 Chromatix 中不直接使用电流的逻辑表示,而是改用镜头位置的逻辑表示,即 lens_pos,目的应该是为了解耦。

1.2.1 far end、near end

在 AF Driver、EEPROM 都正常填写后,接下来需要先修改 3a chromatix 中的 position_far_end。高通使用 far_end 将 lens_pos 与 dac 联系起来。

position_far_end = step_bound - 1
dac = position_far_end + initial_code - lens_pos

		 472,	/* Position Far End */
		 0, 	/* Position Near End */
		/* CAF Mode */
         {
    
    
            0, /* AF Search Limit CAF Enable */
            0, /* AF Search Limit CAF Near End */
            472, /* AF Search Limit CAF Far End */
            472, /* AF Search Limit CAF Default Pos */
         },

1、AF Algo 计算出 lens_pos;
2、经公式转换,向 actuator 传递转换后的 dac;
3、actuator 向 kernel 传递 dac,再在 kernel 中换算成 current,进而推动镜头。

1.2.2 fullsweep & _single_index_t

设置好 far_end、near_end 后,需要进行 fullsweep 测出指定记录下的 lens_pos

typedef enum _single_index_t
2372{
    
    
2373    SINGLE_NEAR_LIMIT_IDX    = 0,
2374    SINGLE_7CM_IDX           = 1,
2375    SINGLE_10CM_IDX          = 2,
2376    SINGLE_14CM_IDX          = 3,
2377    SINGLE_20CM_IDX          = 4,
2378    SINGLE_30CM_IDX          = 5,
2379    SINGLE_40CM_IDX          = 6,
2380    SINGLE_50CM_IDX          = 7,
2381    SINGLE_60CM_IDX          = 8,
2382    SINGLE_120CM_IDX         = 9,
2383    SINGLE_HYP_F_IDX         = 10,
2384    SINGLE_INF_LIMIT_IDX     = 11,
2385    SINGLE_MAX_IDX           = 12,
2386} single_index_t; //TODO : Chage to Enum Capital
 /* Index */
         {
    
    
            0, 21, 69, 229, 275, 331, 353, 363, 371, 401,
            421, 472
         },

Index 中只需要填写 12 个数据,分别对应 near_end ~ far_end

开启 fullsweep & AF log

adb root
adb remount
adb shell setprop vendor.debug.camera.af_fullsweep 1
adb shell setprop persist.vendor.camera.stats.af.debug 6

1.2.3 optic information

高通使用一些 optic index 映射 Index 中的数组下标,用于 AF Algo 的相关算法。例如 fine search 的范围,mid zone、Init pos 用于调整搜索方向,search region 用于区分 step size 等等。

/* Optics */
         {
    
    
            11, /* CAF Far End */
            0, /* CAF Near End */
            11, /* TAF Far End */
            0, /* TAF Near End */
            7, /* Search Region 1 */
            4, /* Search Region 2 */
            3, /* Search Region 3 */
            5, /* Fine Search Region */ 
            11, /* Far Zone */
            2, /* Near Zone */
            8, /* Mid Zone */
            10, /* Far Start Position */
            2, /* Near Start Position */
            11, /* Initial Position */
         },

1.2.4 thresholds

建议使用 hw thresholds(sw thresholds 会占用很多 CPU 资源,且容易丢 log)

0, /* PAAF Enable */

hw thresholds 中目前使用的不多,有以下几个

1.020000f, /* Flat Inc Threshold */
0.980000f, /* Flat DeC Threshold */
/* Flat Threshold */
{
    
    
    0.970000f, 0.970000f, 0.970000f, 0.970000f, 0.970000f, 0.970000f, 0.970000f, 0.970000f
}

当 AF 搜索超过 3 frames 后,会开始计算每一帧的 change_ratio
change_ratio = cur_fv/pre_fv

if(change_ratio > Flat Dec Threshold || change_ratio < Flat Inc Threshold){
    
    
	result = 3; // Flat
}else if (change_ratio < Flat Dec Threshold){
    
    
	result = 2; // Decrese
}else if (change_ratio > Flat Inc Threshold){
    
    
	result = 1; // Increase
}

AF Algo 会根据连续三帧的 result 判断当前趋势是 INCREASE、DECREASE、FLAT 还是 PEAK;
如果是 INCREASE 或者 FLAT,则会继续搜索,直到超出边界;
如果是 DECREASE,则会改变方向搜索,如果已经改变过一次,则会结束搜索;
如果是 PEAK,则会直接结束搜索。

默认下 SDM429 不支持修改 Flat Inc/Dec threhshold,高通直接在 3a core 中使用宏定义,但由于某些需求,已让高通提供 patch,目前能正常修改 hw thresholds

在搜索结束后,会再次计算 drop = fv_min/fv_max,用于判定整体曲线是否为 FLAT CURVE

if(drop < Flat Threshold){
    
    
	final pos = lens_pos(max_fv);  
}else if(drop >= Flat Threshold){
    
    
	...// other conditions
	final pos = hyperfocus;
}

1.2.5 step size

高通将对焦范围划分为 5 个区域,每个区域可以使用不同的 step size

			/* Prescan Normal Light */
            {
    
    
               20, /* Region 0 */
               12, /* Region 1 */
               12, /* Region 2 */
               16, /* Region 3 */
               18, /* Region 4 */
            },

一定范围内,step size 越大,对焦速度越快,准确率越低

Region 0 和 Region 4 建议使用稍大的 step size,Region 1、2、3 使用稍小的 step size

1.2.6 fine search

在 CAF 结束后,如果 final pos 在 [fine_search_region, far_end] 之间,则会进入 fine search,使用另一组 step size,继续搜索一轮 peak。

fine search 优势在于提高了对焦准确率,缺点是增加了对焦时间。

			5, /* Fine Search Region */ 
			/* Finescan Normal Light */
            {
    
    
               10, /* Region 0 */
               8, /* Region 1 */
               8, /* Region 2 */
               8, /* Region 3 */
               12, /* Region 4 */
            },

2、对焦结束条件

如 1.2.4 所述,关键在于判断 change_ratio 和对应的 threshold。

3、触发条件

CAF 使用 SAD 和 GYRO 来判断是否触发 AF,这里仅讨论 SAR。

默认情况下,CAF 使用 SADR 检测场景变化,SAD 检测场景平移。
当scene_change = 1 && scene_stable = 1 时,refocus = 1。
SADR 与 SAD 被封装成 AF monitor。

AF monitor 使用 Monitor Algo Config 控制 SADR/SAD 的 sensitivity,在 Value Monitor Bank 中 根据 sensitivity 选择调用 low/high/medium sensi 中的参数。
可直接设置 SADR/SAD sensitivity = 50,然后直接修改 medium sensitivitiy 中的阈值。

SARD 和 SAD 的输出会经过两个滤波器(可选)。

input -> median filter -> moving avg filter -> output

再根据 output 与参数中的阈值去比较。

if(metafilter >= threshold){
    
    
	cnt++;
}
if(cnt >= count threshold){
    
    
	decision = 1;
}else{
    
    
	decision = 0;
}

调试建议:优先按照 1.1、1.2.1、1.2.2、1.2.3 的步骤完成,其余可先使用默认参数

混合对焦(Hybrid Auto Focus)

反差对焦虽然比较准确,但是搜索步数较多,因此可以通过添加其他 feature 弥补 CAF 的不足,例如 PDAF。

HAF 先使用 PDAF 找到一次 peak,然后再在 peak 点附近进行一次 CAF,最终得出 final pos。为确保 HAF 正常计算 final pos,必须保证 PDAF 正常。

PD 趋势验证

driver 需要正确实现 eeprom,并且保证 pd 坐标正确配置。Tuning 可用一下方法确认 PD 的正确性。

1、关闭 PD,完成 CAF 的一般步骤;
2、打开 PD,对着细节充足的明亮场景(灯箱内使用 ISO Chart 即可),距离为 30cm 左右,进行 fullsweep,同时录制 log;
3、提取 defocus 和 lens_pos 数据,以 lens_pos 为横坐标,defocus 为纵坐标,绘制曲线;

横坐标从 far_end -> near_end,且曲线应满足以下条件:
1、与 x 轴只有一个交点;
2、曲线在一定范围内是单调递增的;
3、defocus 在 near_end 附近足够大,一般大于 300.

有任一条件不满足,则应检查 PD driver。

sensor vendor 可通过 raw 数据确认 PD 坐标

PD 行为分析

与 CAF 类似,PD 也可拆分成三部分理解:

  • PD 步长
  • PD 结束条件
  • PD 触发条件

1、PD 步长(focus table)

target_pos = cur_pos + defocus * focus_pcnt

可调整 focus_pcnt 来控制 PD 的步长,一定范围内,pcnt 越大,对焦越快

/* Focus Table */
            {
    
    
               5, /* Number of Entries */
               /* Entries */
               {
    
    
                  /* Entry 0 */
                  {
    
    
                     0, /* Defocus */
                     0.900000f, /* Move Percent */
                  },
                  /* Entry 1 */
                  {
    
    
                     20, /* Defocus */
                     0.900000f, /* Move Percent */
                  },
                  /* Entry 2 */
                  {
    
    
                     48, /* Defocus */
                     0.800000f, /* Move Percent */
                  },
				...
				}

2、PD 结束条件(focus converge done && panning)

PD 结束有两个条件

  • defocus < Focus Done Threshold
  • scene is stable
2.1 Focus Done Threshold

理论上来说,defocus = 0 为 peak 点,因此高通会给 defocus 设置一个阈值 threshold,当 |defocus| - |next_move| < threshold,说明此时已经处于 peak 点,不需要再进行 PD search

考虑到 type 3 PD sensor 的准确性,Focus Done Threshold 建议设置在 10 以上

 10, /* Focus Done Threshold */
2.2 panning

如果某个场景已经满足 Focus Done 的条件,但是却仍然有场景变化,可以想象,此时结束 PD 跳转到 CAF 是不合适的。因此 AF 会考虑到 panning 的输出,当没有场景平移时,才会结束 PD

3、is_trig_refocus

PD refocus 有 4 个条件

  • is_conf = 1
  • is_defocused = 1
  • is_stable = 1
  • is_scene_changed = 1

is_conf 和 is_scene_changed 一般都满足,这里需要重点关注 is_defocused 和 is_stable

3.1 PD 触发条件(is_defocused)
if(|defocus| > defocus_thres){
    
    
	defocus_cnt++;
}else{
    
    
	defocus_cnt = 0;
}
if(defocus_cnt >= min_defocus_cnt){
    
     //min_defocus_cnt = min_stable_cnt
	is_defocused = 1;
}else{
    
    
	is_defocused = 0;
}
 15.00000f, /* Defocused Threshold */
 /* Stable Table */
        {
           3, /* Number of Entries */
           /* Entries */
           {
              /* Entry 0 */
              {
                 10, /* FPS */
                 0, /* Minimum Stable Count */
              },
              /* Entry 1 */
              {
                 14, /* FPS */
                 1, /* Minimum Stable Count */
              },
              /* Entry 2 */
              {
                 24, /* FPS */
                 2, /* Minimum Stable Count */
			......
			}
		}
3.2 is_stable

AF ALGO 会记录最近 3 帧的 defocus,并计算 delta_defocus

defocus history = {
    
    d1, d2, d3};
delta = max(history) - min(history);
if(delta <= Depth Stable Threshold){
    
    
	stable_cnt++;
}else{
    
    
	stable_cnt = 0;
}
if(stable_cnt >= min_stable_cnt){
    
    
	is_stable = 1;
}else{
    
    
	is_stable = 0;
}

参考文档:kba-170501033706_3

猜你喜欢

转载自blog.csdn.net/justXiaoSha/article/details/121485803
AF