QualComm Android5.1 Camera浅谈-daemon进程
来源:互联网 发布:matlab编程题目 编辑:程序博客网 时间:2024/05/20 01:35
转载来自:http://blog.csdn.net/a04081122/article/details/52981001
vendor\qcom\proprietary\mm-camera\mm-camera2\server-imaging\server.c //daemon进程开始
int main(int argc, char *argv[])
{
1. serv_hal_node_name = malloc((size_t)MAX_DEV_NAME_SIZE); 为节点分配内存
if (get_server_node_name(serv_hal_node_name) == FALSE)//找到/dev/video0节点
hal_fd = malloc(sizeof(read_fd_info_t));
snprintf(dev_name, sizeof(dev_name), "/dev/%s", serv_hal_node_name);
hal_fd->fd[0] = open(dev_name, O_RDWR | O_NONBLOCK);//打开/dev/video0节点,并设置type为RD_FD_HAL
hal_fd->type = RD_FD_HAL;
if (!(listen_fd_list = mct_list_append(listen_fd_list, hal_fd, NULL, NULL))) //将hal_fd加入到监听链表listen_fd_list中
2. if(server_process_module_sensor_init() == FALSE)
if (server_process_module_init() == FALSE)
//调用server_process.c中的各个module的init函数,并通过mct_list_append()函数,将每个模块的init函数生成的mct_module_t加入到static mct_list_t *modules = NULL链表中。
static mct_module_init_name_t modules_list[] = {
{"sensor", module_sensor_init, module_sensor_deinit, NULL},
{"iface", module_iface_init, module_iface_deinit, NULL},
{"isp", module_isp_init, module_isp_deinit, NULL},
{"stats", stats_module_init, stats_module_deinit, NULL},
{"pproc", pproc_module_init, pproc_module_deinit, NULL},
{"imglib", module_imglib_init, module_imglib_deinit, NULL},
};
其中,module_sensor_init()函数中,通过判断entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT,找到相应的
/dev/v4l-subdevX节点并打开,并通过LOG_IOCTL(fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg),将sensor IC的有关信息拷贝到内核空间,调用msm_sensor_driver_probe()函数,
/* Power up and probe sensor */
rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
rc为0,表明sensro I2C通信正常,接着通过
msm_sensor_driver_create_i2c_v4l_subdev(),生成了/dev/media1&/dev/video1(后)和/dev/media2&/dev/video2(前)节点,并通过msm_sd_register(&s_ctrl->msm_sd)注册前后摄像头的sensor。
用户空间的module_sensor_find_sensor_subdev(module_ctrl)和module_sensor_find_other_subdev(module_ctrl)函数,把前后sensor,actuator,csi,isp等从设备的文件节点一一确定好,并加入到module_ctrl->sensor_bundle链表中。
/* Subcribe V4L2 event */
memset(&subscribe, 0, sizeof(struct v4l2_event_subscription));
subscribe.type = MSM_CAMERA_V4L2_EVENT_TYPE;
for (i = MSM_CAMERA_EVENT_MIN + 1; i < MSM_CAMERA_EVENT_MAX; i++) {
subscribe.id = i;
if (ioctl(hal_fd->fd[0], VIDIOC_SUBSCRIBE_EVENT, &subscribe) < 0) //通过服务设备文件的ioctl接口,订阅所有的事件(enent id)
goto subscribe_failed;
}
select_fds.select_fd = hal_fd->fd[0];
3. do {
FD_ZERO(&(select_fds.fds));
mct_list_traverse(listen_fd_list, server_reset_select_fd, &select_fds);
/* no timeout */
ret = select(select_fds.select_fd + 1, &(select_fds.fds), NULL, NULL, NULL);
if (ret > 0) {
mct_list_t *find_list;
read_fd_info_t *fd_info;
find_list = mct_list_find_custom(listen_fd_list, &(select_fds.fds),
server_check_listen_fd);
if (!find_list)
continue;
fd_info = (read_fd_info_t *)find_list->data;
CDBG("CAMERA_DAEMON:fd_info->fd[0]\n",fd_info->fd[0]);
switch (fd_info->type) {
case RD_FD_HAL: {
if (ioctl(fd_info->fd[0], VIDIOC_DQEVENT, &event) < 0)//下命令让服务模块的事件出队列进行处理
continue;
/* server process HAL event:
*
* 1. if it returns success, it means the event message has been
* posted to MCT, don't need to send CMD ACK back to kernel
* immediately, because MCT will notify us after process;
*
* 2. if it returns failure, it means the event message was not
* posted to MCT successfully, hence we need to send CMD ACK back
* to kernel immediately so that HAL thread which sends this
* event can be blocked.
*/
if (event.id == MSM_CAMERA_NEW_SESSION) {
serv_in.it_value.tv_sec = 5;
serv_in.it_value.tv_nsec = 0;
serv_in.it_interval.tv_sec = serv_in.it_value.tv_sec;
serv_in.it_interval.tv_nsec = serv_in.it_value.tv_nsec;
timer_settime(serv_timerid, 0, &serv_in, &serv_out);
} else if (event.id == MSM_CAMERA_DEL_SESSION) {
serv_in.it_value.tv_sec = 5;
serv_in.it_value.tv_nsec = 0;
serv_in.it_interval.tv_sec = serv_in.it_value.tv_sec;
serv_in.it_interval.tv_nsec = serv_in.it_value.tv_nsec;
timer_settime(serv_timerid, 0, &serv_in, &serv_out);
}
proc_ret = server_process_hal_event(&event);
serv_in.it_value.tv_sec = 0;
serv_in.it_value.tv_nsec = 0;
serv_in.it_interval.tv_sec = serv_in.it_value.tv_sec;
serv_in.it_interval.tv_nsec = serv_in.it_value.tv_nsec;
timer_settime(serv_timerid, 0, &serv_in, &serv_out);
}
break;
case RD_DS_FD_HAL:
/* server process message sent by HAL through Domain Socket */
proc_ret = server_process_hal_ds_packet(fd_info->fd[0],
fd_info->session);
break;
case RD_PIPE_FD_MCT:
/* server process message sent by media controller
* through pipe: */
proc_ret = server_process_mct_msg(fd_info->fd[0],
fd_info->session);
break;
default:
continue;
} /* switch (fd_info->type) */
switch (proc_ret.result) {
case RESULT_NEW_SESSION: {
struct msm_v4l2_event_data *ret_data =
(struct msm_v4l2_event_data *)proc_ret.ret_to_hal.ret_event.u.data;
if( ret_data->status == MSM_CAMERA_CMD_SUCESS) {
hal_ds_fd = malloc(sizeof(read_fd_info_t));
if (!hal_ds_fd) {
/* Shouldn't end directly, need to shutdown MCT thread */
goto server_proc_new_session_error;
} else {
hal_ds_fd->session = proc_ret.new_session_info.session_idx;
hal_ds_fd->fd[0] = proc_ret.new_session_info.hal_ds_fd;
hal_ds_fd->type = RD_DS_FD_HAL;
}
mct_fds = malloc(sizeof(read_fd_info_t));
if (!mct_fds) {
free(hal_ds_fd);
goto server_proc_new_session_error;
} else {
mct_fds->session = proc_ret.new_session_info.session_idx;
mct_fds->fd[0] = proc_ret.new_session_info.mct_msg_rd_fd;
mct_fds->fd[1] = proc_ret.new_session_info.mct_msg_wt_fd;
mct_fds->type = RD_PIPE_FD_MCT;
}
if (!(listen_fd_list = mct_list_append(listen_fd_list,
hal_ds_fd, NULL, NULL))) {
free(hal_ds_fd);
free(mct_fds);
goto server_proc_new_session_error;
}
if (!(listen_fd_list = mct_list_append
(listen_fd_list, mct_fds, NULL, NULL))) {
free(hal_ds_fd);
free(mct_fds);
goto server_proc_new_session_error;
}
} else {
CDBG_ERROR("%s: New session [%d] creation failed with error",
__func__, ret_data->session_id);
}
goto check_proc_ret;
} /* RESULT_NEW_SESSION */
break;
case RESULT_DEL_SESSION: {
mct_list_t *find_list;
read_fd_info_t fd_info_match;
read_fd_info_t *ds_fd_info = NULL, *mct_fd_info = NULL;
struct msm_v4l2_event_data *event_data = (struct msm_v4l2_event_data *)
&proc_ret.ret_to_hal.ret_event.u.data[0];
/* this is for Domain Socket FD */
fd_info_match.type = RD_DS_FD_HAL;
fd_info_match.session = event_data->session_id;
find_list = mct_list_find_custom(listen_fd_list, &fd_info_match,
server_find_listen_fd);
if (find_list) {
ds_fd_info = (read_fd_info_t *)find_list->data;
listen_fd_list = mct_list_remove(listen_fd_list, ds_fd_info);
FD_CLR(ds_fd_info->fd[0], &select_fds.fds);
close(ds_fd_info->fd[0]);
free(ds_fd_info);
}
/* this is for MCT FD */
fd_info_match.type = RD_PIPE_FD_MCT;
find_list = mct_list_find_custom(listen_fd_list, &fd_info_match,
server_find_listen_fd);
if (find_list) {
mct_fd_info = (read_fd_info_t *)find_list->data;
listen_fd_list = mct_list_remove(listen_fd_list, mct_fd_info);
FD_CLR(mct_fd_info->fd[0], &select_fds.fds);
close(mct_fd_info->fd[0]);
close(mct_fd_info->fd[1]);
free(mct_fd_info);
}
} /* case RESULT_DEL_SESSION */
goto check_proc_ret;
break;
case RESULT_FAILURE:
goto server_proc_error;
break;
case RESULT_SUCCESS:
goto check_proc_ret;
break;
default:
break;
} /* switch (proc_ret.result) */
server_proc_new_session_error:
event.id = MSM_CAMERA_DEL_SESSION;
server_process_hal_event(&event);
server_proc_error:
proc_ret.ret_to_hal.ret = TRUE;
check_proc_ret:
if (proc_ret.ret_to_hal.ret == TRUE) {
switch (proc_ret.ret_to_hal.ret_type) {
/* @MSM_CAM_V4L2_IOCTL_CMD_ACK is Ack-knowledge to HAL's
* control command, which has command processing status.
*/
case SERV_RET_TO_HAL_CMDACK:
ioctl(hal_fd->fd[0], MSM_CAM_V4L2_IOCTL_CMD_ACK,
(struct msm_v4l2_event_data *)&(proc_ret.ret_to_hal.ret_event.u.data));
break;
/* @MSM_CAM_V4L2_IOCTL_NOTIFY is MCT originated event such
* as meta data, SOF etc. Normally it comes
* 1. domain socket buffer mapping process;
* 2. from MCT.
*/
case SERV_RET_TO_HAL_NOTIFY:
ioctl(hal_fd->fd[0], MSM_CAM_V4L2_IOCTL_NOTIFY,
&(proc_ret.ret_to_hal.ret_event.u.data));
break;
/* @MMSM_CAM_V4L2_IOCTL_NOTIFY_META is Meta data notification
* sent back to HAL during streaming. It is generated by
* BUS message.
*/
case SERV_RET_TO_KERNEL_NOTIFY_POSSIBLE_FREEZE:
ioctl(hal_fd->fd[0], MSM_CAM_V4L2_IOCTL_NOTIFY_FREEZE,
&(proc_ret.ret_to_hal.ret_event.u.data));
break;
case SERV_RET_TO_HAL_NOTIFY_ERROR:
ioctl(hal_fd->fd[0], MSM_CAM_V4L2_IOCTL_NOTIFY_ERROR,
&(proc_ret.ret_to_hal.ret_event.u.data));
break;
default:
break;
}
}
} else {
/* select failed. it cannot time out.*/
/* TO DO: HANDLE ERROR */
}
} while (1);
- QualComm Android5.1 Camera浅谈-daemon进程
- QualComm Android5.1 Camera浅谈-daemon进程module_sensor_find_other_subdev(module_ctrl)
- QualComm Android5.1 Camera浅谈-kernel
- QualComm Android5.1 Camera浅谈-HAL
- Qualcomm 8X camera daemon进程浅析
- Qualcomm 8X camera daemon进程浅析
- Qualcomm 8X camera daemon进程浅析 .
- Qualcomm 8X camera daemon进程浅析
- Android Camera架构浅析 && Qualcomm 8X camera daemon进程浅析
- Android Camera架构浅析 && Qualcomm 8X camera daemon进程浅析
- Qualcomm 8X camera daemon过程浅析
- camera daemon进程
- Qualcomm Camera
- Qualcomm Camera
- Qualcomm Camera
- Qualcomm Camera
- Qualcomm 8X camera daemon过程浅析 (太好了 只有先收藏 非常感谢)
- Camera Daemon
- Android dialogUtils 拿来就用
- 校企兼职平台(二)
- Oracle表结构查询语句
- Codeforces#388div.2 2017-01-05 practice
- Android常用工具类-Utils
- QualComm Android5.1 Camera浅谈-daemon进程
- Android Studio如何快速生成get,set,tostring,构造函数
- docker端口映射失败解决
- notepad++ 匹配行匹配包含特定字符的行或空行
- CentOS 6.7 安装VNC
- 第024 b s 和 c s 的优劣
- RecyclerView点击事件处理
- 基于FPGA的PCIe接口实现
- 第025 web服务器 apache服务器安装