[android][qcom][camera] 梳理focus mode 在vedor下的设置流程

梳理focus mode在vendor路径下的流程,目前还有许多不明白的地方,待后续完善

再往前应该就是pproc,暂时没有进一步梳理

vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/stats/stats_port.c

static boolean stats_port_check_caps_reserve(mct_port_t *port, void *caps,void *info)函数通过:
mct_list_traverse((mct_list_t *)private->sub_ports,stats_port_send_event_downstream, &stats_event)
把命令发给stats下的sub-port,q3a就是其中之一


vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/stats/q3a/q3a_port.c
static boolean q3a_port_event(mct_port_t *port, mct_event_t *event)
通过q3a_port_start_threads(port, event->identity,Q3A_THREAD_AF) 触发

首先af的触发在vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/stats/q3a/af_v2/af_port.c文件下。

af_port接收到事件,并对其做相应处理(具体谁发送的这个事件还待梳理)

这个函数的官方注释:
 * af sink module's event processing function. Received events could be:
 * AEC/AWB/AF Bayer stats;
 * Gyro sensor stats;
 * Information request event from other module(s);
 * Information update event from other module(s);
 * It ONLY takes MCT_EVENT_DOWNSTREAM event.

static boolean af_port_event(mct_port_t * port, mct_event_t * event)

{
  switch (MCT_EVENT_DIRECTION(event)) {
  case MCT_EVENT_DOWNSTREAM: {
    switch (event->type) { 当接收到不同事件的时候做不同处理
    case MCT_EVENT_MODULE_EVENT: {
      af_port_handle_module_event(port, mod_evt);
    }
    case MCT_EVENT_CONTROL_CMD: {
      af_port_handle_control_event(port,event); //Handle control events received at AF port
    }
  } 
}

af_port_handle_control_event


static void af_port_handle_control_event(mct_port_t * port,
   mct_event_t * event) {
  switch (ctrl_evt->type) {
  case MCT_EVENT_CONTROL_SET_PARM: {
........
这里主要做一件事:af_port_handle_set_parm_event //Handle AF related set parameter calls from upper layer.
........
  }
    break;
........
  case MCT_EVENT_CONTROL_HW_SLEEP:
  case MCT_EVENT_CONTROL_HW_WAKEUP: {
    af_port_update_LPM(port,
      (cam_dual_camera_perf_control_t*)event->u.ctrl_event.control_event_data);
  }
    break;
}




static boolean af_port_handle_set_parm_event(mct_port_t *port,
  af_set_parameter_t * parm)
{
  q3a_thread_af_msg_t *af_msg = af_port_create_msg(MSG_AF_SET,parm->type, af_port); //(1)、发送命令给待命的af thread唤醒线程处理setparameter事件
  switch (parm->type) {
  case AF_SET_PARAM_FOCUS_MODE: {
    is_mode_changed = af_port_handle_set_focus_mode_evt(port, set_parm,(int)parm->u.af_mode); //Handle set parameter event to set focus mode.(更新set_parm->u.af_mode参数)
  }
    break;
}



(1)、对应上面的(1):发送命令给待命的af thread唤醒线程处理setparameter事件

vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/stats/q3a/q3a_thread.c
文件唤醒线程:
void* af_thread_handler(void *af_data) //这个线程会一直运行直到受到stop命令,当接收到上面的setparameter命令的时候,会做出反应

void* af_thread_handler(void *af_data)
{
    switch (msg->type) {
    case MSG_AF_START: {
      af_ops.set_parameters(&msg->u.af_set_parm, &camera_af->af_obj->output, 1, af_algo_obj);
      camera_af->af_obj->output.af_custom_param = af_custom_param;
      camera_af->af_cb(&(camera_af->af_obj->output), camera_af->af_port);
    }
      break;
    case MSG_AF_SEND_EVENT: {
      camera_af->af_obj->output.type = AF_OUTPUT_SEND_EVENT;
      camera_af->af_cb(&camera_af->af_obj->output, camera_af->af_port);
    }
      break;
    case MSG_AF_SET: {
      af_ops.set_parameters(&msg->u.af_set_parm, &camera_af->af_obj->output, 1, af_algo_obj) //重点关注
      camera_af->af_cb(&(camera_af->af_obj->output), camera_af->af_port); //(2)设置callback函数
    }
      break;
    case MSG_AF_STATS:
    case MSG_BF_STATS: {
        af_ops.process(msg->u.stats, &camera_af->af_obj->output, 1, af_algo_obj);
        camera_af->af_obj->output.af_custom_param =
              af_custom_param;

      camera_af->af_cb(&(camera_af->af_obj->output), camera_af->af_port);
      camera_af->af_stats_cb(camera_af->af_port, msg->u.stats);
    }
      break;
}


af_ops.set_parameters对应调用:vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/stats/q3a/af_v2/af_biz.c


boolean af_biz_set_parameters(af_set_parameter_t *param,
  af_output_data_t *output, uint8_t num_of_outputs, void *af_internal) {


  switch (param->type) {
  case AF_SET_PARAM_FOCUS_MODE:
    if (af_biz_focus_mode(af, param->u.af_mode) < 0) rc = FALSE; //Set focus mode and update required parameters.
    need_callback = TRUE;
    break;


}


static int af_biz_focus_mode(af_biz_internal *af,af_mode_type af_mode) {

  if (af_biz_focus_mode_internal(af, af->af_UI_mode) < 0) rc = FALSE; //et focus mode and update required parameters.
  return rc;
}

static int af_biz_focus_mode_internal(af_biz_internal *af,
  af_mode_type af_mode ) {

  switch (af_mode) { //根据不同的focus mode获取对应的参数设置
  case AF_MODE_AUTO:
    af->af_input.search_range.near_end_position =
      af->search_limit[AF_FOCUS_MODE_DEFAULT].near_end;
    af->af_input.search_range.far_end_position =
      af->search_limit[AF_FOCUS_MODE_DEFAULT].far_end;
    af->af_input.search_range.default_position =
      af->search_limit[AF_FOCUS_MODE_DEFAULT].default_pos;
    af->af_input.search_range.hyperfocal_position =
      algo_tuning->position_normal_hyperfocal;
    break;
  case AF_MODE_CAF:
    af->af_input.search_range.near_end_position =
      af->search_limit[AF_FOCUS_MODE_CAF].near_end;
    af->af_input.search_range.far_end_position =
      af->search_limit[AF_FOCUS_MODE_CAF].far_end;
    af->af_input.search_range.default_position =
      af->search_limit[AF_FOCUS_MODE_CAF].default_pos;
    af->af_input.search_range.hyperfocal_position =
      algo_tuning->position_normal_hyperfocal;
    break;
  case AF_MODE_NORMAL:
  case AF_MODE_CAF_NORMAL:
    af->af_input.search_range.near_end_position =
      af->search_limit[AF_FOCUS_MODE_NORMAL].near_end;
    af->af_input.search_range.far_end_position =
      af->search_limit[AF_FOCUS_MODE_NORMAL].far_end;
    af->af_input.search_range.default_position =
      af->search_limit[AF_FOCUS_MODE_NORMAL].default_pos;
    af->af_input.search_range.hyperfocal_position =
      algo_tuning->position_normal_hyperfocal;
    break;
  case AF_MODE_MACRO:
  case AF_MODE_CAF_MACRO:                                    //获取对应模式的tunning参数的设置
    af->af_input.search_range.near_end_position =
      af->search_limit[AF_FOCUS_MODE_MACRO].near_end;
    af->af_input.search_range.far_end_position =
      af->search_limit[AF_FOCUS_MODE_MACRO].far_end;
    af->af_input.search_range.default_position =
      af->search_limit[AF_FOCUS_MODE_MACRO].default_pos;
    af->af_input.search_range.hyperfocal_position =
      algo_tuning->position_normal_hyperfocal;
    break;
  case AF_MODE_INFINITY:
    af->af_input.search_range.near_end_position =
      algo_tuning->position_normal_hyperfocal;
    af->af_input.search_range.far_end_position =
      algo_tuning->position_far_end;
    af->af_input.search_range.default_position =
      algo_tuning->position_normal_hyperfocal;
    af->af_input.search_range.hyperfocal_position =
      algo_tuning->position_normal_hyperfocal;
    break;
  case AF_MODE_MANUAL_HAL1:
  case AF_MODE_MANUAL:
    af->af_input.search_range.near_end_position =
      af->search_limit[AF_FOCUS_MODE_MANUAL].near_end;
    af->af_input.search_range.far_end_position =
      af->search_limit[AF_FOCUS_MODE_MANUAL].far_end;
    af->af_input.search_range.default_position =
      af->search_limit[AF_FOCUS_MODE_MANUAL].default_pos;
    af->af_input.search_range.hyperfocal_position =
      algo_tuning->position_normal_hyperfocal;
    break;
  }

  if (!rc) {
    af_biz_util_update_output_data(af, AF_OUTPUT_FOCUS_MODE, NULL); //Update data that needs to be output in internal structure
    if (af->af_mode_changed == TRUE) {
      if (!IS_CAF_ENABLED(af_mode)) {
        if (af_mode == AF_MODE_INFINITY) {
          if(af->sof_id != 0) {
            af_biz_move_lens_to(af, af->af_mode.default_pos);
            af->move_lens_to_def_pos = TRUE;
          }
        }
      }
      if ((!af->lens_reset_on_init) &&
        (af_mode == AF_MODE_MANUAL || af_mode == AF_MODE_MANUAL_HAL1)) {
        af_biz_reset_lens(af);
        af->lens_reset_on_init = TRUE;
      }
      if(af->af_mode.prev_mode == AF_MODE_MANUAL ||
        af->af_mode.prev_mode == AF_MODE_MANUAL_HAL1){
        af_biz_reset_lens(af);
      }
    }
  }
  af->af_algo_ops.set_parameters(af->af_core, &set_param, &af->af_core_out); //这里就调用到了高通算法
}

具体的算法库为:libmmcamera2_q3a_core.so高通算法库,封装在vendor/qcom/proprietary/prebuilt_HY11/target/product/sdm660_64/vendor/lib/下,编译时会被放到out目录里


(2)、对应上面的(2)、设置callback函数.上面调用完3a算法库后执行回调函数
vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/stats/q3a/af_v2/af_port.c
static void af_port_callback(af_output_data_t *af_out, void *p)


该函数根据3a算法输出的result(af_out->result)对具体的focus进行设置
例如:
af_port_process_status_update
af_port_get_optimal_focus_distance 等等
并且更新参数回hal:
af_port_handle_set_focus_mode_to_hal_type















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值