文章目录
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.2
status_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.1
rc = 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.2
rc = mct_shimlayer_reg_buffer(session_id, reg_buf);
}
break;
......
}
接下来看mct_shimlayer_process_event中的2.1 和 2.2。