【高通SDM660平台 Android 10.0】(18) --- Camera start_session() 过程分析

【高通SDM660平台 Android 10.0】18 --- Actuator 与 Kernel Actuator代码分析 及 Camera start_session过程分析

    • 1. module_sensor_init( )
      • 1.1 module_sensor_start_session( )
      • 1.2 module_sensor_init_session()
      • 1.3 module_sensor_offload_init_config( )


《【高通SDM660平台】(1) — Camera 驱动 Bringup Guide》
《【高通SDM660平台】(2) — Camera Kernel 驱动层代码逻辑分析》
《【高通SDM660平台】(3) — Camera V4L2 驱动层分析 》
《【高通SDM660平台】(4) — Camera Init 初始化流程 》
《【高通SDM660平台】(5) — Camera Open 流程》
《【高通SDM660平台】(6) — Camera getParameters 及 setParameters 流程》
《【高通SDM660平台】(7) — Camera onPreview 代码流程》
《【高通SDM660平台】(8) — Camera MetaData介绍》
《【高通SDM660平台 Android 10.0】(9) — Qcom Camera Daemon 代码分析》
《【高通SDM660平台 Android 10.0】(10) — Camera Sensor lib 与 Kernel Camera Probe 代码分析》
《【高通SDM660平台 Android 10.0】(11) — Eeprom lib 与 Kernel eeprom代码分析》
《【高通SDM660平台 Android 10.0】(12) — Camera Chromatix 代码分析》
《【高通SDM660平台 Android 10.0】(18) — Camera start_session() 过程分析》
《【高通SDM660平台 Android 10.0】(19) — Camera_focus、Camera_snapshot、volume_up 按键工作原理分析》
《【高通SDM660平台 Android 10.0】(20) — Actuator 与 Kernel Actuator代码分析》


本来打算分析 flash 、Actuator 等 码流程,但它位的初始化,都是在 start_session()中,所以,我们今天先来看下 start_session()的流程

1. module_sensor_init( )

module_sensor_init() 方法中,将 module_sensor_start_session 函数保存在结构体 s_module->start_session 中,
我们今天就要从它谈起。

mct_module_t *module_sensor_init(const char *name)
{`
	s_module->start_session = module_sensor_start_session;
  	s_module->stop_session = module_sensor_stop_session;
	
	/* module_sensor_probe_sensors */
  	ret = sensor_init_probmodus */
	ret = mct_list_traverse(module_ctrl->sensor_bundle, module_sensors_subinit, NULL);
	/* Create ports based on CID info */
	ret = mct_list_traverse(module_ctrl->sensor_bundle, port_sensor_create, s_module);
	ret = mct_list_traverse(module_ctrl->sensor_bundle, module_sensor_init_eeprom, module_ctrl->eebin_hdl);
	ret = mct_list_traverse(module_ctrl->sensor_bundle, module_sensor_init_chromatix, module_ctrl->eebin_hdl);
}

1.1 module_sensor_start_session( )

module_sensor_start_session 中主要工作如下:

  1. 获取 module_ctrl 结构体
  2. 通过 session id 获取 对应的 s_bundle 结构体
  3. 默认关闭 手电筒,红外线
  4. 创建名为 CAM_sensor 的pthread 线程,用于监听拍照过程中的 SET_AUTOFOCUSOFFLOAD_FUNC 事件
  5. 加载sensor lib,对sensor 进行上电,打开所有外设,初始化
# mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
static boolean module_sensor_start_session( mct_module_t *module, uint32_t sessionid)
{
  // 1. 获取 module_ctrl 结构体
  SHIGH("sessionid %d", sessionid);

  module_ctrl = (module_sensor_ctrl_t *)module->module_private;
  ATRACE_CAMSCOPE_BEGIN(CAMSCOPE_SENSOR_START_SESSION);

  // 2. 通过 session id 获取 对应的 s_bundle 结构体
  /* get the s_bundle from session id */
  s_list = mct_list_find_custom(module_ctrl->sensor_bundle, &sessionid, sensor_util_find_bundle);
  s_bundle = (module_sensor_bundle_info_t *)s_list->data;

  // 3. 默认关闭 手电筒,红外线
  /* initialize the "torch on" flag to 0 */
  s_bundle->torch_on = 0;
  s_bundle->longshot = 0;
  s_bundle->ir_mode = SENSOR_IR_MODE_OFF;

  // 4. 创建名为 CAM_sensor 的pthread 线程,用于监听拍照过程中的 SET_AUTOFOCUS(自动对焦),OFFLOAD_FUNC(转移函数运行) 事件
  /* create sensor thread */
  ret = sensor_thread_create(s_bundle);
  ===========>
  + 	ret = pthread_create(&thread.td, &attr, sensor_thread_func, &thread );
  +  	pthread_setname_np(thread.td, "CAM_sensor");
  + 	------------>
  + 		// mm-camera/mm-camera2/media-controller/modules/sensors/sensor/module/sensor_thread.c
  + 		while(!thread_exit){
  + 			ready = poll(&pollfds, (nfds_t)num_of_fds, -1);
  + 			nread = read(pollfds.fd, &msg, sizeof(sensor_thread_msg_t));
  + 			sensor_process_thread_message(&msg);
  + 		}
  + 	<------------
  <===========

  /* Reset phase correction parameters when session starts */
  module_sensor_dualcamera_reset_pc_params(s_bundle);
	
  // 5. 加载sensor lib,对sensor 进行上电,打开所有外设,初始化
  /* this init session includes
     power up sensor, config init setting */
  ret = module_sensor_init_session(s_bundle, module_ctrl->eebin_hdl);

  /* Power up peer sensor if in stereo mode. */
  if (TRUE == s_bundle->is_stereo_configuration && s_bundle->stereo_peer_s_bundle != NULL) {
    SERR("Powering up peer stereo sensor. ");
    ret = module_sensor_init_session(s_bundle->stereo_peer_s_bundle, module_ctrl->eebin_hdl);
  }

  SHIGH("SUCCESS");
  ATRACE_CAMSCOPE_END(CAMSCOPE_SENSOR_START_SESSION);
  return TRUE;
}

1.2 module_sensor_init_session()

主要工作如下:

  1. session 相关标志位初始化
  2. 初始化帧缓存队列,默认 FRAME_CTRL_SIZE = 7
  3. 获取该 camera 对应所有外设的信息。
  4. 获取 eeprom 结构体数据
  5. 打开所有外设节点,将sensor open 方法转移到 sensor thread 中,运行函数为 module_sensor_offload_open()
    (thead 也就是我们前面CAM_sensorpthread线程,名为sensor_thread_func
  6. 打开所有外设节点,相关信息,以 actuator_data_t * 结构体信息返回在 s_bundle->module_sensor_params[i]->sub_module_private
  7. 等待module_sensor_offload_open() 函数,打开外设成功后,发送的pthread_cond_signal(&s_bundle->cond);
    此时置位标志位 open_done = TRUE
  8. 注册 Chromatix mamnager
  9. 如果使能了 camera.eztune.enable,则重新加载初始化 chromatix
  10. 如果定义了其他的lib 库,则在此处加载功
  11. sensor init config 方法转移到 sensor thread 中,运行函数为 module_sensor_offload_init_config()
  12. 调用 camera sensor 方法,处理 SENSOR_SET_FORMATTED_CAL_DATA ,也就是调用 sensor_set_formatted_cal_data(sctrl, data);
    设置 s_bundle->formatted_datacamera otp 数据
    formatted_data 是在初始化 eeprom 时向kernel 下发命令 EEPROM_GET_FORMATTED_DATA 获取的
  13. 如果支持 LASER 的话,此时对镭射初始化
# mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
/** module_sensor_init_session: init session function for sensor
 *
 *  @s_bundle: sensor bundle pointer pointing to the sensor for which stream is added
 *  @eebin_hdl: pointing to eeprom bin data
 *
 *  Return: 0 for success and negative error for failure
 *
 *  When called first time, this function
 *  1) opens all sub modules to open subdev node
 *  2) loads sensor library
 *  3) calls init on sensor, csiphy and csid. Has ref count to ensure that actual add stream sequence is executed only once 
 ***/

static boolean module_sensor_init_session( module_sensor_bundle_info_t *s_bundle, void *eebin_hdl)
{
  int32_t                 rc = SENSOR_SUCCESS, i = 0, j = 0, k = 0;
  module_sensor_params_t  *module_sensor_params = NULL;
  module_sensor_params_t  *actuator_module_params = NULL;
  module_sensor_params_t  *csiphy_module_params = NULL;
  module_sensor_params_t  *csid_module_params = NULL;
  module_sensor_params_t  *eeprom_module_params = NULL;
  module_sensor_params_t  *flash_module_params = NULL;
  enum sensor_sub_module_t s_module;
  af_algo_tune_parms_t     *af_algo_cam_ptr = NULL;
  af_algo_tune_parms_t     *af_algo_camcorder_ptr = NULL;
  actuator_driver_params_t *af_driver_ptr = NULL;

  // 1. session 相关标志位初始化
  /* Initialize max width, height and stream on count */
  s_bundle->peer_identity = 0;
  s_bundle->max_width = 0;
  s_bundle->max_height = 0;
  s_bundle->stream_on_count = 0;
  s_bundle->stream_mask = 0;
  s_bundle->last_idx = 0;
  s_bundle->delay_frame_idx = 0;
  s_bundle->num_skip = 4;			// 跳过的帧数
  s_bundle->state = 0;
  s_bundle->block_parm = 0;
  s_bundle->regular_led_trigger = 0;
  s_bundle->main_flash_on_frame_skip = 0;
  s_bundle->main_flash_off_frame_skip = 0;
  s_bundle->torch_on_frame_skip = 0;
  s_bundle->torch_off_frame_skip = 0;
  s_bundle->last_flash_request = CAM_FLASH_MODE_OFF;
  s_bundle->flash_params.flash_mode = CAM_FLASH_MODE_OFF;
  s_bundle->flash_params.flash_state = CAM_FLASH_STATE_READY;
  s_bundle->torch_on = 0;
  s_bundle->longshot = 0;
  s_bundle->led_off_count = -1;
  s_bundle->flash_rer_enable = 0;
  s_bundle->ois_cmd_queue_mask = 0x0000;
  s_bundle->ois_enabled = 0;
  s_bundle->ois_mode = OIS_DISABLE;
  s_bundle->hal_params.test_pattern_mode = CAM_TEST_PATTERN_OFF;
  s_bundle->stream_thread_wait_time = 5;
  s_bundle->actuator_sensitivity = 0;
  s_bundle->ir_mode = SENSOR_IR_MODE_OFF;
  s_bundle->retry_frame_skip = 0;
  s_bundle->init_config_done = 0;
  s_bundle->open_done = 0;
  s_bundle->is_plain16 = 0;
  s_bundle->close_done = 0;
  s_bundle->delay_frame_cnt = 0;
  s_bundle->cur_scene_mode = -1;
  memset(prop, 0, sizeof(prop));
  property_get("persist.vendor.partial.skip", prop, "1");
  s_bundle->partial_flash_frame_skip  = atoi(prop);
  s_bundle->sensor_params.flash_mode = CAM_FLASH_MODE_OFF;
  s_bundle->is_first_stream_on = 1;
  s_bundle->is_camera_closing = 0;

  memset(s_bundle->isp_frameskip, 0, sizeof(s_bundle->isp_frameskip));
  memset(s_bundle->identity, 0, sizeof(s_bundle->identity));
  memset(&s_bundle->cap_control, 0, sizeof(sensor_capture_control_t));
  memset(&s_bundle->hal_frame_batch, 0, sizeof(cam_capture_frame_config_t));
  memset(&s_bundle->dualc_info, 0, sizeof(sensor_dualc_info));

  /* initialize condition variable */
  pthread_condattr_init(&s_bundle->fast_aec_condattr);
  pthread_condattr_setclock(&s_bundle->fast_aec_condattr, CLOCK_MONOTONIC);
  pthread_cond_init(&s_bundle->fast_aec_cond, &s_bundle->fast_aec_condattr);
  /* initialize mutex */
  pthread_mutex_init(&s_bundle->fast_aec_mutex, NULL);

  /* initialize flash control mutex */
  pthread_mutex_init(&s_bundle->capture_control_mutex, NULL);
	
  // 2. 初始化帧缓存队列,默认 FRAME_CTRL_SIZE = 7
  /* Initialize frame control queues*/
  for (j = 0; j < FRAME_CTRL_SIZE; j++) {
    s_bundle->frame_ctrl.frame_ctrl_q[j] = (mct_queue_t*)CAM_CALLOC(1, sizeof(mct_queue_t));
    JUMP_ON_NULL(s_bundle->frame_ctrl.frame_ctrl_q[j], ERROR0);
    mct_queue_init(s_bundle->frame_ctrl.frame_ctrl_q[j]);
    /* Initialize frame control mutex */
    pthread_mutex_init(&s_bundle->frame_ctrl.frame_ctrl_mutex[j], NULL);
  }
  // 3. 获取该 camera 对应所有外设的信息。
  for (i = 0; i < SUB_MODULE_MAX; i++) {
    intf_info = &s_bundle->subdev_info[i].intf_info[SUBDEV_INTF_PRIMARY];
    SLOW("primary sd index = %d, id = %d subdev name %s,",i, intf_info->subdev_id, intf_info->sensor_sd_name);
    
    intf_info = &s_bundle->subdev_info[i].intf_info[SUBDEV_INTF_SECONDARY];
    SLOW("secondary sd index %d subdev name %s, secondary id = %d", i, intf_info->sensor_sd_name, s_bundle->sensor_info->subdev_intf[i]);
  }

  // 4. 获取 eeprom 结构体数据
  /* eeprom control is already created at cam daemon init */
  s_bundle->module_sensor_params[SUB_MODULE_EEPROM]->sub_module_private =
    s_bundle->eeprom_data;

  // 5. 打开所有外设节点,
  // 将sensor open 方法转移到 sensor thread 中,运行函数为 `module_sensor_offload_open()`。
  //(thead 也就是我们前面CAM_sensor 的pthread线程,名为sensor_thread_func)
  /* offload open  to sensor thread */
  msg.msgtype = OFFLOAD_FUNC;
  msg.offload_func = module_sensor_offload_open;
  msg.param1 = s_bundle;
  msg.param2 = NULL;
  msg.param3 = NULL;
  msg.param4 = NULL;
  msg.stop_thread = FALSE;
  nwrite = write(s_bundle->pfd[1], &msg, sizeof(sensor_thread_msg_t));
  if (nwrite < 0) {
    SERR("%s: offload open: Writing into fd failed:", __func__);
    module_sensor_offload_open(s_bundle, eebin_hdl, NULL, NULL);
    if (s_bundle->open_done < 0)
      goto ERROR1;
  }
  // 6. 打开所有外设节点,相关信息,以 `actuator_data_t *` 结构体信息返回在 `s_bundle->module_sensor_params[i]->sub_module_private` 中
  ATRACE_CAMSCOPE_BEGIN(CAMSCOPE_SENSOR_SD_OPEN);
  for (i = 0; i < SUB_MODULE_MAX; i++) {
	if (s_bundle->module_sensor_params[i]->func_tbl.open && !s_bundle->subdev_info[i].sub_mod_open_flag) {
      	rc = s_bundle->module_sensor_params[i]->func_tbl.open( &s_bundle->module_sensor_params[i]->sub_module_private,
      			 &s_bundle->subdev_info[i]);
    }
  }
  ATRACE_CAMSCOPE_END(CAMSCOPE_SENSOR_SD_OPEN);

  // 7. 等待module_sensor_offload_open() 函数,打开外设成功后,发送的pthread_cond_signal(&s_bundle->cond);
  // 此时置位标志位 open_done =  TRUE
  TIMED_WAIT_ON_EVENT(s_bundle->mutex, s_bundle->cond,
              ts, OPEN_TIMEOUT, s_bundle->open_done,
              TRUE, "open_done");
  // 8. 注册 Chromatix mamnager
  // 调用 func_tbl.process ,处理事件 CHROMATIX_SET_CM,将 chromatix_ctrl ctrl->cm = s_bundle->chromatix_manager
  /* register chromatix manager to chromatix sub module */
  SENSOR_SUB_MODULE_PROCESS_EVENT(s_bundle, SUB_MODULE_CHROMATIX,
    CHROMATIX_SET_CM, &s_bundle->chromatix_manager, rc);

  for (k = 0; k < (int32_t)ARRAY_SIZE(eebin_load); k++) {
    s_module = eebin_load[k].s_module;
    if (s_bundle->module_sensor_params[s_module]->func_tbl.process) {
      rc = s_bundle->module_sensor_params[s_module]->func_tbl.process(
        		s_bundle->module_sensor_params[s_module]->sub_module_private,eebin_load[k].p_event, eebin_hdl);
    }
  }
	// 9. 如果使能了 camera.eztune.enable,则重新加载初始化 chromatix
  /* reload all chromatix for each session only for eztune */
  property_get("persist.vendor.camera.eztune.enable", prop, "0");
  eztune_enable = atoi(prop);
  SLOW("eztune enabled %d", eztune_enable);
  if (eztune_enable) {
    /* clear all the present chromatix before */
    cm_destroy(&s_bundle->chromatix_manager);
    /* reload chromatix files */
    status = module_sensor_init_chromatix(s_bundle,eebin_hdl);
  }
	// 10. 如果定义了其他的lib 库,则在此处加载功
  /* Load external libraries */
  if (s_bundle->sensor_lib_params->sensor_lib_ptr->external_library) {
    status = module_sensor_load_external_libs(s_bundle);
    if (status == FALSE) {
      SERR("failed: module_sensor_load_external_libs");
      goto ERROR1;
    }
  }
 // 11. 将sensor init config 方法转移到 sensor thread 中,运行函数为 `module_sensor_offload_init_config()`。
  /* offload init config to sensor thread */
  msg.msgtype = OFFLOAD_FUNC;
  msg.offload_func = module_sensor_offload_init_config;
  msg.param1 = s_bundle;
  msg.param2 = eebin_hdl;
  msg.param3 = NULL;
  msg.param4 = NULL;
  msg.stop_thread = FALSE;
  nwrite = write(s_bundle->pfd[1], &msg, sizeof(sensor_thread_msg_t));
  if (nwrite < 0) {
    SERR("%s: offload init config: Writing into fd failed:",__func__);
    module_sensor_offload_init_config(s_bundle, eebin_hdl, NULL, NULL);
  }
  // 12. 调用 camera sensor 方法,处理 SENSOR_SET_FORMATTED_CAL_DATA ,也就是调用 sensor_set_formatted_cal_data(sctrl, data);
   // 设置 s_bundle->formatted_data 为 camera otp 数据
   // formatted_data 是在初始化 eeprom 时 下发命令 EEPROM_GET_FORMATTED_DATA 获取的
  SENSOR_SUB_MODULE_PROCESS_EVENT(s_bundle, SUB_MODULE_SENSOR,
	    SENSOR_SET_FORMATTED_CAL_DATA, s_bundle->formatted_data, rc);
	// 13. 如果支持 LASER 的话,此时对镭射初始化
  if (s_bundle->sensor_lib_params->sensor_lib_ptr->sensor_output.is_depth_sensor) {
    SENSOR_SUB_MODULE_PROCESS_EVENT(s_bundle, SUB_MODULE_LASER_LED,
      LASER_LED_INIT, NULL, rc);
  }
  
  SHIGH("Success : sensor_name:%s",
   s_bundle->sensor_lib_params->sensor_lib_ptr->sensor_slave_info.sensor_name);
  return TRUE;
}


1.3 module_sensor_offload_init_config( )

  1. 解析 sdm660_camera.xml 中的旋转角度
  2. 析像头的位置,如 CAM_POSITION_BACK(0)CAM_POSITION_FRONT(1)CAM_POSITION_BACK_AUX(4)
  3. 解析 sdm660_camera.xml中的
  4. 获取 sensor_property, 其定义在 sensor lib.h 中,
    mm-camera/mm-camera2/media-controller/modules/sensors/sensor/libs/s5k3l8/s5k3l8_lib.h
    下的 .sensor_property属性
  5. 解析 sdm660_camera.xml中的 lens 信息
  6. Camera sensor 初始化,停止senosr 数据流,VDDIO上电,下发初始化参数
  7. 如果需要修改 i2c ,此开始重写 i2c 寄存器
  8. 获取并设置senoor 的otp 数据
    获取Camera otp 数据是在否sensor 内部做 isp,还是在平台端 中做isp , is_insensor
    获取otp数据,并且把 otp 数据写入sensor 中。
    // 注,有些sensor 是在sensor 内部做isp, 所以会用到 这些数据。
    // 绝大多数的 sensor isp 是在平台端做的。
  9. 初始化闪光灯 ,调用 flash_init(),打开闪光灯 lib 库 -----> 后面分析闪光灯代码流程时,就直接从这里跳入了
  10. 获取使用闪光灯时,跳过的帧数,如果没设置,默认过滤 2 帧
  11. 初始化马达
  12. 如果定义了其他的库,则直接加载
  13. 解析快速 AEC 时,跳过的帧数
  14. 解析 ext_pipeline_delay
void module_sensor_offload_init_config( void* param1,  void* param2,  void* param3 __attribute__((unused)),
  					void* param4 __attribute__((unused)))
{
  module_sensor_bundle_info_t *s_bundle = (module_sensor_bundle_info_t *)param1;
  void *eebin_hdl = param2;
  int32_t  rc = SENSOR_SUCCESS, i = 0, j = 0, k = 0;
  module_sensor_params_t  *module_sensor_params = NULL;
  module_sensor_params_t  *eeprom_module_params = NULL;
  sensor_get_t             sensor_get;
  sensor_property_t        sensor_property;
  eebin_ctl_t              bin_ctl;
  enum sensor_sub_module_t s_module;
  af_algo_tune_parms_t    *af_algo_cam_ptr = NULL;
  af_algo_tune_parms_t    *af_algo_camcorder_ptr = NULL;
  actuator_driver_params_t *af_driver_ptr = NULL;
  boolean                  status = TRUE;
  boolean                  live_connect_enabled = FALSE;
  char                     prop[PROPERTY_VALUE_MAX];

  module_sensor_params = s_bundle->module_sensor_params[SUB_MODULE_SENSOR];

  // 1. 解析 sdm660_camera.xml 中的旋转角度 
  /* set mount angle, position and modes_supported */
  if (s_bundle->sensor_info->is_mount_angle_valid == 1)
    if (s_bundle->sensor_common_info.camera_config.sensor_mount_angle >= SENSOR_MOUNTANGLE_360)
      s_bundle->sensor_common_info.camera_config.sensor_mount_angle =s_bundle->sensor_info->sensor_mount_angle;
  // 2. 解析像头的位置,如 CAM_POSITION_BACK(0),CAM_POSITION_FRONT(1), CAM_POSITION_BACK_AUX(4)
  switch(s_bundle->sensor_info->position) {
    case BACK_CAMERA_B:		// 0 后报
      s_bundle->sensor_common_info.camera_config.position = CAM_POSITION_BACK; break;
    case FRONT_CAMERA_B: 	// 1 前摄
      s_bundle->sensor_common_info.camera_config.position = CAM_POSITION_FRONT; break;
    case AUX_CAMERA_B:  	// 4 后二摄
      s_bundle->sensor_common_info.camera_config.position = CAM_POSITION_BACK_AUX; break;
  }
  // 3. 解析 sdm660_camera.xml 中的 
  if (s_bundle->sensor_info->modes_supported != CAMERA_MODE_INVALID)
    s_bundle->sensor_common_info.camera_config.modes_supported = s_bundle->sensor_info->modes_supported;

  s_bundle->sensor_params.aperture_value = 0;
  memset(&sensor_property, 0, sizeof(sensor_property));
  
  // 4. 获取 sensor_property, 其定义在 sensor lib.h 中,
  // 如mm-camera/mm-camera2/media-controller/modules/sensors/sensor/libs/s5k3l8/s5k3l8_lib.h
  // 下的 .sensor_property 属性
  /* get lens info to sensor sub module */
  rc = module_sensor_params->func_tbl.process(
    module_sensor_params->sub_module_private,  SENSOR_GET_PROPERTY, &sensor_property);
   
  // 5. 解析 sdm660_camera.xml 中的lens 信息 
  {
    /* Fill aperture */
    s_bundle->sensor_params.aperture_value = s_bundle->sensor_common_info.camera_config.lens_info.f_number;
    s_bundle->sensor_params.f_number =_bundle->sensor_common_info.camera_config.lens_info.f_number;
    s_bundle->sensor_params.focal_length = s_bundle->sensor_common_info.camera_config.lens_info.focal_length;
    s_bundle->sensor_params.sensing_method = sensor_property.sensing_method;
    s_bundle->sensor_params.crop_factor = sensor_property.crop_factor;
    SLOW("aperture %f", s_bundle->sensor_params.aperture_value);
  }

  // 6. Camera sensor 初始化
  /* af_actuator_init */
  /* get actuator header */
  /* sensor init */
  rc = module_sensor_params->func_tbl.process( module_sensor_params->sub_module_private,SENSOR_INIT, NULL);
  ====================>
  	static int32_t sensor_init(void *sctrl)
	{
		// 停止senosr 数据流
  		rc = sensor_set_stop_stream_settings(ctrl);
  		//  VDDIO 上电
  		rc = sensor_power_up(ctrl);
  			=========>
  			+	cfg.cfgtype = CFG_POWER_UP;
  			+	LOG_IOCTL(ctrl->s_data->fd, VIDIOC_MSM_SENSOR_CFG, &cfg, "power_up");
  			<=========
  		// 下发 Camera 初始化参数
  		rc = sensor_write_init_settings(sctrl);
  	}
  <====================

  // 7. 如果需要修改 i2c ,此开始重写 i2c 寄存器
  /* Set alternative slave address if needed */
  rc = module_sensor_params->func_tbl.process( module_sensor_params->sub_module_private,
    SENSOR_SET_ALTERNATIVE_SLAVE, &s_bundle->sensor_common_info.camera_config.sensor_slave_addr);

  /*Disabling fast aec by default. Will be enabled only based on HAL input */
  s_bundle->fast_aec_required = FALSE;

  // 8. 获取并设置senoor 的otp 数据
  if (s_bundle->sensor_info->subdev_id[SUB_MODULE_EEPROM] != -1) {
    struct msm_camera_i2c_reg_setting cal_setting;
    int32_t                           is_insensor = 0;
	// 8.1 获取Camera otp 数据是在否sensor 内部做 isp,还是在平台端 中做isp , is_insensor 
    /* Check if eeprom has cal data for sensor module. */
    SENSOR_SUB_MODULE_PROCESS_EVENT(s_bundle, SUB_MODULE_EEPROM, EEPROM_GET_ISINSENSOR_CALIB, &is_insensor, rc);
    
	// 8.2 获取otp数据,并且把 otp 数据写入sensor 中。
	// 注,有些sensor 是在sensor 内部做isp, 所以会用到 这些数据。
	// 绝大多数的 sensor isp 是在平台端做的。
    /* If yes, apply cal data to the sensor module. */
    if (is_insensor) {
      SENSOR_SUB_MODULE_PROCESS_EVENT(s_bundle, SUB_MODULE_EEPROM, EEPROM_GET_RAW_DATA, &cal_setting, rc);
      SENSOR_SUB_MODULE_PROCESS_EVENT(s_bundle, SUB_MODULE_SENSOR, SENSOR_SET_CALIBRATION_DATA, &cal_setting, rc);
    }
  }
	//  9. 初始化闪光灯 ,调用 flash_init(),打开闪光灯 lib 库
  SLOW("flash subdev id = %d",
  status = module_sensor_flash_init(s_bundle);
	// 10. 获取使用闪光灯时,跳过的帧数,如果没设置,默认过滤 2 帧
  /* Get led frame skip timing parameters */
  SENSOR_SUB_MODULE_PROCESS_EVENT(s_bundle, SUB_MODULE_LED_FLASH, LED_FLASH_GET_FRAME_SKIP_TIME_PARAMS, s_bundle, rc);
  if (rc < 0) {
    SERR("failed to get led off frame skip time");
    s_bundle->main_flash_on_frame_skip = 2;
    s_bundle->main_flash_off_frame_skip = 2;
    s_bundle->torch_on_frame_skip = 2;
    s_bundle->torch_off_frame_skip = 2;
  }
 //  11. 初始化马达
 status = module_sensor_actuator_init_calibrate(s_bundle);

 // 12. 如果定义了其他的库,则直接加载
  /* Load external libraries */
  if (s_bundle->sensor_lib_params->sensor_lib_ptr->external_library) {
    status = module_sensor_load_external_libs(s_bundle);
  }
  // 13. 解析快速 AEC 时,跳过的帧数
  /* Get fast AEC capabilities */
  rc = module_sensor_params->func_tbl.process(
    module_sensor_params->sub_module_private,
    SENSOR_GET_FAST_AEC_WAIT_FRAMES, &s_bundle->sensor_num_fast_aec_frame_skip);

  // 14. 解析 ext_pipeline_delay
  if (s_bundle->sensor_info->subdev_id[SUB_MODULE_EXT] != -1) {
    SENSOR_SUB_MODULE_PROCESS_EVENT(s_bundle, SUB_MODULE_EXT,
      EXT_GET_INFO, &s_bundle->ext_pipeline_delay, rc);
  }
  // 15. 如果支持 Camera 调试,则创建  liveconnect 线程
  /* Start live connect thread if property is set */
  memset(prop, 0, sizeof(prop));
  property_get("persist.vendor.camera.liveconnect", prop, "0");
  live_connect_enabled = atoi(prop);
  if (live_connect_enabled > 0 ) {
    /* Create sensor live connect thread */
    status = sensor_live_connect_thread_create(s_bundle);
    s_bundle->live_connect_thread_started = TRUE;
  }
  
  SHIGH("Success");
  /*end*/
  PTHREAD_MUTEX_LOCK(&s_bundle->mutex);
  s_bundle->init_config_done = 1;
  pthread_cond_signal(&s_bundle->cond);
  PTHREAD_MUTEX_UNLOCK(&s_bundle->mutex);
  return;
}

至此 start_session 结束

你可能感兴趣的:(Qualcomm经验总结,Android,Camera,Android驱动)