承接上文Camera在connect后会调度到Camera3Device->initialize函数 ,如下:
initialize:
status_t res = manager->openSession(mId.string(), this,
/*out*/ &session);
mInterface = new HalInterface(session, queue);
return initializeCommonLocked();
|=======>
| 1. 创建线程StatusTracker指向的"C3Dev-%s-Status"
| 2. 创建线程RequestThread指向的"C3Dev-%s-ReqQueue"
|<==========================
openSession的会话调用到
frameworks\av\services\camera\libcameraservice\common\CameraProviderManager.cpp
status_t CameraProviderManager::openSession(const std::string &id,
const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
/*out*/
sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id,
/*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
Status status;
hardware::Return<void> ret;
ret = deviceInfo3->mInterface->open(callback, [&status, &session]
(Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
status = s;
if (status == Status::OK) {
*session = cameraSession;
}
});
if (!ret.isOk()) {
ALOGE("%s: Transaction error opening a session for camera device %s: %s",
__FUNCTION__, id.c_str(), ret.description().c_str());
return DEAD_OBJECT;
}
return mapToStatusT(status);
}
这里的deviceInfo3指向的mInterface是在开机时CameraService服务创建的时候,通过HIDL的机制获取的Camera HAL的服务。可以查阅Camera 初始化(Open)一(FrameWork -> Hal)
我们这儿直接进入到Hal去
hardware\interfaces\camera\device\3.2\default\cameraDevice.cpp
Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback, open_cb _hidl_cb) {
...
camera3_device_t *device;
ATRACE_BEGIN("camera3->open");
/*
* 1. 调用到HAL3完成CAM_Dispatch和CAM_evntPoll这2个线程的创建
*/
res = mModule->open(mCameraId.c_str(),reinterpret_cast<hw_device_t**>(&device));
...
/*
* 1. 创建CameraDeviceSession
* 2.
*/
session = createSession(
device, info.static_camera_characteristics, callback);
...
//hidl返回
_hidl_cb(status, session->getInterface());
}
这里的Module指向的时CameraMoudle
hardware\interfaces\camera\common\1.0\default\cameraModule.cpp
int CameraModule::open(const char* id, struct hw_device_t** device) {
int res;
ATRACE_BEGIN("camera_module->open");
res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
ATRACE_END();
return res;
}
需要注意的是这个地方的module是在CameraModule构造的时候赋值的
hardware\interfaces\camera\provider\2.4\default\cameraProvider.cpp
bool CameraProvider::initialize() {
camera_module_t *rawModule;
int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(const hw_module_t **)&rawModule);
if (err < 0) {
ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
return true;
}
mModule = new CameraModule(rawModule);
err = mModule->init();
...
err = mModule->setCallbacks(this);+
...
mNumberOfLegacyCameras = mModule->getNumberOfCameras();
for (int i = 0; i < mNumberOfLegacyCameras; i++) {
{
struct camera_info info;
mModule->getCameraInfo(i, &info);
...
addDeviceNames(i);
}
我的当前系统中含有CAMERA_HARDWARE_MODULE_ID的hw的库文件是只有一个camera.sdm660.so
其对应的源文件是:
hardware\qcom\camera\qcamera2\QCamera2Hal.cpp
// Camera dependencies
#include "QCamera2Factory.h"
#include "HAL3/QCamera3VendorTags.h"
static hw_module_t camera_common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = CAMERA_MODULE_API_VERSION_2_4,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = CAMERA_HARDWARE_MODULE_ID,
.name = "QCamera Module",
.author = "Qualcomm Innovation Center Inc",
.methods = &qcamera::QCamera2Factory::mModuleMethods,
.dso = NULL,
.reserved = {0}
};
camera_module_t HAL_MODULE_INFO_SYM = {
.common = camera_common,
.get_number_of_cameras = qcamera::QCamera2Factory::get_number_of_cameras,
.get_camera_info = qcamera::QCamera2Factory::get_camera_info,
.set_callbacks = qcamera::QCamera2Factory::set_callbacks,
.get_vendor_tag_ops = qcamera::QCamera3VendorTags::get_vendor_tag_ops,
.open_legacy = qcamera::QCamera2Factory::open_legacy,
.set_torch_mode = qcamera::QCamera2Factory::set_torch_mode,
.init = NULL,
.reserved = {0}
};
hardware\qcom\camera\qcamera2\QCamera2Factory.cpp
int QCamera2Factory::cameraDeviceOpen(int camera_id,
struct hw_device_t **hw_device)
{
...
QCamera3HardwareInterface *hw = new QCamera3HardwareInterface(mHalDescriptors[camera_id].cameraId,
...
rc = hw->openCamera(hw_device);
}
int QCamera2Factory::camera_device_open(
const struct hw_module_t *module, const char *id,
struct hw_device_t **hw_device)
{
int rc = NO_ERROR;
if (module != &HAL_MODULE_INFO_SYM.common) {
LOGE("Invalid module. Trying to open %p, expect %p",
module, &HAL_MODULE_INFO_SYM.common);
return INVALID_OPERATION;
}
if (!id) {
LOGE("Invalid camera id");
return BAD_VALUE;
}
#ifdef QCAMERA_HAL1_SUPPORT
if(gQCameraMuxer)
rc = gQCameraMuxer->camera_device_open(module, id, hw_device);
else
#endif
rc = gQCamera2Factory->cameraDeviceOpen(atoi(id), hw_device);
return rc;
}
struct hw_module_methods_t QCamera2Factory::mModuleMethods = {
.open = QCamera2Factory::camera_device_open,
};
很明显进入了QCamera3HardwareInterface->openCamera
从这里开始正式的进入了HAL3的流程
Android架构分析之硬件抽象层_转载和创作优秀的博客-CSDN博客
hardware\qcom\camera\qcamera2\stack\mm-camera-interface\src\mm_camera_interface.c
camera_open
cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
cam_obj->vtbl.ops = &mm_camera_ops;
rc = mm_camera_open(cam_obj);
|=======>mm_camera_open (mm_camera.c)
|my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
|snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch");
|mm_camera_cmd_thread_launch(&my_obj->evt_thread,
| mm_camera_dispatch_app_event,
| (void *)my_obj);
|snprintf(my_obj->evt_poll_thread.threadName, THREAD_NAME_SIZE, "CAM_evntPoll");
|mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
MM_CAMERA_POLL_TYPE_EVT);
| //下面这步会将/dev/videoX加入到poll的线程中。
|mm_camera_evt_sub(my_obj, TRUE);
|<==========================
如上Camera在open的时候还会开启线程"CAM_Dispatch"和"CAM_evntPoll"
mm_camera_cmd_thread_launch 这个线程完成命令的分发,具体的命令如下:
typedef enum
{
MM_CAMERA_CMD_TYPE_DATA_CB, /* dataB CMD */
MM_CAMERA_CMD_TYPE_EVT_CB, /* evtCB CMD */
MM_CAMERA_CMD_TYPE_EXIT, /* EXIT */
MM_CAMERA_CMD_TYPE_REQ_DATA_CB,/* request data */
MM_CAMERA_CMD_TYPE_SUPER_BUF_DATA_CB, /* superbuf dataB CMD */
MM_CAMERA_CMD_TYPE_CONFIG_NOTIFY, /* configure notify mode */
MM_CAMERA_CMD_TYPE_START_ZSL, /* start zsl snapshot for channel */
MM_CAMERA_CMD_TYPE_STOP_ZSL, /* stop zsl snapshot for channel */
MM_CAMERA_CMD_TYPE_FLUSH_QUEUE, /* flush queue */
MM_CAMERA_CMD_TYPE_GENERAL, /* general cmd */
MM_CAMERA_CMD_TYPE_MAX
} mm_camera_cmdcb_type_t;
callback函数mm_camera_cmd_thread->mm_camera_dispatch_app_event->my_obj->evt.evt[i].evt_cb(...)
mm_camera_poll_thread_launch线程主要完成EVT事件和DATA事件的Poll监听,例如最重要的"/dev/videoX"事件的到来
typedef enum {
MM_CAMERA_POLL_TYPE_EVT,
MM_CAMERA_POLL_TYPE_DATA,
MM_CAMERA_POLL_TYPE_MAX
} mm_camera_poll_thread_type_t;
在Open的时候创建的是EVT事件。
本篇文章的最后,我们来看下mm_camera_evt_sub订阅事件的过程
mm_camera_evt_sub(my_obj, TRUE)
这里的TRUE意味着订阅事件,FALSE意味着取消订阅. 我们这儿分析事件订阅流程
int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
uint8_t reg_flag)
{
int32_t rc = 0;
struct v4l2_event_subscription sub;
memset(&sub, 0, sizeof(sub));
sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
sub.id = MSM_CAMERA_MSM_NOTIFY;
if(FALSE == reg_flag) {
/* unsubscribe */
...
} else {
rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
if (rc < 0) {
LOGE("subscribe event rc = %d, errno %d",
rc, errno);
return rc;
}
/* add evt fd to polling thread when subscribe the first event */
rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
0, my_obj->my_hdl, my_obj->ctrl_fd, mm_camera_event_notify,
(void*)my_obj, mm_camera_sync_call);
|=======>
|poll_cb->poll_entries[idx].fd = fd; //这里的fd:my_obj->ctrl_fd也就是"/dev/videoX"
|poll_cb->poll_entries[idx].handler = handler;
|poll_cb->poll_entries[idx].notify_cb = notify_cb;//指的是mm_camera_event_notify
|poll_cb->poll_entries[idx].user_data = userdata;
|rc = mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED);
|<==========================
|=======>
| //下面这步唤醒PIPE管道
|ssize_t len = write(poll_cb->pfds[1], &cmd_evt, sizeof(cmd_evt));
| //下面这步唤醒PIPE管道
}
return rc;
}
mm_camera_poll_thread_launch(线程被唤醒)
->mm_camera_poll_thread
->mm_camera_poll_fn
->mm_camera_poll_proc_pipe
如下在poll的事件中加入了"/dev/videoX"后,再次调用poll完成监听
stati` void mm_camera_poll_proc_pipe(mm_camera_poll_thread_t *poll_cb)
{
...
switch (cmd_evt.cmd) {
case MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED:
case MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED_ASYNC:
/* we always have index 0 for pipe read */
poll_cb->num_fds = 0;
poll_cb->poll_fds[poll_cb->num_fds].fd = poll_cb->pfds[0];
poll_cb->poll_fds[poll_cb->num_fds].events = POLLIN|POLLRDNORM|POLLPRI;
poll_cb->num_fds++;
...
}
}
我们之前提到还有一个线程 CAM_dataPoll,这个线程就是CameraPreview数据接收线程,看看是何时被创建的
hardware\interfaces\camera\device\3.2\default\CameraDevice.cpp
sp<CameraDeviceSession> CameraDevice::createSession(camera3_device_t* device,
const camera_metadata_t* deviceInfo,
const sp<ICameraDeviceCallback>& callback) {
return new CameraDeviceSession(device, deviceInfo, callback);
}
CameraDeviceSession::CameraDeviceSession
CameraDeviceSession::initialize()
mDevice->ops->initialize(mDevice, this)
QCamera3HardwareInterface::initialize
mCameraHandle->ops->add_channel
hardware\qcom\camera\qcamera2\hal3\QCamera3HWI.cpp
int QCamera3HardwareInterface::initialize(
const struct camera3_callback_ops *callback_ops)
{
...
//注意这条信道没有回调函数
mChannelHandle = mCameraHandle->ops->add_channel(
mCameraHandle->camera_handle, NULL, NULL, this);
...
}
hardware\qcom\camera\qcamera2\stack\mm-camera-interface\src\mm_camera.c
uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
mm_camera_channel_attr_t *attr,
mm_camera_buf_notify_t channel_cb,
void *userdata)
{
mm_channel_t *ch_obj = NULL;
uint8_t ch_idx = 0;
uint32_t ch_hdl = 0;
//取出 HAL3 中 mm_camera_obj_t 指向的 Channel[],这是个数组,最多可以保存6个信道
for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
ch_obj = &my_obj->ch[ch_idx];
break;
}
}
//初始化这个信道
if (NULL != ch_obj) {
/* initialize channel obj */
memset(ch_obj, 0, sizeof(mm_channel_t));
ch_hdl = mm_camera_util_generate_handler_by_num(my_obj->my_num, ch_idx);
ch_obj->my_hdl = ch_hdl;
ch_obj->state = MM_CHANNEL_STATE_STOPPED;
ch_obj->cam_obj = my_obj;
pthread_mutex_init(&ch_obj->ch_lock, NULL);
ch_obj->sessionid = my_obj->sessionid;
mm_channel_init(ch_obj, attr, channel_cb, userdata);
}
pthread_mutex_unlock(&my_obj->cam_lock);
return ch_hdl;
}
hardware\qcom\camera\qcamera2\stack\mm-camera-interface\src\mm_camera_channel.c
int32_t mm_channel_init(mm_channel_t *my_obj,
mm_camera_channel_attr_t *attr,
mm_camera_buf_notify_t channel_cb,
void *userdata)
{
int32_t rc = 0;
my_obj->bundle.super_buf_notify_cb = channel_cb;
my_obj->bundle.user_data = userdata;
if (NULL != attr) {
my_obj->bundle.superbuf_queue.attr = *attr;
}
my_obj->num_s_cnt = 0;
memset(&my_obj->frame_sync, 0, sizeof(my_obj->frame_sync));
pthread_mutex_init(&my_obj->frame_sync.sync_lock, NULL);
mm_muxer_frame_sync_queue_init(&my_obj->frame_sync.superbuf_queue);
my_obj->bundle.is_cb_active = 1;
LOGD("my_obj->bundle.is_cb_active = %d", my_obj->bundle.is_cb_active);
LOGD("Launch data poll thread in channel open");
snprintf(my_obj->poll_thread[0].threadName, THREAD_NAME_SIZE, "CAM_dataPoll");
mm_camera_poll_thread_launch(&my_obj->poll_thread[0],
MM_CAMERA_POLL_TYPE_DATA);
/* change state to stopped state */
my_obj->state = MM_CHANNEL_STATE_STOPPED;
return rc;
}