open流程一主要是沿着open的主线一直到sensor open,着一些主要是看看 camera_init_internal 中的其他初始化流程

cmr_int camera_init_internal(cmr_handle oem_handle, cmr_uint is_autotest) {···//sensor初始化ret = camera_sensor_init(oem_handle, is_autotest);//grab初始化ret = camera_grab_init(oem_handle);//res初始化ret = camera_res_init(oem_handle);//isp初始化ret = camera_isp_init(oem_handle);//初始化完成ret = camera_res_init_done(oem_handle);//前置摄像头,lcd屏幕可以作为补光灯camera_front_lcd_enhance_module_init(oem_handle);···return ret;
}

书接上篇我们分析了camera_sensor_init这个函数,下面我们对其他的初始化流程分析。

1、camera_grab_init

这个主要时图形数据的传输

idh.code\vendor\sprd\modules\libcamera\oem2v6\src\cmr_oem.c

cmr_int camera_grab_init(cmr_handle oem_handle) {struct phySensorInfo *phyPtr = NULL;cmr_int ret = CMR_CAMERA_SUCCESS;struct camera_context *cxt = (struct camera_context *)oem_handle;struct grab_context *grab_cxt = NULL;struct sensor_context *sn_cxt = NULL;cmr_handle grab_handle = NULL;struct grab_init_param grab_param;struct sensor_exp_info sensor_info;cmr_bzero(&sensor_info, sizeof(struct sensor_exp_info));grab_cxt = &cxt->grab_cxt;sn_cxt = &(cxt->sn_cxt);ret = cmr_sensor_get_info(sn_cxt->sensor_handle, cxt->camera_id,&(sn_cxt->sensor_info));phyPtr = sensorGetPhysicalSnsInfo(cxt->camera_id);if (0 == grab_cxt->inited) {grab_param.oem_handle = oem_handle;grab_param.sensor_id = phyPtr->slotId;ret = cmr_grab_init(&grab_param, &grab_handle);if (ret) {CMR_LOGE("failed to init grab %ld", ret);ret = -CMR_CAMERA_NO_SUPPORT;goto exit;}cmr_grab_evt_reg(grab_handle, camera_grab_evt_cb);//p_grab->grab_evt_cb = grab_event_cb;cmr_grab_stream_cb(grab_handle, camera_sensor_streamctrl);//p_grab->stream_on_cb = str_on(camera_sensor_streamctrl)/*only raw sensor should init isp*/if (CAM_IMG_FMT_BAYER_MIPI_RAW == sn_cxt->sensor_info.image_format) {    cmr_grab_isp_statis_evt_reg(grab_handle, isp_statis_evt_cb);//p_grab->isp_statis_evt_cb = isp_statis_event_cb;cmr_grab_isp_irq_proc_evt_reg(grab_handle, isp_irq_proc_evt_cb);//p_grab->isp_irq_proc_evt_cb = isp_irq_proc_event_cb;}cmr_grab_post_ynr_evt_reg(grab_handle, camera_grab_post_ynr_evt_cb);//p_grab->grab_post_ynr_evt_cb = grab_post_ynr_evt_cb;grab_cxt->inited = 1;grab_cxt->grab_handle = grab_handle;}return ret;
}

这个函数我们主要是初始化 grab_handle,包含各种回调。回调函数的调用时在cmr_grab_init中的线程调用的。

这里我们先看cmr_grab_init函数

idh.code\vendor\sprd\modules\libcamera\oem2v6\src\cmr_grab.c

cmr_int cmr_grab_init(struct grab_init_param *init_param_ptr,cmr_handle *grab_handle) {cmr_int ret = 0;cmr_u32 i = 0;cmr_u32 channel_id;struct cmr_grab *p_grab = NULL;struct sprd_img_res res;p_grab = (struct cmr_grab *)malloc(sizeof(struct cmr_grab));p_grab->init_param = *init_param_ptr;p_grab->fd = open(CMR_GRAB_DEV_NAME, O_RDWR, 0);//#define CMR_GRAB_DEV_NAME "/dev/sprd_image"ret = pthread_mutex_init(&p_grab->cb_mutex, NULL);ret = pthread_mutex_init(&p_grab->dcam_mutex, NULL);ret = pthread_mutex_init(&p_grab->status_mutex, NULL);for (channel_id = 0; channel_id < CHN_MAX; channel_id++) {ret = pthread_mutex_init(&p_grab->path_mutex[channel_id], NULL);}pthread_mutex_lock(&p_grab->dcam_mutex);if (0 == p_grab->mode_enable) {res.sensor_id = p_grab->init_param.sensor_id;ret = ioctl(p_grab->fd, SPRD_IMG_IO_GET_DCAM_RES, &res);//获取一些dcam的信息,具体分析等分析驱动时在说p_grab->res = res.flag;p_grab->mode_enable = 1;}pthread_mutex_unlock(&p_grab->dcam_mutex);sem_init(&p_grab->close_sem, 0, 0);ret = cmr_grab_create_thread((cmr_handle)p_grab);//pthread_create(&p_grab->thread_handle, &attr, cmr_grab_thread_proc, (void *)grab_handle);//这里创建一个线程用来读取/dev/sprd_image,根据读取额数据调用对应的回调函数p_grab->grab_evt_cb = NULL;p_grab->stream_on_cb = NULL;p_grab->isp_cb_enable = 1;memset(p_grab->chn_status, 0, sizeof(p_grab->chn_status));*grab_handle = (cmr_handle)p_grab;return ret;
}

这里时初始化grab_handle结构体,同时启动一个线程。

static void *cmr_grab_thread_proc(void *data) {cmr_s32 evt_id = -1;struct frm_info frame;cmr_u32 on_flag = 0;cmr_s32 frm_num = -1;cmr_s32 cnt;struct cmr_grab *p_grab;struct img_data_end endian;struct sprd_img_read_op op;struct sprd_img_res res;struct sprd_img_statis_info statis_info;struct sprd_irq_info irq_info;p_grab = (struct cmr_grab *)data;struct camera_context *cxt = (struct camera_context *)p_grab->init_param.oem_handle;while (1) {cnt = sizeof(struct sprd_img_read_op);op.cmd = SPRD_IMG_GET_FRM_BUFFER;op.sensor_id = p_grab->init_param.sensor_id;if (cnt != read(p_grab->fd, &op, sizeof(struct sprd_img_read_op))) {CMR_LOGE("read failed");break;}if (IMG_TX_STOP == op.evt) {// stopped , to do release resourceCMR_LOGI("TX Stopped, exit thread");break;} else if (IMG_SYS_BUSY == op.evt) {CMR_LOGI("continue");continue;} else {if (op.parm.frame.irq_type == CAMERA_IRQ_IMG ||op.parm.frame.irq_type == CAMERA_IRQ_4IN1_DONE) {if (p_grab->grab_evt_cb) {(*p_grab->grab_evt_cb)(evt_id, &frame,(void *)p_grab->init_param.oem_handle);}} else if (op.parm.frame.irq_type == CAMERA_IRQ_STATIS) {      if (p_grab->isp_statis_evt_cb && p_grab->isp_cb_enable) {(*p_grab->isp_statis_evt_cb)(evt_id, &statis_info, (void *)cxt->isp_cxt.isp_handle);}} else if (op.parm.frame.irq_type == CAMERA_IRQ_DONE) {if (p_grab->isp_irq_proc_evt_cb && p_grab->isp_cb_enable) {CMR_LOGV("irq_info.irq_property = %d",irq_info.irq_property);(p_grab->isp_irq_proc_evt_cb)(evt_id, &irq_info, (void *)cxt->isp_cxt.isp_handle);}} else if (op.parm.frame.irq_type == CAMERA_IRQ_POST_YNR_DONE) {if (p_grab->grab_post_ynr_evt_cb && p_grab->isp_cb_enable) {(p_grab->grab_post_ynr_evt_cb)(evt_id, NULL, (void *)p_grab->init_param.oem_handle);}}}}return NULL;
}

这里在循环的读取sprd_image节点,根据读取出来的数据类型和中断类型调用不同的回调函数。我们的帧数就是这里从这里开始向上传递的,后面单独介绍帧数据流程。

2、camera_res_init

idh.code\vendor\sprd\modules\libcamera\oem2v6\src\cmr_oem.c

cmr_int camera_res_init(cmr_handle oem_handle) {cmr_int ret = CMR_CAMERA_SUCCESS;struct camera_context *cxt = (struct camera_context *)oem_handle;CMR_MSG_INIT(message);CMR_PRINT_TIME;sem_init(&cxt->hdr_sync_sm, 0, 0);sem_init(&cxt->hdr_flag_sm, 0, 1);sem_init(&cxt->threednr_flag_sm, 0, 1);sem_init(&cxt->cnr_flag_sm, 0, 1);sem_init(&cxt->dre_flag_sm, 0, 1);sem_init(&cxt->ai_scene_flag_sm, 0, 1);sem_init(&cxt->filter_sm, 0, 1);sem_init(&cxt->share_path_sm, 0, 0);sem_init(&cxt->access_sm, 0, 1);sem_init(&cxt->sbs_sync_sm, 0, 0);cxt->err_code = CMR_CAMERA_SUCCESS;/*create thread*/ret = cmr_thread_create((cmr_handle *)&cxt->init_thread,CAMERA_OEM_MSG_QUEUE_SIZE, camera_init_thread_proc,(void *)cxt);ret = cmr_thread_set_name(cxt->init_thread, "res_init");message.msg_type = CMR_EVT_INIT;message.sync_flag = CMR_MSG_SYNC_NONE;ret = cmr_thread_msg_send(cxt->init_thread, &message);return ret;
}

这个函数主要是初始化一些信号量,创建一个线程程序,调用这个线程程序。

static cmr_int camera_init_thread_proc(struct cmr_msg *message, void *p_data) {cmr_int ret = CMR_CAMERA_SUCCESS;cmr_u32 msg_type = 0;cmr_uint evt = 0;cmr_u32 camera_id = CAMERA_ID_MAX;struct camera_context *cxt = (struct camera_context *)p_data;msg_type = (cmr_u32)message->msg_type;switch (msg_type) {case CMR_EVT_INIT:cxt->err_code = camera_res_init_internal((cmr_handle)cxt);if (cxt->err_code) {camera_res_deinit_internal((cmr_handle)cxt);}CMR_LOGI("cb thread inited");break;......default:break;}return ret;
}
static cmr_int camera_res_init_internal(cmr_handle oem_handle) {cmr_int ret = CMR_CAMERA_SUCCESS;struct camera_context *cxt = (struct camera_context *)oem_handle;ret = camera_ipm_init(oem_handle);//初始化oem_handle->ipm_cxt->ipm_handleret = camera_setting_init(oem_handle);//初始化oem_handle->setting_cxt->setting_handleret = camera_focus_init(oem_handle);//初始化oem_handle->focus_cxt->focus_handleret = camera_jpeg_init(oem_handle);//初始化oem_handle->jpeg_cxt->jpeg_handle,这里导入libjpeg_hw_sprd.soret = camera_scaler_init(oem_handle);//初始化oem_handle->scaler_cxt->scaler_handle,这里会open /dev/sprd_cppret = camera_rotation_init(oem_handle);//初始化oem_handle->rot_cxt->rotation_handle,这里会open /dev/sprd_cppret = camera_preview_init(oem_handle);ret = camera_interface_init();ret = camera_snapshot_init(oem_handle);ret = camera_init_thread(oem_handle);return ret;
}

这个接口这要是对camera_context 中成员变量xxx_context 进行初始化,初始化对应的工作程序。

这里主要看一下preview 和 snapshot 相关的初始化

1)camera_preview_init

这里是继续给oem_handle下的各种context初始化。

cmr_int camera_preview_init(cmr_handle oem_handle) {cmr_int ret = CMR_CAMERA_SUCCESS;struct camera_context *cxt = (struct camera_context *)oem_handle;struct preview_context *prev_cxt = NULL;struct preview_init_param init_param;prev_cxt = &cxt->prev_cxt;init_param.oem_handle = oem_handle;init_param.ipm_handle = cxt->ipm_cxt.ipm_handle;init_param.ops.channel_cfg = camera_channel_cfg;//...很多操作函数的赋值,省略init_param.oem_cb = camera_preview_cb;init_param.private_data = NULL;init_param.sensor_bits = (1 << cxt->camera_id);ret = cmr_preview_init(&init_param, &prev_cxt->preview_handle);prev_cxt->inited = 1;return ret;
}

在cmr_preview_init 中主要是将init_param 用来初始化preview_handle 的成员变量。同时也生成几个很重要的线程程序。

cmr_thread_create(&handle->thread_cxt.assist_thread_handle,
                                PREV_MSG_QUEUE_SIZE, prev_assist_thread_proc,
                                (void *)handle);

cmr_thread_create(&handle->thread_cxt.thread_handle,
                                PREV_MSG_QUEUE_SIZE, prev_thread_proc,
                                (void *)handle);

cmr_thread_create(&handle->thread_cxt.cb_thread_handle,
                            PREV_MSG_QUEUE_SIZE, prev_cb_thread_proc,
                            (void *)handle);

这些程序在预览流程中有很重要的作用。

2)camera_snapshot_init

这个和cmr_preview_init 类似,但是生成的线程程序会多很多。

snapshot_context -----> snp_context---------> snp_thread_context 有多少个cmr_handle了

3)camera_init_thread

是对camera_context 下的cmr_handle 生成线程程序。

3、camera_isp_init

isp这一类的还不太懂暂时这样。

总结:

我觉这个open 流程主要是对sensor、isp等进行简单初始化和设置,注册操作函数集和回调函数,同时生成一些线程程序,便于preview 和 snapshot 时调用。

[SPRD CAMERA] 5 HAL Camera open流程二相关推荐

  1. [SPRD CAMERA] 4 HAL Camera open流程一

    前言 最近在搞8581的camera问题,作为一个新手从没有做过camera部分,希望通过这一系列的文章记录自己学习过程.     大量参考大神的文章:[Camera专题]你应该熟悉的Camera驱动 ...

  2. Android4.2之Camera系统HAL调用流程

    一.重要结构体 1.模块 hardware/libhardware/include/hardware/camera_common.h [cpp] view plaincopy typedef stru ...

  3. MTK6735 camera 闪光灯Flashlight驱动调试流程学习

    MTK6735 camera 闪光灯Flashlight驱动调试流程学习 一.Flash驱动涉及到的文件包含: kernel-3.10/drivers/misc/mediatek/flashlight ...

  4. 51全志R58平台Android4.4下Camera的HAL层修改

    51全志R58平台Android4.4下Camera的HAL层修改 2018/11/7 15:20 版本:V1.0 开发板:SC5806 1.系统编译: (略) 2.全志R58平台Android4.4 ...

  5. 【camera专题】 Camera Open/Close (1)

    系列文章 基于HAL1: camera hal层框架源码系列: HAL1 – Camera Open/Close (1) 一.代码流程图 整个流程就很清晰了. 二.源码及log分析 1.camera ...

  6. Android Camera HAL3 - Multi Camera(1)

    本文介绍下 Google Android 在其文档中对于 Multi-Camera 的描述,以及 Android R 中对 Camera HAL3 的一些新增内容,Multi-Camera 从 And ...

  7. android camera(三):camera V4L2 FIMC

    关键词: android  camera CMM 模组 camera参数  CAMIF   V4L2   平台信息: 内核: linux 系统: android 平台:S5PV310(samsung ...

  8. android camera(四):camera 驱动 GT2005

    关键词:android  camera CMM 模组 camera参数  GT2005 摄像头常见问题 平台信息: 内核:linux 系统:android 平台:S5PV310(samsung exy ...

  9. android l camera no panorama,camera预览是闪退的有关问题

    camera预览是闪退的问题 使用ov8825 sensor时,如果是摄像预览可以点亮,如果切换到拍照预览时,apk闪退.log如下: root@rk3288:/ # logcat logcat -- ...

最新文章

  1. android surface 平板,Surface平板能升级安卓4.0吗
  2. Navicat for Oracle工具连接oracle
  3. mysql 重启io线程_MySQL IO线程及相关参数调优
  4. 【经验分享】产品、运营人如何告别重复的数据分析工作?
  5. Nagios:企业级系统监控方案
  6. 报错The sandbox is not in sync with the Podfile.lock
  7. TensorFlow 全网最全学习资料汇总之TensorFlow的技术应用
  8. burpsuite小米手机抓包_使用burpsuite实现Android APP的HTTPS抓包
  9. [转]WeiFenLuo.winFormsUI.Docking.dll的使用(简单入门版)
  10. Linux-rhel6.4 编译安装PHP,Nginx与php连接
  11. 洛谷——P1422 小玉家的电费
  12. zpf框架的business使用方法
  13. OpenCasCade将鼠标点映射到OCC三维视图中的三维点(鼠标点转换为OCC三维坐标)
  14. winyyy sys hcpidesk sys mtlrd sys uldfhjfh sys servets exe等1
  15. 常见的立体匹配算法介绍
  16. plc无线连接服务器,plc连接云服务器
  17. LinUX接收蓝牙音频,Win10 v2004已重新支持蓝牙A2DP音频串流接收功能
  18. pentaho mysql_pentaho BI Server-4.5 迁移到mysql详解
  19. 嵌入式算法8---空间向量夹角公式及其应用
  20. 多么痛的领悟,只有程序员才知道的12个人艰不拆的真相

热门文章

  1. 20世纪中文电影一百强
  2. android页面布局计算机,Android Studio制作简单计算器App
  3. 大学生期末网页大作业:基于HTML+CSS+JavaScript蓝色的汽车设备营销企业网站模板13页面
  4. Air Jordan 32 Performance Review
  5. 数据仓库:维度分析和指标
  6. SQL AlawaysOn 之三:SQL服务器加入域
  7. sumo交通流仿真软件的使用说明
  8. lombok导入报错,版本1.18.12已在maven本地仓库中
  9. 电脑所有的浏览器都上不了网怎么解决
  10. weblogic新建一个managed server并启动