文章目录
- processCaptureRequest\_3\_4
- 1.1 mDevice
- 1.2 mDevice->ops->process\_capture\_request
- 1.3 hardware to vendor
- mct\_shimlayer\_process\_event
- 2.1 mct\_shimlayer\_handle\_parm
- 2.2 mct\_shimlayer\_reg\_buffer
processCaptureRequest_3_4
sdm660的摄像头走camera hal 3.4接口,每个预览帧,都是由camera service发起,通过camera HAL的CameraDeviceSession::processCaptureRequest_3_4接口,通知hal,请求一个预览帧。
hardware/interfaces/camera/device/3.4/default/CameraDeviceSession.cpp
Return<void> CameraDeviceSession::processCaptureRequest_3_4(const hidl_vec<V3_4::CaptureRequest>& requests,const hidl_vec<V3_2::BufferCache>& cachesToRemove,ICameraDeviceSession::processCaptureRequest_3_4_cb _hidl_cb) {for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {s = processOneCaptureRequest_3_4(requests[i]);}...
}Status CameraDeviceSession::processOneCaptureRequest_3_4(const V3_4::CaptureRequest& request) {...//@ 1.1 - 1.2status_t ret = mDevice->ops->process_capture_request(mDevice, &halRequest);...
}
1.1 mDevice
mDevice
由camera_device_t
或者camera3_device_t
定义。camera1
和camera3
代表的是CAMERA DEVICE API VERSION
,camera3
和canera1
完全不一样。这里mDevice
是camera3_device_t
定义。
camera3_device_t:是 camera HAL 核心结构体之一,是对 venor camera HAL 实现的抽象,APP 通过 Framework对底层Camera设备(物理设备和逻辑虚拟设备)的操作都是通过对 camera3_device_t 实例对象来进行的。
camera3_device_t:主要用来表示Camera设备,其中定义了Camera3_device_ops操作集合,用来实现正常获取图像数据以及控制Camera的功能。
typedef struct camera3_device {hw_device_t common;camera3_device_ops_t *ops;void *priv;
} camera3_device_t;
HAL3的核心接口都是在camera3_device_ops
中被定义。
camera3_device_ops
结构体定义了一系列的函数指针,用来指向平台厂商实际的实现方法。
typedef struct camera3_device_ops {/*initialize何时被调用:在camera_modul_t中的open方法之后,其他camera3_device_ops方法之前被调用。主要作用:将上层实现的回调方法注册到HAL中,并根据需要在该方法中加入自定义的一些初始化操作。返回时间:在5ms内返回,最长不能超过10ms。*/int (*initialize)(const struct camera3_device *,const camera3_callback_ops_t *callback_ops);/*configure_streams何时被调用:在Initialize方法完成之后,在调用process_capture_request方法之前被调用主要作用:重设当前正在运行的Pipeline以及设执行的输入输出流,其中它回见stream_list中的新的数据流替换之前配置的数据流。返回时间:500ms内返回,最长不能超过1000ms*/int (*configure_streams)(const struct camera3_device *,camera3_stream_configuration_t *stream_list);int (*register_stream_buffers)(const struct camera3_device *,const camera3_stream_buffer_set_t *buffer_set);const camera_metadata_t* (*construct_default_request_settings)(const struct camera3_device *,int type);/*process_capture_request主要作用:下发单次新的capture request到HAL中,上层必须保证该方法的调用都是在一个线程中完成,而且该方法是异步的,其结果是通过HAL调用另一个接口process_capture_result()来返回结果给上层,在使用过程中,通过in-flight机制,保证短时间内下发足够多的requst,从而满足帧率要求。*/int (*process_capture_request)(const struct camera3_device *,camera3_capture_request_t *request);void (*get_metadata_vendor_tag_ops)(const struct camera3_device*,vendor_tag_query_ops_t* ops);void (*dump)(const struct camera3_device *, int fd);int (*flush)(const struct camera3_device *);void (*signal_stream_flush)(const struct camera3_device*,uint32_t num_streams,const camera3_stream_t* const* streams);int (*is_reconfiguration_required)(const struct camera3_device*,const camera_metadata_t* old_session_params,const camera_metadata_t* new_session_params);/* reserved for future use */void *reserved[6];
} camera3_device_ops_t;
1.2 mDevice->ops->process_capture_request
继续mDevice->ops->process_capture_request
在hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.h中camera3_device_ops_t定义了mCameraOps:
static camera3_device_ops_t mCameraOps;
camera3_device_ops_t QCamera3HardwareInterface::mCameraOps = {.initialize = QCamera3HardwareInterface::initialize,.configure_streams = QCamera3HardwareInterface::configure_streams,.register_stream_buffers = NULL,.construct_default_request_settings = QCamera3HardwareInterface::construct_default_request_settings,.process_capture_request = QCamera3HardwareInterface::process_capture_request,.get_metadata_vendor_tag_ops = NULL,.dump = QCamera3HardwareInterface::dump,.flush = QCamera3HardwareInterface::flush,.reserved = {0},
};
hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp
int QCamera3HardwareInterface::process_capture_request(const struct camera3_device *device,camera3_capture_request_t *request)
{LOGE("sundpmy_ process_capture_request E");...QCamera3HardwareInterface *hw =reinterpret_cast<QCamera3HardwareInterface *>(device->priv);int rc = hw->orchestrateRequest(request);LOGE("sundpmy_ process_capture_request X");return rc;
}int32_t QCamera3HardwareInterface::orchestrateRequest(camera3_capture_request_t *request)
{int32_t ret = NO_ERROR;...ret = processCaptureRequest(request, internallyRequestedStreams);...
}
1.3 hardware to vendor
QCamera2Factory构造的时候调用get_num_of_cameras_to_expose,一直到用到mm_camera_load_shim_lib。
QCamera2Factory::QCamera2Factory(){mHalDescriptors = NULL;mCallbacks = NULL;mNumOfCameras = get_num_of_cameras();mNumOfCameras_expose = get_num_of_cameras_to_expose();get_num_of_cameras_to_expose()---> get_num_of_cameras()--->mm_camera_load_shim_lib()
}
mm_camera_load_shim_lib里面dlopen:libmmcamera2_mct_shimlayer.so。dlsym获取入口函数:mct_shimlayer_process_module_init
#define SHIMLAYER_LIB "/system/vendor/lib/libmmcamera2_mct_shimlayer.so"int32_t mm_camera_load_shim_lib()
{const char* error = NULL;void *qdaemon_lib = NULL;LOGD("E");qdaemon_lib = dlopen(SHIMLAYER_LIB, RTLD_NOW);if (!qdaemon_lib) {error = dlerror();LOGE("dlopen failed with error %s", error ? error : "");return -1;}*(void **)&mm_camera_shim_module_init =dlsym(qdaemon_lib, "mct_shimlayer_process_module_init");if (!mm_camera_shim_module_init) {error = dlerror();LOGE("dlsym failed with error code %s", error ? error: "");dlclose(qdaemon_lib);return -1;}return mm_camera_shim_module_init(&g_cam_ctrl.cam_shim_ops);
}
mct_shimlayer_process_module_init给shim_ops_tbl赋值: @vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct_shim_layer/mct_shim_layer.c
int mct_shimlayer_process_module_init(mm_camera_shim_ops_t*shim_ops_tbl)
{...shim_ops_tbl->mm_camera_shim_open_session = mct_shimlayer_start_session;shim_ops_tbl->mm_camera_shim_close_session = mct_shimlayer_stop_session;shim_ops_tbl->mm_camera_shim_send_cmd = mct_shimlayer_process_event;...
}
mm_camera_shim_send_cmd的调用:
int32_t mm_camera_module_send_cmd(cam_shim_packet_t *event)
{int32_t rc = -1;if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_send_cmd) {rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_send_cmd(event);}return rc;
}
mm_camera_module_send_cmd
是个包装函数:
mm_camera_module_send_cmd被调用的地方比较多,打印log看一下:
D mm-camera: <CPP >< HIGH> 1485: cpp_hardware_process_frame: [CPP_BUF:] stream_status:0xe7f1608c, iden:0x40002, cur_frame_id:17
E QCamera : <MCI><ERROR> mm_stream_unmap_buf: 2327: sundp_mc func:mm_stream_unmap_buf line:2327 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =2
E QCamera : <MCI><ERROR> mm_stream_map_buf: 2168: sundp_mc func:mm_stream_map_buf line:2168 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =2
E QCamera : <MCI><ERROR> mm_camera_util_s_ctrl: 2111: sundp_mc func:mm_camera_util_s_ctrl line:2111 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =0
D mm-camera: <CPP >< HIGH> 1485: cpp_hardware_process_frame: [CPP_BUF:] stream_status:0xe7f1608c, iden:0x40002, cur_frame_id:18
E QCamera : <MCI><ERROR> mm_stream_unmap_buf: 2327: sundp_mc func:mm_stream_unmap_buf line:2327 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =2
E QCamera : <MCI><ERROR> mm_stream_map_buf: 2168: sundp_mc func:mm_stream_map_buf line:2168 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =2
E QCamera : <MCI><ERROR> mm_camera_util_s_ctrl: 2111: sundp_mc func:mm_camera_util_s_ctrl line:2111 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =0
D mm-camera: <CPP >< HIGH> 1485: cpp_hardware_process_frame: [CPP_BUF:] stream_status:0xe7f1608c, iden:0x40002, cur_frame_id:19
E QCamera : <MCI><ERROR> mm_stream_unmap_buf: 2327: sundp_mc func:mm_stream_unmap_buf line:2327 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =2
E QCamera : <MCI><ERROR> mm_stream_map_buf: 2168: sundp_mc func:mm_stream_map_buf line:2168 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =2
E QCamera : <MCI><ERROR> mm_camera_util_s_ctrl: 2111: sundp_mc func:mm_camera_util_s_ctrl line:2111 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =0
D mm-camera: <CPP >< HIGH> 1485: cpp_hardware_process_frame: [CPP_BUF:] stream_status:0xe7f1608c, iden:0x40002, cur_frame_id:20
E QCamera : <MCI><ERROR> mm_stream_unmap_buf: 2327: sundp_mc func:mm_stream_unmap_buf line:2327 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =2
E QCamera : <MCI><ERROR> mm_stream_map_buf: 2168: sundp_mc func:mm_stream_map_buf line:2168 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =2
E QCamera : <MCI><ERROR> mm_camera_util_s_ctrl: 2111: sundp_mc func:mm_camera_util_s_ctrl line:2111 here
E mm-camera: <SHIM ><ERROR> 481: mct_shimlayer_process_event: sundp_mct Received event from HAL type =0
D mm-camera: <CPP >< HIGH> 1485: cpp_hardware_process_frame: [CPP_BUF:] stream_status:0xe7f1608c, iden:0x40002, cur_frame_id:21
以上log,可以看出每一帧,每次captureRequest,mm_camera_module_send_cmd会被调用三次。func:mm_stream_map_buf,func:mm_camera_util_s_ctrl,以及每一帧结束后的func:mm_stream_unmap_buf。
mct_shimlayer_process_event
从cameraservice层到qcom的hal层,到了shimlayer。 vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct_shim_layer/mct_shim_layer.c
从日志看,每次captureRequest,mct_shimlayer_process_event会被调用两次,cmd_type分别是CAM_SHIM_REG_BUF和CAM_SHIM_SET_PARM。
packet->cmd_type----->
typedef enum {CAM_SHIM_SET_PARM, /*v4l2 set parameter*/CAM_SHIM_GET_PARM, /*v4l2 get parameter*/CAM_SHIM_REG_BUF, /*Reg/unreg buffers with back-end*/CAM_SHIM_BUNDLE_CMD, /*Bundled command for streams*/
} cam_shim_cmd_type;int mct_shimlayer_process_event(cam_shim_packet_t *packet)
{switch (packet->cmd_type) {case CAM_SHIM_SET_PARM:case CAM_SHIM_GET_PARM: {session_id = packet->session_id;parm_event = &packet->cmd_data;@2.1rc = mct_shimlayer_handle_parm(packet->cmd_type, session_id, parm_event); }break;case CAM_SHIM_REG_BUF: {session_id = packet->session_id;reg_buf = &packet->reg_buf;@2.2rc = mct_shimlayer_reg_buffer(session_id, reg_buf); }break;......
}
接下来看mct_shimlayer_process_event中的2.1 和 2.2。