(1)测试源码
这个测试项主要是测试不同的shutter和gain 组合,拍的照片亮度差异要小于range。
import os.path
import its.caps
import its.device
import its.image
import its.objects
import its.target
import matplotlib
from matplotlib import pylab
import numpy
IMG_STATS_GRID = 9 # find used to find the center 11.11%
NAME = os.path.basename(__file__).split('.')[0]
NUM_PTS_2X_GAIN = 3 # 3 points every 2x increase in gain
THRESHOLD_MAX_OUTLIER_DIFF = 0.1
THRESHOLD_MIN_LEVEL = 0.1
THRESHOLD_MAX_LEVEL = 0.9
THRESHOLD_MAX_LEVEL_DIFF = 0.045
THRESHOLD_MAX_LEVEL_DIFF_WIDE_RANGE = 0.06
THRESH_ROUND_DOWN_GAIN = 0.1
THRESH_ROUND_DOWN_EXP = 0.03
THRESH_ROUND_DOWN_EXP0 = 1.00
THRESH_EXP_KNEE = 6E6
def find_fit_and_check(chan, mults, values, thresh_max_level_diff):
"""Find line fit and check values.
Check for linearity. Verify sample pixel mean values are close to each
other. Also ensure that the images aren't clamped to 0 or 1
(which would make them look like flat lines).
Args:
chan: [0:2] RGB channel
mults: list of multiplication values for gain*m, exp/m
values: mean values for chan
thresh_max_level_diff: threshold for max difference
"""
m, b = numpy.polyfit(mults, values, 1).tolist()
max_val = max(values)
min_val = min(values)
//(14)求最大最小差值
max_diff = max_val - min_val
print 'Channel %d line fit (y = mx+b): m = %f, b = %f' % (chan, m, b)
print 'Channel max %f min %f diff %f' % (max_val, min_val, max_diff)
e_msg = 'max_diff: %.4f, THRESH: %.3f' % (
max_diff, thresh_max_level_diff)
//(15)判断差值是否小于range
assert max_diff < thresh_max_level_diff, e_msg
e_msg = 'b: %.2f, THRESH_MIN: %.1f, THRESH_MAX: %.1f' % (
b, THRESHOLD_MIN_LEVEL, THRESHOLD_MAX_LEVEL)
assert THRESHOLD_MAX_LEVEL > b > THRESHOLD_MIN_LEVEL, e_msg
for v in values:
e_msg = 'v: %.2f, THRESH_MIN: %.1f, THRESH_MAX: %.1f' % (
v, THRESHOLD_MIN_LEVEL, THRESHOLD_MAX_LEVEL)
assert THRESHOLD_MAX_LEVEL > v > THRESHOLD_MIN_LEVEL, e_msg
e_msg = 'v: %.2f, b: %.2f, THRESH_MAX_OUTLIER_DIFF: %.1f' % (
v, b, THRESHOLD_MAX_OUTLIER_DIFF)
assert abs(v - b) < THRESHOLD_MAX_OUTLIER_DIFF, e_msg
def get_raw_active_array_size(props):
"""Return the active array w, h from props."""
aaw = (props['android.sensor.info.preCorrectionActiveArraySize']['right'] -
props['android.sensor.info.preCorrectionActiveArraySize']['left'])
aah = (props['android.sensor.info.preCorrectionActiveArraySize']['bottom'] -
props['android.sensor.info.preCorrectionActiveArraySize']['top'])
return aaw, aah
def main():
"""Test that a constant exposure is seen as ISO and exposure time vary.
Take a series of shots that have ISO and exposure time chosen to balance
each other; result should be the same brightness, but over the sequence
the images should get noisier.
"""
mults = []
r_means = []
g_means = []
b_means = []
raw_r_means = []
raw_gr_means = []
raw_gb_means = []
raw_b_means = []
threshold_max_level_diff = THRESHOLD_MAX_LEVEL_DIFF
with its.device.ItsSession() as cam:
props = cam.get_camera_properties()
props = cam.override_with_hidden_physical_camera_props(props)
//(1)查询测试条件,平台是否支持测试项
its.caps.skip_unless(its.caps.compute_target_exposure(props))
sync_latency = its.caps.sync_latency(props)
process_raw = its.caps.raw16(props) and its.caps.manual_sensor(props)
debug = its.caps.debug_mode()
//(2)决定拍照Size
largest_yuv = its.objects.get_largest_yuv_format(props)
if debug:
fmt = largest_yuv
else:
match_ar = (largest_yuv['width'], largest_yuv['height'])
fmt = its.objects.get_smallest_yuv_format(props, match_ar=match_ar)
//(3)获取sensor的minSensitivity
e, s = its.target.get_target_exposure_combos(cam)['minSensitivity']
//(4)获取的ae target
s_e_product = s*e
//(5)获取exposureTimeRange和sensitivityRange
expt_range = props['android.sensor.info.exposureTimeRange']
sens_range = props['android.sensor.info.sensitivityRange']
m = 1.0
//(6)根据获取到的当前的ae target搭配支持的最小gain开始曝光,然后保持ae target不变,gain=gain*pow(2, 1.0 / 3) 递增,相应的减小shutter进行拍照
while s*m < sens_range[1] and e/m > expt_range[0]:
mults.append(m)
print 'start s:', s, 'm:', m, 'sens_range[1]:', sens_range[1]
s_test = round(s*m)
//(7)ae target不变,计算出对应的shutter
e_test = s_e_product / s_test
print 'Testing s:', s_test, 'e:', e_test
//(8)创建拍照请求,设置gain和shutter值,并且进行拍照
req = its.objects.manual_capture_request(
s_test, e_test, 0.0, True, props)
cap = its.device.do_capture_with_latency(
cam, req, sync_latency, fmt)
s_res = cap['metadata']['android.sensor.sensitivity']
e_res = cap['metadata']['android.sensor.exposureTime']
# determine exposure tolerance based on exposure time
if e_test >= THRESH_EXP_KNEE:
thresh_round_down_exp = THRESH_ROUND_DOWN_EXP
else:
thresh_round_down_exp = (
THRESH_ROUND_DOWN_EXP +
(THRESH_ROUND_DOWN_EXP0 - THRESH_ROUND_DOWN_EXP) *
(THRESH_EXP_KNEE - e_test) / THRESH_EXP_KNEE)
s_msg = 's_write: %d, s_read: %d, TOL=%.f%%' % (
s_test, s_res, THRESH_ROUND_DOWN_GAIN*100)
e_msg = 'e_write: %.3fms, e_read: %.3fms, TOL=%.f%%' % (
e_test/1.0E6, e_res/1.0E6, thresh_round_down_exp*100)
assert 0 <= s_test - s_res < s_test * THRESH_ROUND_DOWN_GAIN, s_msg
assert 0 <= e_test - e_res < e_test * thresh_round_down_exp, e_msg
s_e_product_res = s_res * e_res
request_result_ratio = float(s_e_product) / s_e_product_res
print 'Capture result s:', s_res, 'e:', e_res
img = its.image.convert_capture_to_rgb_image(cap)
//(9)保存拍照图片,并以照片45%作为起点,10%的面积计算R,G,B的值
its.image.write_image(img, '%s_mult=%3.2f.jpg' % (NAME, m))
tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
rgb_means = its.image.compute_image_means(tile)
# Adjust for the difference between request and result
//(10)保存得到的R,G,B的值
r_means.append(rgb_means[0] * request_result_ratio)
g_means.append(rgb_means[1] * request_result_ratio)
b_means.append(rgb_means[2] * request_result_ratio)
# do same in RAW space if possible
if process_raw and debug:
aaw, aah = get_raw_active_array_size(props)
fmt_raw = {'format': 'rawStats',
'gridWidth': aaw/IMG_STATS_GRID,
'gridHeight': aah/IMG_STATS_GRID}
raw_cap = its.device.do_capture_with_latency(
cam, req, sync_latency, fmt_raw)
r, gr, gb, b = its.image.convert_capture_to_planes(
raw_cap, props)
raw_r_means.append(r[IMG_STATS_GRID/2, IMG_STATS_GRID/2]
* request_result_ratio)
raw_gr_means.append(gr[IMG_STATS_GRID/2, IMG_STATS_GRID/2]
* request_result_ratio)
raw_gb_means.append(gb[IMG_STATS_GRID/2, IMG_STATS_GRID/2]
* request_result_ratio)
raw_b_means.append(b[IMG_STATS_GRID/2, IMG_STATS_GRID/2]
* request_result_ratio)
# Test 3 steps per 2x gain
//(11)gain值按照算法增加
m *= pow(2, 1.0 / NUM_PTS_2X_GAIN)
# Allow more threshold for devices with wider exposure range
//(12)如果m(即为gain)大于64的时候,差值放宽到0.06
if m >= 64.0:
threshold_max_level_diff = THRESHOLD_MAX_LEVEL_DIFF_WIDE_RANGE
# Draw plots
//(13)按照得到的G,R,B值来画图
pylab.figure('rgb data')
pylab.semilogx(mults, r_means, 'ro-')
pylab.semilogx(mults, g_means, 'go-')
pylab.semilogx(mults, b_means, 'bo-')
pylab.title(NAME + 'RGB Data')
pylab.xlabel('Gain Multiplier')
pylab.ylabel('Normalized RGB Plane Avg')
pylab.minorticks_off()
pylab.xticks(mults[0::NUM_PTS_2X_GAIN], mults[0::NUM_PTS_2X_GAIN])
pylab.ylim([0, 1])
matplotlib.pyplot.savefig('%s_plot_means.png' % (NAME))
if process_raw and debug:
pylab.figure('raw data')
pylab.semilogx(mults, raw_r_means, 'ro-', label='R')
pylab.semilogx(mults, raw_gr_means, 'go-', label='GR')
pylab.semilogx(mults, raw_gb_means, 'ko-', label='GB')
pylab.semilogx(mults, raw_b_means, 'bo-', label='B')
pylab.title(NAME + 'RAW Data')
pylab.xlabel('Gain Multiplier')
pylab.ylabel('Normalized RAW Plane Avg')
pylab.minorticks_off()
pylab.xticks(mults[0::NUM_PTS_2X_GAIN], mults[0::NUM_PTS_2X_GAIN])
pylab.ylim([0, 1])
pylab.legend(numpoints=1)
matplotlib.pyplot.savefig('%s_plot_raw_means.png' % (NAME))
for chan in xrange(3):
values = [r_means, g_means, b_means][chan]
find_fit_and_check(chan, mults, values, threshold_max_level_diff)
if process_raw and debug:
for chan in xrange(4):
values = [raw_r_means, raw_gr_means, raw_gb_means,
raw_b_means][chan]
find_fit_and_check(chan, mults, values, threshold_max_level_diff)
if __name__ == '__main__':
main()
备注:
- 步骤6,7,8是通过在请求中添加gain和shutter值来进行拍照;
- 步骤11,12是增大gain值的算法,当gain值大于64时,测试差值也由原来的0.045增大到0.06;
(2)请求参数gain和shutter
拍照的请求参数gain和shutter会通过3A下发到sensor drv,进而对出图生效:
static kal_uint32 feature_control(MSDK_SENSOR_FEATURE_ENUM feature_id,
UINT8 *feature_para,UINT32 *feature_para_len)
{
...
switch (feature_id) {
case SENSOR_FEATURE_SET_ESHUTTER:
set_shutter(*feature_data);
break;
case SENSOR_FEATURE_SET_GAIN:
set_gain((UINT16) *feature_data);
break;
...
}
//(1)set_gain函数
BASEGAIN = 64;
static kal_uint16 set_gain(kal_uint16 gain)
{
kal_uint16 reg_gain;
if (gain < BASEGAIN || gain > 16 * BASEGAIN) {
LOG_INF("Error gain setting");
if (gain < BASEGAIN)
gain = BASEGAIN;
//gain值最大可达1024
else if (gain > 16 * BASEGAIN)
gain = 16 * BASEGAIN;
}
reg_gain = gain2reg(gain);
spin_lock(&imgsensor_drv_lock);
imgsensor.gain = reg_gain;
spin_unlock(&imgsensor_drv_lock);
LOG_INF("gain = %d , reg_gain = 0x%x\n ", gain, reg_gain);
...
return gain;
}
static kal_uint16 gain2reg(const kal_uint16 gain)
{
#if 1
//根据sensor能力,实际的reg_gain最大可达240,从而可知gain最大可达1024
int reg_gain = 0;
reg_gain = 256-(100*256*64/gain)/100;
if (reg_gain <0)
{
reg_gain = 0;
}
if (reg_gain > 240)
{
reg_gain = 240;
}
return reg_gain;
#else
kal_uint8 iI;
for (iI = 0; iI < (MaxGainIndex-1); iI++) {
if(gain <= sensorGainMapping[iI][0]){
break;
}
}
return sensorGainMapping[iI][1];
#endif
}
//(2)set_shutter函数
static void set_shutter(kal_uint16 shutter)
{
unsigned long flags;
LOG_INF("shutter = %d", shutter);
spin_lock_irqsave(&imgsensor_drv_lock, flags);
imgsensor.shutter = shutter;
spin_unlock_irqrestore(&imgsensor_drv_lock, flags);
write_shutter(shutter);
}
(3)测试过程和结果展示
(A)测试成功的过程
//python tests/scene1_1/test_exposure.py camera=0 scenes=1_1
start s: 100 m: 1.0 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 100.0 e: 109913551.0 //拍照请求的gain和shutter值
Capturing 1 frame with 1 format [yuv]
Capture result s: 100 e: 109913000 //拍照图片获取的gain和shutter值
start s: 100 m: 1.25992104989 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 126.0 e: 87232976.9841
Capturing 1 frame with 1 format [yuv]
Capture result s: 126 e: 87232000
start s: 100 m: 1.58740105197 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 159.0 e: 69128019.4969
Capturing 1 frame with 1 format [yuv]
Capture result s: 159 e: 69128000
start s: 100 m: 2.0 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 200.0 e: 54956775.5
Capturing 1 frame with 1 format [yuv]
Capture result s: 200 e: 54956000
start s: 100 m: 2.51984209979 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 252.0 e: 43616488.4921
Capturing 1 frame with 1 format [yuv]
Capture result s: 252 e: 43616000
start s: 100 m: 3.17480210394 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 317.0 e: 34673044.4795
Capturing 1 frame with 1 format [yuv]
Capture result s: 317 e: 34673000
start s: 100 m: 4.0 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 400.0 e: 27478387.75
Capturing 1 frame with 1 format [yuv]
Capture result s: 400 e: 27478000
start s: 100 m: 5.03968419958 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 504.0 e: 21808244.246
Capturing 1 frame with 1 format [yuv]
Capture result s: 504 e: 21808000
start s: 100 m: 6.34960420787 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 635.0 e: 17309220.6299
Capturing 1 frame with 1 format [yuv]
Capture result s: 635 e: 17309000
start s: 100 m: 8.0 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 800.0 e: 13739193.875
Capturing 1 frame with 1 format [yuv]
Capture result s: 800 e: 13739000
start s: 100 m: 10.0793683992 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 1008.0 e: 10904122.123
Capturing 1 frame with 1 format [yuv]
Capture result s: 1008 e: 10904000
start s: 100 m: 12.6992084157 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 1270.0 e: 8654610.31496
Capturing 1 frame with 1 format [yuv]
Capture result s: 1270 e: 8654000
start s: 100 m: 16.0 sens_range[0]: 100 sens_range[1]: 2000 expt_range[0]: 100000
Testing s: 1600.0 e: 6869596.9375
Capturing 1 frame with 1 format [yuv]
Capture result s: 1600 e: 6869000
//测试成功的结果
Channel 0 line fit (y = mx+b): m = -0.000895, b = 0.263744
Channel max 0.266336 min 0.248863 diff 0.017474
Channel 1 line fit (y = mx+b): m = -0.001812, b = 0.502523
Channel max 0.506676 min 0.473412 diff 0.033264
Channel 2 line fit (y = mx+b): m = -0.001107, b = 0.312942
Channel max 0.315233 min 0.294373 diff 0.020860
(B)测试Fail的过程
//python tests/scene1_1/test_exposure.py camera=0 scenes=1_1
start s: 100 m: 1.0 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 100.0 e: 100596412.0
Capturing 1 frame with 1 format [yuv]
Capture result s: 100 e: 100596000
start s: 100 m: 1.25992104989 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 126.0 e: 79838422.2222
Capturing 1 frame with 1 format [yuv]
Capture result s: 126 e: 79838000
start s: 100 m: 1.58740105197 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 159.0 e: 63268183.6478
Capturing 1 frame with 1 format [yuv]
Capture result s: 159 e: 63268000
start s: 100 m: 2.0 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 200.0 e: 50298206.0
Capturing 1 frame with 1 format [yuv]
Capture result s: 200 e: 50298000
start s: 100 m: 2.51984209979 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 252.0 e: 39919211.1111
Capturing 1 frame with 1 format [yuv]
Capture result s: 252 e: 39919000
start s: 100 m: 3.17480210394 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 317.0 e: 31733883.9117
Capturing 1 frame with 1 format [yuv]
Capture result s: 317 e: 31733000
start s: 100 m: 4.0 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 400.0 e: 25149103.0
Capturing 1 frame with 1 format [yuv]
Capture result s: 400 e: 25149000
start s: 100 m: 5.03968419958 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 504.0 e: 19959605.5556
Capturing 1 frame with 1 format [yuv]
Capture result s: 504 e: 19959000
start s: 100 m: 6.34960420787 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 635.0 e: 15841954.6457
Capturing 1 frame with 1 format [yuv]
Capture result s: 635 e: 15841000
start s: 100 m: 8.0 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 800.0 e: 12574551.5
Capturing 1 frame with 1 format [yuv]
Capture result s: 800 e: 12574000
start s: 100 m: 10.0793683992 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 1008.0 e: 9979802.77778
Capturing 1 frame with 1 format [yuv]
Capture result s: 1008 e: 9979000
start s: 100 m: 12.6992084157 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 1270.0 e: 7920977.32283
Capturing 1 frame with 1 format [yuv]
Capture result s: 1270 e: 7920000
start s: 100 m: 16.0 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 1600.0 e: 6287275.75
Capturing 1 frame with 1 format [yuv]
Capture result s: 1600 e: 6287000
start s: 100 m: 20.1587367983 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 2016.0 e: 4989901.38889
Capturing 1 frame with 1 format [yuv]
Capture result s: 2016 e: 4989000
start s: 100 m: 25.3984168315 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 2540.0 e: 3960488.66142
Capturing 1 frame with 1 format [yuv]
Capture result s: 2540 e: 3960000
start s: 100 m: 32.0 sens_range[0]: 100 sens_range[1]: 4000 expt_range[0]: 100000
Testing s: 3200.0 e: 3143637.875
Capturing 1 frame with 1 format [yuv]
Capture result s: 3200 e: 3143000
Channel 0 line fit (y = mx+b): m = -0.004096, b = 0.276796
Channel max 0.264993 min 0.124147 diff 0.140846
Traceback (most recent call last):
File "tests/scene1_1/test_exposure.py", line 221, in <module>
main()
File "tests/scene1_1/test_exposure.py", line 213, in main
find_fit_and_check(chan, mults, values, threshold_max_level_diff)
File "tests/scene1_1/test_exposure.py", line 62, in find_fit_and_check
assert max_diff < thresh_max_level_diff, e_msg
AssertionError: max_diff: 0.1408, THRESH: 0.045
可以看到如上的结果是超过给定的range,从而导致Fail,这种一般会修改tuning效果文件和metadata文件,metadata一般修改如下几个配置项。
//config_static_metadata.sensor.bf2253lmipiraw.h
//获取灵敏度SENSITIVITY的最大最小值
CONFIG_METADATA_BEGIN(MTK_SENSOR_INFO_SENSITIVITY_RANGE)
CONFIG_ENTRY_VALUE(100, MINT32)
CONFIG_ENTRY_VALUE(1600, MINT32)
CONFIG_METADATA_END()
CONFIG_METADATA_BEGIN(MTK_SENSOR_INFO_EXPOSURE_TIME_RANGE)// 1 us - 30 sec
CONFIG_ENTRY_VALUE( 100000L, MINT64)
CONFIG_ENTRY_VALUE(400000000L, MINT64)
CONFIG_METADATA_END()
CONFIG_METADATA_BEGIN(MTK_SENSOR_INFO_MAX_FRAME_DURATION)// 30 sec
CONFIG_ENTRY_VALUE(400000000L, MINT64)
CONFIG_METADATA_END()
//灵敏度的最大值
CONFIG_METADATA_BEGIN(MTK_SENSOR_MAX_ANALOG_SENSITIVITY)
CONFIG_ENTRY_VALUE(400, MINT32)
CONFIG_METADATA_END()
备注:这里需要注意一点,测试脚本当中的判断条件sens_range[1]即获取的是灵敏度MTK_SENSOR_MAX_ANALOG_SENSITIVITY的最大值配置。
- 配置的是100,到脚本中会变成1000,从而测试到8倍gain(800)//会有CTS Fail,因为要求最大值比最小值要大,现在最小值也是100
- 配置的是200,到脚本中会变成2000,从而测试到16倍gain(1600)
- 配置的是400,到脚本中会变成4000,从而测试到32倍gain(3200)
(4)测试成功和失败案例
(A)成功案例
//测试成功结果
Channel 0 line fit (y = mx+b): m = 0.000115, b = 0.301613
Channel max 0.313877 min 0.296713 diff 0.017164
Channel 1 line fit (y = mx+b): m = 0.000163, b = 0.513307
Channel max 0.531636 min 0.501918 diff 0.029718
Channel 2 line fit (y = mx+b): m = 0.000123, b = 0.303716
Channel max 0.316307 min 0.297863 diff 0.018444
(B)失败案例
可以看到第一个点曝光太明显从而导致Fail。
分析如下:
//(1)从main log看,Afe这个值一般不能低于1024的(该值在AeMgr为1024base,1024代表1x gain),怀疑这里低于1024的时候设给sensor_driver会出问题
D ae_mgr : [updateAEInfo2ISP()] State:10 eAEstate:0 VDNum:0 Exp/Afe/Isp/ISO:10000/853/1024/100 CurrentidxF:99 DisableOBC:0 FrameRate:300.000 FrameDuration:33350000 Flare offset/gain:0/512 ExpRatio:100
//(2)从sensor的kernel log来看:
//进行该项测试之前
23389 02-08 10:07:03.548 <4>[ 450.465098] (3)[6746:HwBinder:693_5]bf2253L_camera_sensor[set_shutter] Exit! shutter = 1112, framelength = 1236
23391 02-08 10:07:03.549 <4>[ 450.465136] (3)[6746:HwBinder:693_5]bf2253L_camera_sensor[set_gain] gain=1520, reg_gain=0x17
//第一帧
23434 02-08 10:07:03.647 <4>[ 450.563146] (1)[13685:3AEventThd]bf2253L_camera_sensor[set_shutter] Exit! shutter = 4636, framelength = 4636
//第二帧
23619 02-08 10:07:04.305 <4>[ 451.221480] (1)[13748:3AEventThd]bf2253L_camera_sensor[set_shutter] Exit! shutter = 3680, framelength = 3680
23621 02-08 10:07:04.305 <4>[ 451.221539] (2)[0:swapper/2]bf2253L_camera_sensor[set_gain] gain=1072, reg_gain=0x10
//第三帧
23796 02-08 10:07:04.937 <4>[ 451.854108] (0)[13812:3AEventThd]bf2253L_camera_sensor[set_shutter] Exit! shutter = 2916, framelength = 2916
23798 02-08 10:07:04.938 <4>[ 451.854175] (1)[0:swapper/1]bf2253L_camera_sensor[set_gain] gain=1344, reg_gain=0x14
//第四帧
23973 02-08 10:07:05.550 <4>[ 452.466240] (1)[13875:3AEventThd]bf2253L_camera_sensor[set_shutter] Exit! shutter = 2318, framelength = 2318
23975 02-08 10:07:05.550 <4>[ 452.466291] (0)[0:swapper/0]bf2253L_camera_sensor[set_gain] gain=1696, reg_gain=0x1a
//由于在测试过程中afe gain是逐帧提升的,因此只有第一帧会出现低于1024的情况,从log看对应第一帧的时候并没有触发set_gain,因此合理怀疑是当帧使用了进行测试前上一帧的"gain=1520",所以过曝。
//(3)当前要查出现afe gain低于1024的原因,
//需要从ae_mgr的code来看(vendor/mediatek/proprietary/hardware/mtkcam/aaa/source/isp_30/ae_mgr/):
MUINT32 u4MinIsoGain = m_p3ANVRAM->rAENVRAM[m_u4AENVRAMIdx].rDevicesInfo.u4MiniISOGain;
u4ISOValue = m_SensorQueueCtrl.rSensorParamQueue[m_SensorQueueCtrl.uOutputIndex].u4Sensitivity;
u4ISPGain = 1024;
if (m_p3ANVRAM != NULL)
{
//通过u4ISOValue和u4MinIsoGain来计算得到m_u4UpdateGainValue的变化值
m_u4UpdateGainValue = (u4ISOValue * 1024) / u4MinIsoGain;
if (m_u4UpdateGainValue > u4MaxGain)
{
u4ISPGain = 1024 * m_u4UpdateGainValue / u4MaxGain;
m_u4UpdateGainValue = u4MaxGain;
}
}
else
{
AE_LOG("[%s] NVRAM is NULL\n", __FUNCTION__);
m_u4UpdateGainValue = 1024;
}
//将变化值m_u4UpdateGainValue赋值给Afe gain,就和上面的Log对应上了
rAEInfo2ISP.u4AfeGain = m_u4UpdateGainValue;
最终的原因就是metadata配置的最小gain(u4MinIsoGain)是100,而tuning配置的是120,二者不一致导致的。
//tuning文件里配置的是120(camera_ae_tuning_para_xxx_bf2253Lmipiraw.cpp):
static AE_DEVICES_INFO_T g_rDevicesInfo =
{
1024, // u4MinGain
10856, // u4MaxGain
120, // u4MiniISOGain
//而metadata里配置的是100:
android.sensor.info.sensitivityRange (f0001): int32[2]
[100 6000 ]