平台 | 内核版本 |
---|---|
RK1108 | Linux3.1 |
创建线程
static pthread_t g_isp_camera = -1;
RK_CAM_ATTACHED_TO_e isp_camera = RK_CAM_ATTACHED_TO_ISP;
pthread_create(&g_isp_camera, nullptr, start_camera, &isp_camera);
其中RK_CAM_ATTACHED_TO_e
定义如下:
enum RK_CAM_ATTACHED_TO_e {
RK_CAM_ATTACHED_TO_INVALID,
RK_CAM_ATTACHED_TO_ISP,
RK_CAM_ATTACHED_TO_CIF,
RK_CAM_ATTACHED_TO_USB
};
线程中主要做这些事情:
- 摄像头参数的读取
- open
- pu操作
获取摄像头个数
int camera_num = rv1108_space::Camera::getNumberOfCameras();
定义如下:
int Camera::getNumberOfCameras() {
if(!is_device_get_) {
CamHwItf::getCameraInfos(&camera_devive_);
is_device_get_ = true;
}
return camera_devive_.num_camers;
}
因为线程指定了摄像头类型为RK_CAM_ATTACHED_TO_ISP
,因此我们需要找到相应的ISP
摄像头的索引:
for (int i = 0; i < camera_num; ++i) {
rv1108_space::CameraInfo info;
rv1108_space::Camera::getCameraInfo(i, info);
ARCLOG_PRINT_INFO("start_camera", "idx %d name %s type %d\n", info.index, info.pName, info.type);
if (info.type == camera_type) {
printf("yang ok type = %d\n", info.type);
camera_index = i;
}
}
摄像头初始化操作
shared_ptr<rv1108_space::Camera> camera = rv1108_space::Camera::Open(camera_index);
定义如下:
shared_ptr<Camera> instance(new Camera);
int ret = instance->getParameters(camera_devive_.cam[camera_id]->name,instance->parameters_);
switch (instance->parameters_.type) {
case RK_CAM_ATTACHED_TO_ISP : {
instance->camera_instance_ = getCamHwItf(&camera_devive_.isp_dev);
if(instance->camera_instance_.get() == nullptr) {
ARCLOG_PRINT_ERROR("Camera", "Get ISP Camera Failed!\n ");
return nullptr;
}
break;
}
case RK_CAM_ATTACHED_TO_CIF : {
int cif_num =
((struct rk_cif_dev_info*)(camera_devive_.cam[camera_id]->dev))->cif_index;
instance->camera_instance_ = shared_ptr<CamHwItf>(new CamCifDevHwItf(&(camera_devive_.cif_devs.cif_devs[cif_num])));
if(instance->camera_instance_.get() == nullptr) {
ARCLOG_PRINT_ERROR("Camera", "Get CIF Camera Failed!\n ");
return nullptr;
}
break;
}
default: {
assert(false);
}
}
bool init_ret = instance->camera_instance_->initHw(camera_devive_.cam[camera_id]->index);
ret = instance->camera_instance_->tryFormat(instance->parameters_.format, instance->parameters_.format);
启动
rv1108_space::CameraParameters param = camera->getParameters();
int ret = camera->startPreview();
定义如下:
int Camera::startPreview() {
switch (parameters_.type) {
case RK_CAM_ATTACHED_TO_ISP:
camera_path_ = camera_instance_->getPath(CamHwItf::SP);
break;
case RK_CAM_ATTACHED_TO_CIF:
camera_path_ = camera_instance_->getPath(CamHwItf::MP);
break;
default:
break;
}
if(camera_path_.get() == nullptr) {
ARCLOG_PRINT_ERROR("Camera", "get camera path error!\n");
camera_instance_->deInitHw();
camera_instance_.reset();
return -1;
}
camera_buffer_allocator = make_shared<IonCameraBufferAllocator>();
if(camera_path_->prepare(parameters_.format, kCameraBufferPoolBufferNumber,
*(camera_buffer_allocator.get()), false, 0) == false) {
ARCLOG_PRINT_ERROR("Camera", "camera path prepare error!\n");
camera_path_->stop();
camera_path_->releaseBuffers();
camera_path_.reset();
return -1;
}
if(camera_path_->start() == false) {
ARCLOG_PRINT_ERROR("Camera", "camera path start error!\n");
camera_path_->stop();
camera_path_->releaseBuffers();
camera_path_.reset();
return -1;
}
ARCLOG_PRINT_INFO("Camera", "camera path start ok!\n");
return 0;
}
addBufferNotifier
shared_ptr<DsmProcess> dsm_process = make_shared<DsmProcess>(camera_type);
camera->addProcessUnit(dsm_process, param.format, 0, NULL);
定义:
int Camera::addProcessUnit( shared_ptr<StreamPUBase> next,
frm_info_t &frmFmt, unsigned int num, shared_ptr<CameraBufferAllocator> allocator) {
if (!camera_path_.get() || !next.get()) {
ARCLOG_PRINT_ERROR("Camera", "%s: PU is NULL\n", __func__);
return -1;
}
camera_path_->addBufferNotifier(next.get());
next->prepare(frmFmt, num, allocator);
if (!next->start()) {
ARCLOG_PRINT_ERROR("Camera", "PU start failed!\n");
return -1;
}
return 0;
}