Camera ITS当中的test_exposure测试

(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 ]
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪舞飞影

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值