https://www.freesion.com/article/4029747962/
https://wenku.baidu.com/view/d335e7da647d27284a7351b7.html
http://www.360doc.com/content/20/1105/13/67063969_944236154.shtml
sensor曝光分为逐行曝光和全局曝光。
逐行曝光的sensor 技术难度较全局曝光sensor 低,价格便宜,且分辨率较大,对于一些静态图像拍摄是不错的选择。
sensor逐行曝光基本原理
sensor逐行曝光从第一行开始曝光,一个行周期结束之后第二行才开始曝光。依次类推,经过N-1 行后第N 行开始曝光。第一行曝光结束后开始读出数据,读出一行需要一行周期时间。至第一行完全读出后,第二行刚好开始读出,依次类推,直到整幅图像完全读出。
sensor全局曝光基本原理
全局曝光Sensor的所有行同时开始曝光,并同时结束曝光,在曝光结束后,Sensor将所有电子从感光区转到存储区,之后逐行地读出像素数据。 这样曝光的好处是获得图像每一行的曝光时间比较一致,并且在拍摄运动物体时图像不会出现偏移和歪斜。
H_Blank :扫描完一行后,行与行之间的返回过程称为水平消隐, 也叫行消隐
V_Blank :扫描完一帧后,从图像的右下角返回到左上角的过程称为垂直消隐, 也叫场消隐
H_Blank = line length pck - visible pixel width = Line blank Time
V_Blank = frame length lines - visible pixel height = Frame blank Time
line_length = Line Length pck (表示一行的长度,包含H_Blank)
frame_length = Frame Length lines(一帧的行数,包含V_Blank)
pclk : 控制像素输出的时钟(MHz),表示是每个单位时间内采样的pixel数量,由MCLK经过PLL电路分频获得
fps = pclk / (frame_length * line_lenth) = 1 / (line_time * frame_length) (表示帧率)
line_time = line_length / pclk (表示曝光一行所需要的时间)
下面以hi1336 datasheet和驱动为例:
//hi1336_setting.h
0x0734, 0x4b04, pll_mdiv = 4b = 75; vt_sys_div2 = 00 = 1; pll_prediv = 0010 = 3 (ramp)
0x0736, 0xd8b0, clk_div = 00 = 1; vt_sys_div1 = 011 = 4 (ramp)
pclk = ramp_vt_sys_clk = 24 / pll_prediv * pll_mdiv / vt_sys_div1 / vt_sys_div2
= 24 /3 * 75 / 4 / 1 = 150 Mhz
...
//hi1336_sensor.c
static void set_dummy(void){
LOG_INF("dummyline = %d, dummypixels = %d\n",
imgsensor.dummy_line, imgsensor.dummy_pixel);
write_cmos_sensor(0x020e, imgsensor.frame_length & 0xFFFF);
write_cmos_sensor(0x0206, imgsensor.line_length/4);
}
从寄存器中可以计算出pclk,MTK平台上驱动中set_dummy会对line_length处理(有些除4,有些除8);
所以对应pclk也会对应处理乘上对应的倍数
.cap = {
.pclk = 600000000, // 150*4
.linelength = 6004,
.framelength = 3316,
.startx = 0,
.starty = 0,
.grabwindow_width = 4208,
.grabwindow_height = 3120,
.mipi_data_lp2hs_settle_dc = 85,
.max_framerate = 300,
.mipi_pixel_rate = 571200000,
},
.margin = 7,
.min_shutter = 7,
.mclk = 24,
.mipi_lane_num = SENSOR_MIPI_4_LANE,
//hi1336_setting.h
0x0730, 0x770f, pll_mdiv = 77 = 119; vt_sys_div2 = 00 = 1; pll_prediv = 0011 = 4 (mipi)
0x0732, 0xe0b0, clk_div1 = 00 = 1; clk_div2 = 00 = 1; vt_sys_div1 = 100 = 5 (mipi)
mipi_clk = mipi_bitrate_clk = 24 / pll_prediv * pll_mdiv / vt_sys_div1 / vt_sys_div2
= 24 / 4 * 119 / 1 / 1 = 714 Mhz
mipi_pixel_rate = mipi_clk * 2 / raw_bits * lane_number (MIPI P N信号)
= 714 * 2 / 10 * 4 = 571.2 Mhz
...
根据shutter判断frame_length需要写多少
exposure_line = shutter = frame_length - dummy_line;(dummy_line 填充VBlank的行, 用于调整帧率)
dummy_line = dummy_line > frame_offset ? dummy _line : frame_offset
min_shutter <= shutter <= frame_length - frame_offset (frame_offset:最小的dummy_line)
dummy_line = (pclk / fps / line_length) - frame_length
= (600000000 / 30 / 6004) - 3316 = 3331 - 3316 = 15
exposure_time = exposure_line * line_time
从datasheet中可以得知,写入fame_length和exposure_line的寄存器是24bit,即最大时0xffffff
所以理论曝光时间的最大值可以得出
exposure_time = (0xffffff - 7) * 10006 ns = 167s
在暗的情况下,会增加曝光时间增加补偿亮度,当曝光时间超过当前vts的时候,曝光时间超过一帧的时间,这样会引起帧率降低
若要保持帧率可以增加gain值,MTK上gain主要分为isp gain(digital gain) sensor gain(analog gain)
sensor gain + isp gain一般不能超过最大曝光时间,tunning调试AE曝光表参数中会有isp gain,一般最大在2x,
需要注意增加gain值都是优先使用analog gain,当analog gain增加到最大的时候,才会考虑使用digital gain
MTK平台上的write_shutter
static void write_shutter(kal_uint32 shutter){
...
spin_lock(&imgsensor_drv_lock);
if(shutter > imgsensor.min_frame_length - imgsensor_info.margin)
imgsensor.frame_length = shutter + imgsensor_info.margin;
else
imgsensor.frame_length = imgsensor.min_frame_length;
if(imgsensor.frame_length > imgsensor_info.max_frame_length)
imgsensor.frame_length = imgsensor_info.max_frame_length;
spin_unlock(&imgsensor_drv_lock);
...
}
[collectParsedStrategyCaptureInfo] App set shutter = 1000000 (us)(1 s)
[write_shutter] sshutter = 99930, imgsensor.frame_length = 99937, imgsensor.min_frame_length = 3331
[collectParsedStrategyCaptureInfo] App set shutter = 2000000 (us)(2 s)
[write_shutter] shutter = 199860, imgsensor.frame_length = 199867, imgsensor.min_frame_length = 3331
同样展讯平台上,参数例如
//Unisoc
#define SNAPSHOT_TRIM_X 0
#define SNAPSHOT_TRIM_Y 0
#define SNAPSHOT_TRIM_W 4208
#define SNAPSHOT_TRIM_H 3120
#define EX_MCLK 24
#define LANE_NUM 4
#define SNAPSHOT_MIPI_PER_LANE_BPS 1152
#define SHAPSHOT_LINE_TIME 10006
#define SNAPSHOT_FRAME_LENGTH 3328
SHAPSHOT_LINE_TIME = linelength / pclk linelength = 10006 ns / 150 Mhz = 1500.9 ≈ 1501
SNAPSHOT_MIPI_PER_LANE_BPS = 2 * mipi_clk = 2 * 714 = 1428 (Mbps/lane)
SNAPSHOT_FRAME_LENGTH = framelength = 3328
如果SHAPSHOT_LINE_TIME 错填的很大,会导致AE线性度fail,exposure_line变小,专业模式相同曝光时间下画面亮度会相差极大