Mtk Camera Hal到驱动的流程(3)

(1)Camera成像原理

(A)成像原理

  • 物体通过镜头(lens)生成的光学图像投射到图像传感器上(CMOS/CCD集成电路),把光信号转换为电信号;
  • 然后经过A/D(模数转换)转换后变为数字图像信号(图像处理器ISP处理);
  • 在送到数字信号处理器中处理(DSP)转换成标准的GRB、YUV等格式图像信号;

Mtk Camera Hal到驱动的流程(3)
(B)相机包含四大件

镜头(lens)、图像传感器(sensor)、图像处理器(ISP)、数字信号处理器(DSP)

  • 镜头(lens)是相机的灵魂,镜头(lens)对成像的效果有很重要的作用,是利用透镜的折射原理,景物光线通过镜头,在聚焦平面上形成清晰的影像,通过感光材料CMOS或CCD感光器记录景物的影像;
  • 图像传感器(sensor)是一种半导体芯片,其表面包含几十万到几百万的光电二极管,二极管受到光照时就会产生电荷。目前主要有两种CCD,一种是广泛使用的CCD(电荷藕合)元件,另一种是CMOS(互补金属氧化物导体)器件;
  • ISP的性能是决定是否流畅的关键;
  • 数字信号处理器(DSP)是将感光芯片获得的数据及时快速地传递到*处理器并刷新感光芯片,因此DSP芯片的好坏,直接影响画面品质(比如色彩饱和度,清晰度等);

(C)图像输出格式

常见的输出格式:YUV格式、RGB格式、Rawdata格式

  • YUV格式:"Y"表示明亮度 ,"U"和 "V"则是色度、浓度,一般情况下sensor支持YUV422格式,即数据格式是按Y-U-Y-V次序输出的;
  • RGB格式:传统的红绿蓝格式,比如RGB565/RGB8888,采用这种编码方法,每种颜色都可用三个变量来表示红色、绿色以及蓝色的强度。每一个像素有三原色R红色、G绿色、B蓝色组成;
  • 图像感应器将捕捉到的光源信号转化为数字信号的原始数据。RAW文件是一种记录了数码相机传感器的原始信息,同时记录了由相机拍摄所产生的一些原数据( Metadata,如ISO的设置、快门速度、光圈值、白平衡等)的文件;

(2)Sensor Drv结构

Mtk Camera Hal到驱动的流程(3)
首先看一下Sensor Drv相关的struct,这里以gc8034_mipi_raw为例。

(A)控制Flip + Mirror效果

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.h

#define  GC8034_MIRROR_NORMAL
#undef  GC8034_MIRROR_H
#undef  GC8034_MIRROR_V
#undef GC8034_MIRROR_HV

#if defined(GC8034_MIRROR_NORMAL)
	#define GC8034_MIRROR         0xc0
	#define GC8034_BinStartY      0x04
	#define GC8034_BinStartX      0x05
	#define GC8034_FullStartY     0x08
	#define GC8034_FullStartX     0x09
#elif defined(GC8034_MIRROR_H)
	#define GC8034_MIRROR         0xc1
	#define GC8034_BinStartY      0x04
	#define GC8034_BinStartX      0x05
	#define GC8034_FullStartY     0x08
	#define GC8034_FullStartX     0x0b
#elif defined(GC8034_MIRROR_V)
	#define GC8034_MIRROR         0xc2
	#define GC8034_BinStartY      0x04
	#define GC8034_BinStartX      0x05
	#define GC8034_FullStartY     0x08
	#define GC8034_FullStartX     0x09
#elif defined(GC8034_MIRROR_HV)
	#define GC8034_MIRROR         0xc3
	#define GC8034_BinStartY      0x04
	#define GC8034_BinStartX      0x05
	#define GC8034_FullStartY     0x08
	#define GC8034_FullStartX     0x0b
#else
	#define GC8034_MIRROR         0xc0
	#define GC8034_BinStartY      0x04
	#define GC8034_BinStartX      0x05
	#define GC8034_FullStartY     0x08
	#define GC8034_FullStartX     0x09
#endif

(B)struct imgsensor_mode_struct不同模式特征的结构体:这个结构体描叙了各个模式下的pclk/linelength/framelength 等。

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.h

enum{
	IMGSENSOR_MODE_INIT,
	IMGSENSOR_MODE_PREVIEW,
	IMGSENSOR_MODE_CAPTURE,
	IMGSENSOR_MODE_VIDEO,
	IMGSENSOR_MODE_HIGH_SPEED_VIDEO,
	IMGSENSOR_MODE_SLIM_VIDEO,
};

struct imgsensor_mode_struct {
	kal_uint32 pclk;                    /*record different mode's pclk*/
	kal_uint32 linelength;              /*record different mode's linelength*/
	kal_uint32 framelength;             /*record different mode's framelength*/
	kal_uint8  startx;                  /*record different mode's startx of grabwindow*/
	kal_uint8  starty;                  /*record different mode's startx of grabwindow*/
	kal_uint16 grabwindow_width;        /*record different mode's width of grabwindow*/
	kal_uint16 grabwindow_height;       /*record different mode's height of grabwindow*/
	/* following for MIPIDataLowPwr2HighSpeedSettleDelayCount by different scenario */
	kal_uint8  mipi_data_lp2hs_settle_dc;
	/* following for GetDefaultFramerateByScenario() */
	kal_uint32 mipi_pixel_rate;
	kal_uint16 max_framerate;
};

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c
static struct imgsensor_info_struct imgsensor_info = {
	.sensor_id = GC8034_SENSOR_ID,       /*record sensor id defined in Kd_imgsensor.h*/
	.checksum_value = 0x1b375588,		//0xa11f4e23,            /*checksum value for Camera Auto Test*/

	.pre = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,                /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85, /*unit, ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},

	.cap = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85, /*unit, ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},
	//...
};

对应的描叙信息如下:pclk ≈ linelength * frame_length * framerate。

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c

static kal_uint32 set_max_framerate_by_scenario(enum MSDK_SCENARIO_ID_ENUM scenario_id, MUINT32 framerate) 
{
	kal_uint32 frame_length;

	LOG_INF("scenario_id = %d, framerate = %d\n", scenario_id, framerate);

	switch (scenario_id) {
	case MSDK_SCENARIO_ID_CAMERA_PREVIEW:
		frame_length = imgsensor_info.pre.pclk / framerate * 10 / imgsensor_info.pre.linelength;
		spin_lock(&imgsensor_drv_lock);
		imgsensor.dummy_line = (frame_length > imgsensor_info.pre.framelength) ?
			(frame_length - imgsensor_info.pre.framelength) : 0;
		imgsensor.frame_length = imgsensor_info.pre.framelength + imgsensor.dummy_line;
		imgsensor.min_frame_length = imgsensor.frame_length;
		spin_unlock(&imgsensor_drv_lock);
    	if(imgsensor.frame_length > imgsensor.shutter)
		{
			set_dummy();
		}
		break;
	case MSDK_SCENARIO_ID_VIDEO_PREVIEW:
		if (framerate == 0)
			return ERROR_NONE;
		frame_length = imgsensor_info.normal_video.pclk / framerate * 10 /
			imgsensor_info.normal_video.linelength;
		spin_lock(&imgsensor_drv_lock);
		imgsensor.dummy_line = (frame_length > imgsensor_info.normal_video.framelength) ?
			(frame_length - imgsensor_info.normal_video.framelength) : 0;
		imgsensor.frame_length = imgsensor_info.normal_video.framelength + imgsensor.dummy_line;
		imgsensor.min_frame_length = imgsensor.frame_length;
		spin_unlock(&imgsensor_drv_lock);
    	if(imgsensor.frame_length > imgsensor.shutter)
		{
			set_dummy();
		}
		break;
		//...
}

sensor的linelength是固定的,每个模式的pclk也是不可调的,所以要调整帧率framerate,只能调整frame_length。set_dummy使得当前帧率立刻变化为设置的帧率。

(C)struct imgsensor_info_struct描叙sensor info常量的结构体。

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.h

struct imgsensor_info_struct {
   	kal_uint32 sensor_id;                      /*record sensor id defined in Kd_imgsensor.h*/
   	kal_uint32 checksum_value;                 /*checksum value for Camera Auto Test*/
   //不同mode 的信息
   	struct imgsensor_mode_struct pre;          /*preview scenario relative information*/
   	struct imgsensor_mode_struct cap;          /*capture scenario relative information*/
   	struct imgsensor_mode_struct cap1;
   	struct imgsensor_mode_struct cap2;
   	struct imgsensor_mode_struct normal_video; /*normal video  scenario relative information*/
   	struct imgsensor_mode_struct hs_video;     /*high speed video scenario relative information*/
   	struct imgsensor_mode_struct slim_video;   /*slim video for VT scenario relative information*/
    //支持的功能
   	kal_uint8  ae_shut_delay_frame;            /*shutter delay frame for AE cycle*/
   	kal_uint8  ae_sensor_gain_delay_frame;     /*sensor gain delay frame for AE cycle*/
   	kal_uint8  ae_ispGain_delay_frame;         /*isp gain delay frame for AE cycle*/
   	kal_uint8  ihdr_support;                   /*1, support; 0,not support*/
   	kal_uint8  ihdr_le_firstline;              /*1,le first ; 0, se first*/
   	kal_uint8  sensor_mode_num;                /*support sensor mode num*/
    //丢帧处理(丢掉不稳定帧的数据)
   	kal_uint8  cap_delay_frame;                /*enter capture delay frame num*/
   	kal_uint8  pre_delay_frame;                /*enter preview delay frame num*/
   	kal_uint8  video_delay_frame;              /*enter video delay frame num*/
   	kal_uint8  hs_video_delay_frame;           /*enter high speed video  delay frame num*/
   	kal_uint8  slim_video_delay_frame;         /*enter slim video delay frame num*/
   	kal_uint8  margin;                         /*sensor framelength & shutter margin*/
   	kal_uint32 min_shutter;                    /*min shutter*/
   	kal_uint32 max_frame_length;               /*max framelength by sensor register's limitation*/
    //isp驱动电流,电流过大可能会射频干扰
   	kal_uint8  isp_driving_current;            /*mclk driving current*/
   	kal_uint8  sensor_interface_type;          /*sensor_interface_type*/
   	kal_uint8  mipi_sensor_type;
   	/*0,MIPI_OPHY_NCSI2; 1,MIPI_OPHY_CSI2, default is NCSI2, don't modify this para*/
   	/*don't modify this para*/
   	kal_uint8  mipi_settle_delay_mode;
   	/*0, high speed signal auto detect; 1, use settle delay,unit is ns, */
   	kal_uint8  sensor_output_dataformat;       /*sensor output first pixel color*/
   	kal_uint8  mclk;                           /*mclk value, suggest 24 or 26 for 24Mhz or 26Mhz*/
   	kal_uint8  mipi_lane_num;                  /*mipi lane num*/
   	kal_uint8  i2c_addr_table[5];
   	/*record sensor support all write id addr, only supprt 4must end with 0xff*/
};
//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c

static struct imgsensor_info_struct imgsensor_info = {
	.sensor_id = GC8034_SENSOR_ID,       /*record sensor id defined in Kd_imgsensor.h*/
	.checksum_value = 0x1b375588,		//0xa11f4e23,            /*checksum value for Camera Auto Test*/

	.pre = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,                /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85, /*unit, ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},

	.cap = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85, /*unit, ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},
	.cap1 = {
		/* capture for PIP 24fps relative information */
		/* capture1 mode must use same framelength */
		/* linelength with Capture mode for shutter calculate */
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85,/*unit , ns*/
		/* less than 13M(include 13M),cap1 max framerate is 24fps */
		/* 16M max framerate is 20fps, 20M max framerate is 15fps */
		.mipi_pixel_rate = 215040000,	//672000000,
		.max_framerate = 240,
	},
	.normal_video = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85,/*unit , ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},
	.hs_video = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 1632,
		.grabwindow_height = 1224,
		.mipi_data_lp2hs_settle_dc = 85,/*unit , ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},
	.slim_video = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 1280,
		.grabwindow_height = 720,
		.mipi_data_lp2hs_settle_dc = 85,/*unit , ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},
	.margin = 4,                          /* sensor framelength & shutter margin */
	.min_shutter = 4,                     /* min shutter */
	.max_frame_length =0x7fff,           /* 0xffff 0x29b3max framelength by sensor register's limitation */
	.ae_shut_delay_frame = 0,
	/* shutter delay frame for AE cycle, 2 frame with ispGain_delay-shut_delay=2-0=2 */
	.ae_sensor_gain_delay_frame = 0,
	/* sensor gain delay frame for AE cycle, */
	/* 2 frame with ispGain_delay-sensor_gain_delay=2-0=2 */
	.ae_ispGain_delay_frame = 2,          /* isp gain delay frame for AE cycle */
	.frame_time_delay_frame = 2,
	.ihdr_support = 0,                    /* 1, support; 0,not support */
	.ihdr_le_firstline = 0,               /* 1,le first ; 0, se first */
	.sensor_mode_num = 5,                 /* support sensor mode num */
	.cap_delay_frame = 2,                 /* enter capture delay frame num */
	.pre_delay_frame = 2,                 /* enter preview delay frame num */
	.video_delay_frame = 2,               /* enter video delay frame num */
	.hs_video_delay_frame = 2,            /* enter high speed video  delay frame num */
	.slim_video_delay_frame = 2,          /* enter slim video delay frame num */

	.isp_driving_current = ISP_DRIVING_8MA,                 /* mclk driving current */
	.sensor_interface_type = SENSOR_INTERFACE_TYPE_MIPI,    /* sensor_interface_type */
	.mipi_sensor_type = MIPI_OPHY_NCSI2,                    /* 0,MIPI_OPHY_NCSI2;  1,MIPI_OPHY_CSI2 */
	.mipi_settle_delay_mode = MIPI_SETTLEDELAY_AUTO,
	/* 0,MIPI_SETTLEDELAY_AUTO; 1,MIPI_SETTLEDELAY_MANNUAL */
#if defined(GC8034_MIRROR_NORMAL)
	.sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_R, /*sensor output first pixel color*/
#elif defined(GC8034_MIRROR_H)
	.sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_Gr,/*sensor output first pixel color*/
#elif defined(GC8034_MIRROR_V)
	.sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_Gb,/*sensor output first pixel color*/
#elif defined(GC8034_MIRROR_HV)
	.sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_B, /*sensor output first pixel color*/
#else
	.sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_R, /*sensor output first pixel color*/
#endif
	.mclk = 24,                                             /* mclk value, suggest 24 or 26 for 24Mhz or 26Mhz */
	.mipi_lane_num = SENSOR_MIPI_4_LANE,                    /* mipi lane num */
	.i2c_addr_table = { 0x6e, 0xff },
	/* record sensor support all write id addr, only supprt 4must end with 0xff */
};

(D)struct imgsensor_struct记录sensor info变量的结构体:用于动态的保存sensor的关键信息。

struct imgsensor_struct {
//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.h

    //记录当前是normal, or H mirror, or V flip,or both H& V
   	kal_uint8  mirror;                        /*mirrorflip information*/
    //记录当前处于哪种mode(init/preview/capture/video)
   	kal_uint8  sensor_mode;                   /*record IMGSENSOR_MODE enum value*/
    //记录当前的shutter值
   	kal_uint32 shutter;                       /*current shutter*/
    //记录当前的sensor gain值
   	kal_uint16 gain;                          /*current gain*/
   	kal_uint32 pclk;                          /*current pclk*/
   	kal_uint32 frame_length;                  /*current framelength*/
   	kal_uint32 line_length;                   /*current linelength*/
   	kal_uint32 min_frame_length;              /*current min  framelength to max framerate*/
    //记录当前的dummy pixel, dummy line的值
    kal_uint16 dummy_pixel;                   /*current dummypixel*/
    kal_uint16 dummy_line;                    /*current dummline*/
    kal_uint16 current_fps;                   /*current max fps*/
    kal_bool   autoflicker_en;                /*record autoflicker enable or disable*/
    kal_bool   test_pattern;                  /*record test pattern mode or not*/
    //记录当前处于哪个scenario( preview/capture/video)
    enum MSDK_SCENARIO_ID_ENUM current_scenario_id;/*current scenario id*/
    kal_bool   ihdr_en;                       /*ihdr enable or disable*/
    //记录当前i2c使用的address
    kal_uint8  i2c_write_id;                  /*record current sensor's i2c write id*/
};

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c

static struct imgsensor_struct imgsensor = {
	.mirror = IMAGE_HV_MIRROR,            /* IMAGE_NORMAL, mirrorflip information */
	.sensor_mode = IMGSENSOR_MODE_INIT,
	/* IMGSENSOR_MODE enum value,record current sensor mode */
	/* such as: INIT, Preview, Capture, Video,High Speed Video, Slim Video */
	.shutter = 0x3ED,                     /* current shutter */
	.gain = 0x40,                         /* current gain */
	.dummy_pixel = 0,                     /* current dummypixel */
	.dummy_line = 0,                      /* current dummyline */
	.current_fps = 300,                   /* full size current fps : 24fps for PIP, 30fps for Normal or ZSD */
	.autoflicker_en = KAL_FALSE,
	/* auto flicker enable: KAL_FALSE for disable auto flicker, KAL_TRUE for enable auto flicker */
	.test_pattern = KAL_FALSE,
	/* test pattern mode or not. KAL_FALSE for in test pattern mode, KAL_TRUE for normal output */
	.current_scenario_id = MSDK_SCENARIO_ID_CAMERA_PREVIEW,	/* current scenario id */
	.ihdr_en = 0,                         /* sensor need support LE, SE with HDR feature */
	.i2c_write_id = 0x6e,                 /* record current sensor's i2c write id */
};

(E)Sensor output window information

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c

static struct SENSOR_WINSIZE_INFO_STRUCT imgsensor_winsize_info[5] = {
	{ 3264, 2448,   0,   0, 3264, 2448, 3264, 2448, 0, 0, 3264, 2448, 0, 0, 3264, 2448}, /* Preview */
	{ 3264, 2448,   0,   0, 3264, 2448, 3264, 2448, 0, 0, 3264, 2448, 0, 0, 3264, 2448}, /* capture */
	{ 3264, 2448,   0,   0, 3264, 2448, 3264, 2448, 0, 0, 3264, 2448, 0, 0, 3264, 2448}, /* video */
	{ 3264, 2448,   0,   0, 3264, 2448, 3264, 2448, 0, 0, 1632, 1224, 0, 0, 1632, 1224}, /* hight speed video */
	{ 3264, 2448, 252, 504, 2560, 1440, 1280,  720, 0, 0, 1280,  720, 0, 0, 1280,  720}  /* slim video */
};

(3)驱动入口函数xxxx_MIPI_RAW_SensorInit

(A)驱动入口函数GC8034_MIPI_RAW_SensorInit

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_sensor_list.c

struct IMGSENSOR_INIT_FUNC_LIST kdSensorList[MAX_NUM_OF_SUPPORT_SENSOR] = {

	#if defined(GC8034_MIPI_RAW)
	{GC8034_SENSOR_ID,
	SENSOR_DRVNAME_GC8034_MIPI_RAW,
	GC8034_MIPI_RAW_SensorInit},
#endif

//...
{0, {0}, NULL}
};

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c

UINT32 GC8034_MIPI_RAW_SensorInit(struct SENSOR_FUNCTION_STRUCT **pfFunc)
{
	/* Check Sensor status here */
	if (pfFunc != NULL)
		*pfFunc = &sensor_func;
	return ERROR_NONE;
}

(B)SENSOR_FUNCTION_STRUCT这个结构体包含了所有sensor driver的操作接口

//kernel-4.19/drivers/misc/mediatek/imgsensor/inc/kd_imgsensor_define.h

struct SENSOR_FUNCTION_STRUCT {
   	MUINT32 (*SensorOpen)(void);
   	MUINT32 (*SensorGetInfo)(enum MSDK_SCENARIO_ID_ENUM ScenarioId,
   	    MSDK_SENSOR_INFO_STRUCT *pSensorInfo,
   	    MSDK_SENSOR_CONFIG_STRUCT *pSensorConfigData);
     
   	MUINT32 (*SensorGetResolution)(
   	    MSDK_SENSOR_RESOLUTION_INFO_STRUCT * pSensorResolution);
    
   	MUINT32 (*SensorFeatureControl)(MSDK_SENSOR_FEATURE_ENUM FeatureId,
   	    MUINT8 *pFeaturePara,
   	    MUINT32 *pFeatureParaLen);
    
   	MUINT32 (*SensorControl)(enum MSDK_SCENARIO_ID_ENUM ScenarioId,
   	    MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *pImageWindow,
   	    MSDK_SENSOR_CONFIG_STRUCT *pSensorConfigData);
     
   	MUINT32 (*SensorClose)(void);
    
   	MUINT8  arch;
   	void   *psensor_inst; /* IMGSENSOR_SENSOR_INST */
};

对应驱动中填充的信息如下:

static struct SENSOR_FUNCTION_STRUCT sensor_func = {
   	open,//打开camera时调用
   	get_info,// 获取sensor的动态信息
   	get_resolution,//获取sensor特定模式下的尺寸
   	feature_control,
   	control,
   	close
};

(C)open 函数

//gc8034mipi_Sensor.c

//此函每次打开camera都会调用
static kal_uint32 open(void)
{
	  //sensor初始化参数设置
	sensor_init();

	gc8034_gcore_identify_otp();
	spin_lock(&imgsensor_drv_lock);
	
	  //初始化imgsensor结构体
	imgsensor.autoflicker_en = KAL_FALSE;
	imgsensor.sensor_mode = IMGSENSOR_MODE_INIT;
	imgsensor.pclk = imgsensor_info.pre.pclk;
	imgsensor.frame_length = imgsensor_info.pre.framelength;
	imgsensor.line_length = imgsensor_info.pre.linelength;
	imgsensor.min_frame_length = imgsensor_info.pre.framelength;
	imgsensor.dummy_pixel = 0;
	imgsensor.dummy_line = 0;
	imgsensor.ihdr_en = 0;
	imgsensor.test_pattern = KAL_FALSE;
	imgsensor.current_fps = imgsensor_info.pre.max_framerate;
	spin_unlock(&imgsensor_drv_lock);
}

(D)feature_control函数

//获取linelength和pclk
   	case SENSOR_FEATURE_GET_PERIOD:
   		*feature_return_para_16++ = imgsensor.line_length;
   		*feature_return_para_16 = imgsensor.frame_length;
   		*feature_para_len = 4;
   		break;
   	case SENSOR_FEATURE_GET_PIXEL_CLOCK_FREQ:
   		*feature_return_para_32 = imgsensor.pclk;
   		*feature_para_len = 4;
   		break;

//set_shutter设置曝光行
    case SENSOR_FEATURE_SET_ESHUTTER:
    	set_shutter(*feature_data);
    	break;

//streaming_control控制sensor输出数据
   case SENSOR_FEATURE_SET_STREAMING_SUSPEND:
    	pr_info("SENSOR_FEATURE_SET_STREAMING_SUSPEND\n");
    	streaming_control(KAL_FALSE);
    	break;

设置曝光行,曝光行物理上小于frame_length,所以曝光行大于当前frame_length时,frame_length会自动撑长,
帧率降低,所以亮度较低时,帧率会下降,因为这时候shutter比较大。

(E)control模式切换函数

static kal_uint32 control(enum MSDK_SCENARIO_ID_ENUM scenario_id, MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window,
	MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data)
{
	LOG_INF("Enter control!\n");
	LOG_INF("scenario_id = %d\n", scenario_id);
	spin_lock(&imgsensor_drv_lock);
	imgsensor.current_scenario_id = scenario_id;
	spin_unlock(&imgsensor_drv_lock);
	switch (scenario_id) {
	case MSDK_SCENARIO_ID_CAMERA_PREVIEW:
		preview(image_window, sensor_config_data);
		break;
	case MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG:
		capture(image_window, sensor_config_data);
		break;
	case MSDK_SCENARIO_ID_VIDEO_PREVIEW:
		normal_video(image_window, sensor_config_data);
		break;
	case MSDK_SCENARIO_ID_HIGH_SPEED_VIDEO:
		hs_video(image_window, sensor_config_data);
		break;
	case MSDK_SCENARIO_ID_SLIM_VIDEO:
		slim_video(image_window, sensor_config_data);
		break;
	default:
		LOG_INF("Error ScenarioId setting");
		preview(image_window, sensor_config_data);
		return ERROR_INVALID_SCENARIO_ID;
	}
	return ERROR_NONE;
}

这里以preview为例说明流程:

static kal_uint32 preview(MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window,
	MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data)
{
	//更新imgsensor结构体信息
	spin_lock(&imgsensor_drv_lock);
	imgsensor.sensor_mode = IMGSENSOR_MODE_PREVIEW;
	imgsensor.pclk = imgsensor_info.pre.pclk;
	/* imgsensor.video_mode = KAL_FALSE; */
	imgsensor.line_length = imgsensor_info.pre.linelength;
	imgsensor.frame_length = imgsensor_info.pre.framelength;
	imgsensor.min_frame_length = imgsensor_info.pre.framelength;
	imgsensor.autoflicker_en = KAL_TRUE;
	spin_unlock(&imgsensor_drv_lock);
	 //更新寄存器
	preview_setting();
	return ERROR_NONE;
}
上一篇:Android项目开发:指南针(两种方法实现)


下一篇:Flink——四种读取数据方式(集合、文件、kafka、自定义数据源)