qual_camera_video
来源:互联网 发布:java面试基础知识 编辑:程序博客网 时间:2024/05/29 08:29
/*******************************************
********** qual_camera_stats CODE WALK THROUTH ************
*************************************************
********************************************/
//main函数在qcom\proprietary\mm-camera\mm-camera2\server-imaging\Server.c
int main(int argc, char *argv[])---->server_process_module_init会调用到下边的init数组
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},
};
我们这里关注stats_module_init函数
stats_module_init
mct_module_create("stats");
for{stats_mods_list[i].init_mod} //这里会call到sub module的init函数,如下sub module表
---->q3a_module_init
mct_module_create("q3a");
aec_module_init("aec"); //这三个是q3a的三个sub module
awb_module_init("awb");
af_module_init("af");
stats module 下有好多sub module,如下
static mct_module_init_name_t stats_mods_list[] = {
{ "q3a", q3a_module_init, q3a_module_deinit },
{ "afd", afd_module_init, afd_module_deinit },
{ "asd", asd_module_init, asd_module_deinit },
{ "is", is_module_init, is_module_deinit},
};
camera launch的时候stats_module_start_session会被调用到***** //Stats_module.c (qcom\proprietary\mm-camera\mm-camera2\media-controller\modules\stats)
下边解释stats_module_start_session为什么会被call到
mm_camera_open //Mm_camera.c (hardware\qcom\camera\qcamera2\stack\mm-camera-interface\src)
open(dev_name, O_RDWR | O_NONBLOCK);导致camera_v4l2_open(struct file *filep)被调用 //Camera.c (drivers\media\platform\msm\camera_v2\camera)
camera_v4l2_open
camera_pack_event(filep, MSM_CAMERA_NEW_SESSION, 0, -1, &event); //发送event,会调用到下边的函数
server_process_hal_event 函数中case MSM_CAMERA_NEW_SESSION: mct_controller_new(modules, data->session_id, pipe_fd[1])
mct_controller_new(modules, data->session_id, pipe_fd[1])会调用到mct_pipeline_start_session--->mct_pipeline_modules_start--->mct_pipeline_start_session_thread----
---->module->start_session(为每一个module调用start_session动作,即调用/********stats_module_start_session*******/)
stats_module_start_session的调用过程
/* Now need to create a new sink port */
port = mct_port_create("stats_sink"); //这里只create了一个port ,因为这里stats只有一个入口,
stats_module_sub_mod_start_session
module->start_session //这里的start_session可以是q3a_module.c的start_session----
------>q3a_module_start_session //创建一个port,和三个子module的start_session
mct_port_create("q3a_sink");
private->aec_module->start_session(private->aec_module, sessionid);
private->awb_module->start_session(private->awb_module, sessionid);
private->af_module->start_session(private->af_module, sessionid);
aec_port = aec_module_get_port(private->aec_module, sessionid);
awb_port = awb_module_get_port(private->awb_module, sessionid);
af_port = af_module_get_port(private->af_module, sessionid);
q3a_port_init(port, aec_port, awb_port, af_port, //对这些port做init动作
sub.sub_ports = NULL; //存放后边所有的port
stats_port_init(port, sessionid , sub.sub_ports)
port->direction = MCT_PORT_SINK; //port的方向
caps.port_caps_type = MCT_PORT_CAPS_STATS;
mct_port_set_event_func(port, stats_port_event); //这个function会用来做port跟port之间event的deliever跟receive
mct_port_set_set_caps_func(port, stats_port_set_caps);
mct_port_set_ext_link_func(port, stats_port_ext_link); //port跟port做link的时候会用到
mct_port_set_unlink_func(port, stats_port_unlink);
mct_port_set_check_caps_reserve_func(port, stats_port_check_caps_reserve);
mct_port_set_check_caps_unreserve_func(port, stats_port_check_caps_unreserve);
再看q3a的sub module 的start_session
aec_module_start_session
mct_port_create("aec_sink");
mct_module_add_port(module, port)
//如何get到这些port可以参考如下函数,最终结果是所有的port存在sub.sub_ports中
stats_module_get_sub_ports
message 的handle (upstream跟downstream)
port跟port之间event的都会调用到stats_port_event,上边有说到,在stats_port.c中
stats_port_event //有两个方向的event,MCT_EVENT_UPSTREAM和MCT_EVENT_DOWNSTREAM
case MCT_EVENT_UPSTREAM
case MCT_EVENT_DOWNSTREAM:
这里继续根据event的type和ctrl的type来进行不同的处理
最终会调用到这,把event进一步发送到sub module的port_event(),如q3a_port_event(),会送到所有的port,如果不合适可以不处理
mct_list_traverse((mct_list_t *)private->sub_ports, stats_port_send_event_downstream, &port_event);
q3a_port_event()
case MCT_EVENT_UPSTREAM
case MCT_EVENT_DOWNSTREAM:
q3a_port_send_event_downstream(port, event)
MCT_PORT_EVENT_FUNC(private->aec_port)(private->aec_port, event); //调用到aec的port的event(aec_port_event)
MCT_PORT_EVENT_FUNC(private->awb_port)(private->awb_port, event);
MCT_PORT_EVENT_FUNC(private->af_port)(private->af_port, event);
aec_port_event
case MCT_EVENT_UPSTREAM
case MCT_EVENT_DOWNSTREAM:
aec_port_proc_downstream_event(port, event);
af_port_event
af_port_handle_module_event(port, mod_evt);
q3a_af_thread_en_q_msg(af_port->thread_data, af_msg); 会调用到q3a_thread如下
af_thread_handler //Q3a_thread.c (qcom\proprietary\mm-camera\mm-camera2\media-controller\modules\stats\q3a)
case MSG_BF_STATS:af->af_obj->af_ops.process(msg->u.stats, &(af->af_obj->output),
af->af_cb(& (af->af_obj->output), af->af_port); ----->af_port_callback(每个port都会有自己的callback函数)
af_port_callback
event.direction = MCT_EVENT_UPSTREAM; 改变传送方向后,它会向down的所有port传送此event
event.type = MCT_EVENT_MODULE_EVENT;
event.u.module_event.type = MCT_EVENT_MODULE_STATS_AF_UPDATE;
stats_port_ext_link //port跟port做link的时候会用到 即 调用mct_stream_link_modules(stream, sensor, iface, isp, pproc, imglib,)link这些module的时候;
event.direction = MCT_EVENT_UPSTREAM; //event传送的方向 改变传送方向后,它会向up的所有port传送此event
event.type = MCT_EVENT_MODULE_EVENT; //event的类型
event.u.module_event.type = MCT_EVENT_MODULE_STATS_AF_UPDATE; //event的模块
q3a_port_event
case MCT_EVENT_UPSTREAM: q3a_port_proc_upstream_mod_event(port,event);
mct_port_event_to_peer(); //送到upstream的下一个port,从框图可以看到下一个port是stats——port,所以调用stats_port_event()
AF Region of Internet(Rol) Handing example
从hal传过来,类型为downstream set_param(为ctrl event)
从port过来,所以看stats_port_event()函数看起
stats_port_event
case MCT_EVENT_DOWNSTREAM:
if (event->type == MCT_EVENT_CONTROL_CMD &&event->u.ctrl_event.type == MCT_EVENT_CONTROL_SET_PARM)
stats_port_proc_downstream_set_parm(port, event, &sent);
case CAM_INTF_PARM_AF_ROI:处理完成后,继续送到 q3a_port.c中的event处理
总体downstream处理流程,stats_port_event ----> q3a_port_event ----> af_port_event --->process --->q3a_af_thread_en_q_msg ---->af_port_event-----> q3a_port_event
所有的q_msg都会有一个thread 来hand它
比如:afd_thread_handler,这些thread在asd_port_ext_link(连接两个port)的时候被create "asd_port_start_threads()"
isp相关的event
isp_port.c
port_isp_event_func--->port_isp_module_event
源码相关目录
mm_camera/mm-camera2/media-controller/modules/stats/
/******************************************************************
********** VIDEO QCAMERA SERVER AND MCTL CODE WALK THROUGH ************
************************************************************
*****************************************************************/
MCTL:media controller
open:
main //Server.c (qcom\proprietary\mm-camera\mm-camera2\server-imaging)
open(dev_name, O_RDWR | O_NONBLOCK);
server_process_module_init()
modules_list[i].init_mod
server_process_hal_event(&event);
case MSM_CAMERA_NEW_SESSION
mct_controller_new(modules, data->session_id, pipe_fd[1])
mct_pipeline_start_session(mct->pipeline)
pthread_create(&tid, NULL, mct_controller_thread_run, mct)
do {...}while(1);
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},
}
query_cap:
mct_controller_proc_serv_msg_internal
case SERV_MSG_HAL:
pipeline->process_serv_msg(&msg->u.hal_msg,pipeline);//这里的process_serv_msg被赋值为mct_pipeline_process_serv_msg
mct_pipeline_process_serv_msg:
case MSM_CAMERA_GET_PARM:
mct_pipeline_process_get(data, pipeline);
case MSM_CAMERA_PRIV_QUERY_CAP:
mct_pipeline_populate_query_cap_buffer(pipeline); //fill up HAL's query buffer
close:
server_process_hal_event
case MSM_CAMERA_DEL_SESSION:
mct_controller_destroy(data->session_id)
mct_pipeline_stop_session(mct->pipeline);
mct_pipeline_destroy(mct->pipeline);
set_format:
mct_pipeline_process_serv_msg
case MSM_CAMERA_SET_PARM:
mct_pipeline_process_set(data, pipeline);
case CAM_PRIV_STREAM_INFO_SYNC:
MCT_STREAM_LINK(stream)----->mct_stream_start_link---->mct_stream_link_modules(stream, sensor, iface, isp);------>mct_module_link----->
stream_on:
mct_pipeline_process_set
case MSM_CAMERA_PRIV_STREAM_ON:
mct_pipeline_pack_event(MCT_EVENT_CONTROL_CMD,
pipeline->send_event(pipeline, data->stream_id, &cmd_event);
mct_stream_send_event
src_module->process_event(src_module, event);
typedef boolean (*mct_port_event_func)(mct_port_t *port, mct_event_t *event);
typedef mct_list_t *(*mct_port_int_link_func)(unsigned int identity,
mct_port_t *port);
typedef boolean (*mct_port_ext_link_func)(unsigned int identity,
mct_port_t* port, mct_port_t *peer);
typedef void (*mct_port_unlink_func)(unsigned int identity,
mct_port_t *port, mct_port_t *peer);
typedef boolean (*mct_port_set_caps_func)(mct_port_t *port,
mct_port_caps_t *caps);
typedef boolean (*mct_port_check_caps_reserve_func)
(mct_port_t *port, void *peer_caps, void *stream_info);
typedef boolean (*mct_port_check_caps_unreserve_func)
(mct_port_t *port, unsigned int identity);
module中的函数
struct _mct_module {
mct_object_t object;
mct_list_t *type_list;
mct_list_t *srcports;
unsigned short numsrcports;
mct_list_t *sinkports;
unsigned short numsinkports;
void *module_private;
/* virtual functions - MUST be implemented by each module */
mct_module_process_event_func process_event;
mct_module_set_mod_func set_mod;
mct_module_query_mod_func query_mod;
mct_module_request_port_function request_new_port;
mct_module_start_session start_session;
mct_module_stop_session stop_session;
};
#define mct_module_set_process_event_func(mod,f) \
MCT_MODULE_CAST(mod)->process_event = f
#define mct_module_set_set_mod_func(mod,f) \
MCT_MODULE_CAST(mod)->set_mod = f
#define mct_module_set_query_mod_func(mod,f) \
MCT_MODULE_CAST(mod)->query_mod = f
#define mct_module_set_request_new_port_func(mod,f) \
MCT_MODULE_CAST(mod)->request_new_port = f
#define mct_module_set_start_session_func(mod,f) \
MCT_MODULE_CAST(mod)->start_session = f
#define mct_module_set_stop_session_func(mod,f) \
MCT_MODULE_CAST(mod)->stop_session = f
polling and types messages handled //以下在server.c的main函数中
RD_DS_FD_HAL用来处理mapping buffer的socket messages
RD_FD_HAL 用来处理kernel的node update
RD_PIPE_FD_MCT 用来处理mct的update
buffer manager:
buffer type: matedata 和frame buffers
main //Server.c (qcom\proprietary\mm-camera\mm-camera2\server-imaging)
case RD_DS_FD_HAL:
server_process_hal_ds_packet
mct_controller_proc_serv_msg
case SERV_MSG_DS:
session = serv_msg->u.ds_msg.session;
同时mct_controller_proc_serv_msg_internal会被调用
case SERV_MSG_DS: pipeline->map_buf(&msg->u.ds_msg, pipeline); //这里会调用到mct_pipeline_map_buf()
mct_pipeline_map_buf()
stream->map_buf(msg, stream);//这里会调用 mct_stream_map_buf---->mmap();
message passing
post 一个消息到bus 通过函数mct_module_post_bus_msg
msg_bus_post_msg
case MCT_BUS_MSG_ISP_SOF:
mct_stream_metadata_bus_msg//mct_stream.c中
if (MCT_BUS_MSG_ISP_SOF == bus_msg->type)
ioctl(stream->metadata_stream.buf_mgr_dev_fd,VIDIOC_MSM_BUF_MNGR_BUF_DONE
ioctl(stream->metadata_stream.buf_mgr_dev_fd,VIDIOC_MSM_BUF_MNGR_GET_BUF
debug point:
mct_pipeline_process_set()//traceing stream information or tracking command
mct_pipeline.c mct_pipeline_process_set--->CDBG_HIGH("%s: stream_type = %d\n", __func__, stream->streaminfo.stream_type);
mct_pipeline.c mct_pipeline_process_set--->CDBG_HIGH("%s:command=%x", __func__, data->command); //what message is goingon
/*******************************************************
MCTL POSTPROC CODE WALKTHROUGH
***********************************************************/
vi server/core/config/config_v2.c
/STREAM_ON
搜到函数config_MSM_V4L2_STREAM_ON
config_MSM_V4L2_STREAM_ON
config_v2_pp_topology
config_pp_acquire_mctl_node //preparing mctl pp node config_pp.c
mctl_pp_node_open
mctl_pp_node_prepare //mctl_pp_node.c
mctl_pp_node_alloc_buf
mctl_pp_node_reg_buf
mctl_pp_node_streamon
config_update_stream_info //updating mctl inst
config_pp_setup_pp_topology //set video mode to mctl_pp
cmd.src_cfg.parms.image_mode =
ctrl->curr_output_info.output[SECONDARY].stream_type;
cmd.src_cfg.parms.path =
ctrl->curr_output_info.output[SECONDARY].path;
cmd.src_cfg.parms.format =
ctrl->curr_output_info.output[SECONDARY].format;
cmd.src_cfg.parms.image_width =
ctrl->curr_output_info.output[SECONDARY].image_width +
ctrl->curr_output_info.output[SECONDARY].extra_pad_width;
cmd.src_cfg.parms.image_height =
ctrl->curr_output_info.output[SECONDARY].image_height +
ctrl->curr_output_info.output[SECONDARY].extra_pad_height;
cmd.src_cfg.parms.plane[0] =
ctrl->curr_output_info.output[SECONDARY].plane[0];
cmd.src_cfg.parms.plane[1] =
ctrl->curr_output_info.output[SECONDARY].plane[1];
cmd.cmd_type = QCAM_MCTL_CMD_CONFIG_SRC; //重点
mctl_pp_cmd(&ctrl->mctl_pp_ctrl[pipeline_idx], &cmd);---->mctl_pp_proc_config_src
cmd.cmd_type = QCAM_MCTL_CMD_CONFIG_DEST; //重点
mctl_pp_cmd(&ctrl->mctl_pp_ctrl[pipeline_idx], &cmd);
config_pp_acquire_hw //acquiring hardware,下边会分析
config_pp_send_stream_on //Sending START CMD to VFE
cmd.cmd_type = QCAM_MCTL_CMD_CONFIG_SRC;
mctl_pp_cmd(&ctrl->mctl_pp_ctrl[pipeline_idx], &cmd);
<----->
mctl_pp_proc_config_src //Mctl_pp.c (qcom\proprietary\mm-camera\server\core\mctl)
pp_ctrl->src[src_cfg->src_idx].ops->config_src(poll_cb, src_cfg);
.config_src = mctl_pp_src_config, //mctl_pp_src.c
cmd.cmd_type = QCAM_MCTL_CMD_CONFIG_DEST;
mctl_pp_cmd(&ctrl->mctl_pp_ctrl[pipeline_idx], &cmd);
<----->
mctl_pp_proc_config_dest //Mctl_pp.c (qcom\proprietary\mm-camera\server\core\mctl)
pp_ctrl->src[dest_cfg->src_idx].ops->config_dest(poll_cb, dest_cfg);
.config_dest = mctl_pp_src_config_dest,
dest->ops->config_dest(poll_cb, dest_cfg);
.config_dest = mctl_pp_dest_config, //Mctl_pp_dest.c (qcom\proprietary\mm-camera\server\core\mctl)
acquire_hw调用过程:
config_pp_acquire_hw //Config_pp.c (qcom\proprietary\mm-camera\server\core\config)
mctl_pp_cmd(&ctrl->mctl_pp_ctrl[pipeline_idx], &pp_cmd);//Mctl_pp.c mm-camera\server\core\mctl
pp_ctrl->src[i].ops->acquire_hw((void *)poll_cb, i, j);
mctl_pp_src_acquire_hw
mctl_pp_dest_acquire_hw
mctl_pp_acquire_vpe(poll_cb, dest); //Mctl_pp_vpe_cmd.c (qcom\proprietary\mm-camera\server\core\mctl)
mctl_pp_acquire_c2d(poll_cb, dest); //Mctl_pp_c2d_cmd.c (qcom\proprietary\mm-camera\server\core\mctl)
c2d_interface_create(c2d_mod_ops)
pipe(fds);
c2d_mod_ops->init(c2d_mod_ops->handle, &mctl_ops, fds)
mctl_pp_add_poll_fd(poll_cb, &poll_fd, src->my_idx, dest->my_idx);
streamon调用过程:
mctl_pp_stream_on_off_notify
pp_ctrl->src[i].ops->streamon((void *)poll_cb, i, j);
mctl_pp_src_streamon
mctl_pp_src_enable(poll_cb, 1, src->data.path);
mctl_pp_dest_streamon
case MCTL_PP_C2D_CROP_2D:hw_ops->process(hw_ops->handle, C2D_EVENT_START, &init_data);
---->c2d_event_start
c2d_get_frame_format(init_data->src_format);
c2d_create_default_yuv_surface(ctrl, &ctrl->persist_params.dst.surfaceDef, //
cam_list_init(&(ctrl->g_list.list));
ctrl->state = C2D_STATE_START;
CDBG("%s: ctrl->state = %d", __func__, ctrl->state);
********** qual_camera_stats CODE WALK THROUTH ************
*************************************************
********************************************/
//main函数在qcom\proprietary\mm-camera\mm-camera2\server-imaging\Server.c
int main(int argc, char *argv[])---->server_process_module_init会调用到下边的init数组
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},
};
我们这里关注stats_module_init函数
stats_module_init
mct_module_create("stats");
for{stats_mods_list[i].init_mod} //这里会call到sub module的init函数,如下sub module表
---->q3a_module_init
mct_module_create("q3a");
aec_module_init("aec"); //这三个是q3a的三个sub module
awb_module_init("awb");
af_module_init("af");
stats module 下有好多sub module,如下
static mct_module_init_name_t stats_mods_list[] = {
{ "q3a", q3a_module_init, q3a_module_deinit },
{ "afd", afd_module_init, afd_module_deinit },
{ "asd", asd_module_init, asd_module_deinit },
{ "is", is_module_init, is_module_deinit},
};
camera launch的时候stats_module_start_session会被调用到***** //Stats_module.c (qcom\proprietary\mm-camera\mm-camera2\media-controller\modules\stats)
下边解释stats_module_start_session为什么会被call到
mm_camera_open //Mm_camera.c (hardware\qcom\camera\qcamera2\stack\mm-camera-interface\src)
open(dev_name, O_RDWR | O_NONBLOCK);导致camera_v4l2_open(struct file *filep)被调用 //Camera.c (drivers\media\platform\msm\camera_v2\camera)
camera_v4l2_open
camera_pack_event(filep, MSM_CAMERA_NEW_SESSION, 0, -1, &event); //发送event,会调用到下边的函数
server_process_hal_event 函数中case MSM_CAMERA_NEW_SESSION: mct_controller_new(modules, data->session_id, pipe_fd[1])
mct_controller_new(modules, data->session_id, pipe_fd[1])会调用到mct_pipeline_start_session--->mct_pipeline_modules_start--->mct_pipeline_start_session_thread----
---->module->start_session(为每一个module调用start_session动作,即调用/********stats_module_start_session*******/)
stats_module_start_session的调用过程
/* Now need to create a new sink port */
port = mct_port_create("stats_sink"); //这里只create了一个port ,因为这里stats只有一个入口,
stats_module_sub_mod_start_session
module->start_session //这里的start_session可以是q3a_module.c的start_session----
------>q3a_module_start_session //创建一个port,和三个子module的start_session
mct_port_create("q3a_sink");
private->aec_module->start_session(private->aec_module, sessionid);
private->awb_module->start_session(private->awb_module, sessionid);
private->af_module->start_session(private->af_module, sessionid);
aec_port = aec_module_get_port(private->aec_module, sessionid);
awb_port = awb_module_get_port(private->awb_module, sessionid);
af_port = af_module_get_port(private->af_module, sessionid);
q3a_port_init(port, aec_port, awb_port, af_port, //对这些port做init动作
sub.sub_ports = NULL; //存放后边所有的port
stats_port_init(port, sessionid , sub.sub_ports)
port->direction = MCT_PORT_SINK; //port的方向
caps.port_caps_type = MCT_PORT_CAPS_STATS;
mct_port_set_event_func(port, stats_port_event); //这个function会用来做port跟port之间event的deliever跟receive
mct_port_set_set_caps_func(port, stats_port_set_caps);
mct_port_set_ext_link_func(port, stats_port_ext_link); //port跟port做link的时候会用到
mct_port_set_unlink_func(port, stats_port_unlink);
mct_port_set_check_caps_reserve_func(port, stats_port_check_caps_reserve);
mct_port_set_check_caps_unreserve_func(port, stats_port_check_caps_unreserve);
再看q3a的sub module 的start_session
aec_module_start_session
mct_port_create("aec_sink");
mct_module_add_port(module, port)
//如何get到这些port可以参考如下函数,最终结果是所有的port存在sub.sub_ports中
stats_module_get_sub_ports
message 的handle (upstream跟downstream)
port跟port之间event的都会调用到stats_port_event,上边有说到,在stats_port.c中
stats_port_event //有两个方向的event,MCT_EVENT_UPSTREAM和MCT_EVENT_DOWNSTREAM
case MCT_EVENT_UPSTREAM
case MCT_EVENT_DOWNSTREAM:
这里继续根据event的type和ctrl的type来进行不同的处理
最终会调用到这,把event进一步发送到sub module的port_event(),如q3a_port_event(),会送到所有的port,如果不合适可以不处理
mct_list_traverse((mct_list_t *)private->sub_ports, stats_port_send_event_downstream, &port_event);
q3a_port_event()
case MCT_EVENT_UPSTREAM
case MCT_EVENT_DOWNSTREAM:
q3a_port_send_event_downstream(port, event)
MCT_PORT_EVENT_FUNC(private->aec_port)(private->aec_port, event); //调用到aec的port的event(aec_port_event)
MCT_PORT_EVENT_FUNC(private->awb_port)(private->awb_port, event);
MCT_PORT_EVENT_FUNC(private->af_port)(private->af_port, event);
aec_port_event
case MCT_EVENT_UPSTREAM
case MCT_EVENT_DOWNSTREAM:
aec_port_proc_downstream_event(port, event);
af_port_event
af_port_handle_module_event(port, mod_evt);
q3a_af_thread_en_q_msg(af_port->thread_data, af_msg); 会调用到q3a_thread如下
af_thread_handler //Q3a_thread.c (qcom\proprietary\mm-camera\mm-camera2\media-controller\modules\stats\q3a)
case MSG_BF_STATS:af->af_obj->af_ops.process(msg->u.stats, &(af->af_obj->output),
af->af_cb(& (af->af_obj->output), af->af_port); ----->af_port_callback(每个port都会有自己的callback函数)
af_port_callback
event.direction = MCT_EVENT_UPSTREAM; 改变传送方向后,它会向down的所有port传送此event
event.type = MCT_EVENT_MODULE_EVENT;
event.u.module_event.type = MCT_EVENT_MODULE_STATS_AF_UPDATE;
stats_port_ext_link //port跟port做link的时候会用到 即 调用mct_stream_link_modules(stream, sensor, iface, isp, pproc, imglib,)link这些module的时候;
event.direction = MCT_EVENT_UPSTREAM; //event传送的方向 改变传送方向后,它会向up的所有port传送此event
event.type = MCT_EVENT_MODULE_EVENT; //event的类型
event.u.module_event.type = MCT_EVENT_MODULE_STATS_AF_UPDATE; //event的模块
q3a_port_event
case MCT_EVENT_UPSTREAM: q3a_port_proc_upstream_mod_event(port,event);
mct_port_event_to_peer(); //送到upstream的下一个port,从框图可以看到下一个port是stats——port,所以调用stats_port_event()
AF Region of Internet(Rol) Handing example
从hal传过来,类型为downstream set_param(为ctrl event)
从port过来,所以看stats_port_event()函数看起
stats_port_event
case MCT_EVENT_DOWNSTREAM:
if (event->type == MCT_EVENT_CONTROL_CMD &&event->u.ctrl_event.type == MCT_EVENT_CONTROL_SET_PARM)
stats_port_proc_downstream_set_parm(port, event, &sent);
case CAM_INTF_PARM_AF_ROI:处理完成后,继续送到 q3a_port.c中的event处理
总体downstream处理流程,stats_port_event ----> q3a_port_event ----> af_port_event --->process --->q3a_af_thread_en_q_msg ---->af_port_event-----> q3a_port_event
所有的q_msg都会有一个thread 来hand它
比如:afd_thread_handler,这些thread在asd_port_ext_link(连接两个port)的时候被create "asd_port_start_threads()"
isp相关的event
isp_port.c
port_isp_event_func--->port_isp_module_event
源码相关目录
mm_camera/mm-camera2/media-controller/modules/stats/
/******************************************************************
********** VIDEO QCAMERA SERVER AND MCTL CODE WALK THROUGH ************
************************************************************
*****************************************************************/
MCTL:media controller
open:
main //Server.c (qcom\proprietary\mm-camera\mm-camera2\server-imaging)
open(dev_name, O_RDWR | O_NONBLOCK);
server_process_module_init()
modules_list[i].init_mod
server_process_hal_event(&event);
case MSM_CAMERA_NEW_SESSION
mct_controller_new(modules, data->session_id, pipe_fd[1])
mct_pipeline_start_session(mct->pipeline)
pthread_create(&tid, NULL, mct_controller_thread_run, mct)
do {...}while(1);
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},
}
query_cap:
mct_controller_proc_serv_msg_internal
case SERV_MSG_HAL:
pipeline->process_serv_msg(&msg->u.hal_msg,pipeline);//这里的process_serv_msg被赋值为mct_pipeline_process_serv_msg
mct_pipeline_process_serv_msg:
case MSM_CAMERA_GET_PARM:
mct_pipeline_process_get(data, pipeline);
case MSM_CAMERA_PRIV_QUERY_CAP:
mct_pipeline_populate_query_cap_buffer(pipeline); //fill up HAL's query buffer
close:
server_process_hal_event
case MSM_CAMERA_DEL_SESSION:
mct_controller_destroy(data->session_id)
mct_pipeline_stop_session(mct->pipeline);
mct_pipeline_destroy(mct->pipeline);
set_format:
mct_pipeline_process_serv_msg
case MSM_CAMERA_SET_PARM:
mct_pipeline_process_set(data, pipeline);
case CAM_PRIV_STREAM_INFO_SYNC:
MCT_STREAM_LINK(stream)----->mct_stream_start_link---->mct_stream_link_modules(stream, sensor, iface, isp);------>mct_module_link----->
stream_on:
mct_pipeline_process_set
case MSM_CAMERA_PRIV_STREAM_ON:
mct_pipeline_pack_event(MCT_EVENT_CONTROL_CMD,
pipeline->send_event(pipeline, data->stream_id, &cmd_event);
mct_stream_send_event
src_module->process_event(src_module, event);
typedef boolean (*mct_port_event_func)(mct_port_t *port, mct_event_t *event);
typedef mct_list_t *(*mct_port_int_link_func)(unsigned int identity,
mct_port_t *port);
typedef boolean (*mct_port_ext_link_func)(unsigned int identity,
mct_port_t* port, mct_port_t *peer);
typedef void (*mct_port_unlink_func)(unsigned int identity,
mct_port_t *port, mct_port_t *peer);
typedef boolean (*mct_port_set_caps_func)(mct_port_t *port,
mct_port_caps_t *caps);
typedef boolean (*mct_port_check_caps_reserve_func)
(mct_port_t *port, void *peer_caps, void *stream_info);
typedef boolean (*mct_port_check_caps_unreserve_func)
(mct_port_t *port, unsigned int identity);
module中的函数
struct _mct_module {
mct_object_t object;
mct_list_t *type_list;
mct_list_t *srcports;
unsigned short numsrcports;
mct_list_t *sinkports;
unsigned short numsinkports;
void *module_private;
/* virtual functions - MUST be implemented by each module */
mct_module_process_event_func process_event;
mct_module_set_mod_func set_mod;
mct_module_query_mod_func query_mod;
mct_module_request_port_function request_new_port;
mct_module_start_session start_session;
mct_module_stop_session stop_session;
};
#define mct_module_set_process_event_func(mod,f) \
MCT_MODULE_CAST(mod)->process_event = f
#define mct_module_set_set_mod_func(mod,f) \
MCT_MODULE_CAST(mod)->set_mod = f
#define mct_module_set_query_mod_func(mod,f) \
MCT_MODULE_CAST(mod)->query_mod = f
#define mct_module_set_request_new_port_func(mod,f) \
MCT_MODULE_CAST(mod)->request_new_port = f
#define mct_module_set_start_session_func(mod,f) \
MCT_MODULE_CAST(mod)->start_session = f
#define mct_module_set_stop_session_func(mod,f) \
MCT_MODULE_CAST(mod)->stop_session = f
polling and types messages handled //以下在server.c的main函数中
RD_DS_FD_HAL用来处理mapping buffer的socket messages
RD_FD_HAL 用来处理kernel的node update
RD_PIPE_FD_MCT 用来处理mct的update
buffer manager:
buffer type: matedata 和frame buffers
main //Server.c (qcom\proprietary\mm-camera\mm-camera2\server-imaging)
case RD_DS_FD_HAL:
server_process_hal_ds_packet
mct_controller_proc_serv_msg
case SERV_MSG_DS:
session = serv_msg->u.ds_msg.session;
同时mct_controller_proc_serv_msg_internal会被调用
case SERV_MSG_DS: pipeline->map_buf(&msg->u.ds_msg, pipeline); //这里会调用到mct_pipeline_map_buf()
mct_pipeline_map_buf()
stream->map_buf(msg, stream);//这里会调用 mct_stream_map_buf---->mmap();
message passing
post 一个消息到bus 通过函数mct_module_post_bus_msg
msg_bus_post_msg
case MCT_BUS_MSG_ISP_SOF:
mct_stream_metadata_bus_msg//mct_stream.c中
if (MCT_BUS_MSG_ISP_SOF == bus_msg->type)
ioctl(stream->metadata_stream.buf_mgr_dev_fd,VIDIOC_MSM_BUF_MNGR_BUF_DONE
ioctl(stream->metadata_stream.buf_mgr_dev_fd,VIDIOC_MSM_BUF_MNGR_GET_BUF
debug point:
mct_pipeline_process_set()//traceing stream information or tracking command
mct_pipeline.c mct_pipeline_process_set--->CDBG_HIGH("%s: stream_type = %d\n", __func__, stream->streaminfo.stream_type);
mct_pipeline.c mct_pipeline_process_set--->CDBG_HIGH("%s:command=%x", __func__, data->command); //what message is goingon
/*******************************************************
MCTL POSTPROC CODE WALKTHROUGH
***********************************************************/
vi server/core/config/config_v2.c
/STREAM_ON
搜到函数config_MSM_V4L2_STREAM_ON
config_MSM_V4L2_STREAM_ON
config_v2_pp_topology
config_pp_acquire_mctl_node //preparing mctl pp node config_pp.c
mctl_pp_node_open
mctl_pp_node_prepare //mctl_pp_node.c
mctl_pp_node_alloc_buf
mctl_pp_node_reg_buf
mctl_pp_node_streamon
config_update_stream_info //updating mctl inst
config_pp_setup_pp_topology //set video mode to mctl_pp
cmd.src_cfg.parms.image_mode =
ctrl->curr_output_info.output[SECONDARY].stream_type;
cmd.src_cfg.parms.path =
ctrl->curr_output_info.output[SECONDARY].path;
cmd.src_cfg.parms.format =
ctrl->curr_output_info.output[SECONDARY].format;
cmd.src_cfg.parms.image_width =
ctrl->curr_output_info.output[SECONDARY].image_width +
ctrl->curr_output_info.output[SECONDARY].extra_pad_width;
cmd.src_cfg.parms.image_height =
ctrl->curr_output_info.output[SECONDARY].image_height +
ctrl->curr_output_info.output[SECONDARY].extra_pad_height;
cmd.src_cfg.parms.plane[0] =
ctrl->curr_output_info.output[SECONDARY].plane[0];
cmd.src_cfg.parms.plane[1] =
ctrl->curr_output_info.output[SECONDARY].plane[1];
cmd.cmd_type = QCAM_MCTL_CMD_CONFIG_SRC; //重点
mctl_pp_cmd(&ctrl->mctl_pp_ctrl[pipeline_idx], &cmd);---->mctl_pp_proc_config_src
cmd.cmd_type = QCAM_MCTL_CMD_CONFIG_DEST; //重点
mctl_pp_cmd(&ctrl->mctl_pp_ctrl[pipeline_idx], &cmd);
config_pp_acquire_hw //acquiring hardware,下边会分析
config_pp_send_stream_on //Sending START CMD to VFE
cmd.cmd_type = QCAM_MCTL_CMD_CONFIG_SRC;
mctl_pp_cmd(&ctrl->mctl_pp_ctrl[pipeline_idx], &cmd);
<----->
mctl_pp_proc_config_src //Mctl_pp.c (qcom\proprietary\mm-camera\server\core\mctl)
pp_ctrl->src[src_cfg->src_idx].ops->config_src(poll_cb, src_cfg);
.config_src = mctl_pp_src_config, //mctl_pp_src.c
cmd.cmd_type = QCAM_MCTL_CMD_CONFIG_DEST;
mctl_pp_cmd(&ctrl->mctl_pp_ctrl[pipeline_idx], &cmd);
<----->
mctl_pp_proc_config_dest //Mctl_pp.c (qcom\proprietary\mm-camera\server\core\mctl)
pp_ctrl->src[dest_cfg->src_idx].ops->config_dest(poll_cb, dest_cfg);
.config_dest = mctl_pp_src_config_dest,
dest->ops->config_dest(poll_cb, dest_cfg);
.config_dest = mctl_pp_dest_config, //Mctl_pp_dest.c (qcom\proprietary\mm-camera\server\core\mctl)
acquire_hw调用过程:
config_pp_acquire_hw //Config_pp.c (qcom\proprietary\mm-camera\server\core\config)
mctl_pp_cmd(&ctrl->mctl_pp_ctrl[pipeline_idx], &pp_cmd);//Mctl_pp.c mm-camera\server\core\mctl
pp_ctrl->src[i].ops->acquire_hw((void *)poll_cb, i, j);
mctl_pp_src_acquire_hw
mctl_pp_dest_acquire_hw
mctl_pp_acquire_vpe(poll_cb, dest); //Mctl_pp_vpe_cmd.c (qcom\proprietary\mm-camera\server\core\mctl)
mctl_pp_acquire_c2d(poll_cb, dest); //Mctl_pp_c2d_cmd.c (qcom\proprietary\mm-camera\server\core\mctl)
c2d_interface_create(c2d_mod_ops)
pipe(fds);
c2d_mod_ops->init(c2d_mod_ops->handle, &mctl_ops, fds)
mctl_pp_add_poll_fd(poll_cb, &poll_fd, src->my_idx, dest->my_idx);
streamon调用过程:
mctl_pp_stream_on_off_notify
pp_ctrl->src[i].ops->streamon((void *)poll_cb, i, j);
mctl_pp_src_streamon
mctl_pp_src_enable(poll_cb, 1, src->data.path);
mctl_pp_dest_streamon
case MCTL_PP_C2D_CROP_2D:hw_ops->process(hw_ops->handle, C2D_EVENT_START, &init_data);
---->c2d_event_start
c2d_get_frame_format(init_data->src_format);
c2d_create_default_yuv_surface(ctrl, &ctrl->persist_params.dst.surfaceDef, //
cam_list_init(&(ctrl->g_list.list));
ctrl->state = C2D_STATE_START;
CDBG("%s: ctrl->state = %d", __func__, ctrl->state);
0 0
- qual_camera_video
- Windows学习总结(1)——win10系统最新快捷键汇总
- Android Studio目录结构浅析
- 分享万能java字符串编码转换工具类
- 邮件发送
- Android Please ensure that adb is correctly located at问题解决,重启就好,别的都扯淡
- qual_camera_video
- 自定义Layout
- java入门教程-8.5Java面向字节流的应用
- 【2】深度学习之排头大兵:Caffe
- IOS开发中的几种设计模式介绍
- iOS使用蓝牙的一些注意事项。
- Android eclipse 打开 总是未响应
- java的反射机制
- c++ static的使用方法