1、Camera成像原理介绍
Camera工作流程图
Camera的成像原理可以简单概括如下:
景物(SCENE)通过镜头(LENS)生成的光学图像投射到图像传感器(Sensor)表面上,然后转为电信号,经过A/D(模数转换)转换后变为数字图像信号,再送到数字信号处理芯片(DSP)中加工处理,再通过IO接口传输到CPU中处理,通过DISPLAY就可以看到图像了。
电荷耦合器件(CCD)或
互补金属氧化物半导体(CMOS)接收光学镜头传递来的影像,经模/数转换器(A/D)转换成数字信号,经过编码后存储。
流程如下:
1)、CCD/CMOS将被摄体的光信号转变为电信号—电子图像(模拟信号)
2)、由模/数转换器(ADC)芯片来将模拟信号转化为数字信号
3)、数字信号形成后,由DSP或编码库对信号进行压缩并转化为特定的图像文件格式储存
数码相机的光学镜头与传统相机相同,将影像聚到感光器件上,即(光)电荷耦合器件(CCD) 。CCD替代了传统相机中的感光胶片的位置,其功能是将光信号转换成电信号,与电视摄像相同。
CCD是半导体器件,是数码相机的核心,其内含器件的单元数量决定了数码相机的成像质量——像素,单元越多,即像素数高,成像质量越好,通常情况下像素的高低代表了数码相机的档次和技术指标。
2、Android Camera框架
Android的Camera子系统提供一个拍照和录制视频的框架。
它将Camera的上层应用与Application Framework、用户库串接起来,而正是这个用户库来与Camera的硬件层通信,从而实现操作camera硬件。
--------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
3.Camera HAL层部分
代码存放目录:hardware
k29camera
编译:
[cpp]
view plaincopy
- LOCAL_PATH:= $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:=
- CameraHal_Module.cpp
- CameraHal.cpp
- CameraHal_Utils.cpp
- MessageQueue.cpp
- CameraHal_Mem.cpp
- ...................
- ifeq ($(strip $(TARGET_BOARD_HARDWARE)),rk30board)
- LOCAL_MODULE:= camera.rk30board
为了实现一个具体功能的Camera,在HAL层需要一个硬件相关的Camera库(例如通过调用video for linux驱动程序和Jpeg编码程序实现或者直接用各个chip厂商实现的私有库来实现,比如Qualcomm实现的libcamera.so和libqcamera.so),此处为camera.rk30board.so实现CameraHardwareInterface规定的接口,来调用相关的库,驱动相关的driver,实现对camera硬件的操作。这个库将被Camera的服务库libcameraservice.so调用。
3.1CameraHal_Module.cpp主要是Camera HAL对上层提供的接口,和实际设备无关,上层的本地库都直接调用这个文件里面提供的接口。
[cpp]
view plaincopy
- static int camera_device_open(const hw_module_t* module, const char* name,
- hw_device_t** device);
- static int camera_device_close(hw_device_t* device);
- static int camera_get_number_of_cameras(void);
- static int camera_get_camera_info(int camera_id, struct camera_info *info);
-
-
- static struct hw_module_methods_t camera_module_methods = {
- open: camera_device_open
- };
-
-
- camera_module_t HAL_MODULE_INFO_SYM = {
- common: {
- tag: HARDWARE_MODULE_TAG,
- version_major: ((CONFIG_CAMERAHAL_VERSION&0xff00)>>8),
- version_minor: CONFIG_CAMERAHAL_VERSION&0xff,
- id: CAMERA_HARDWARE_MODULE_ID,
- name: CAMERA_MODULE_NAME,
- author: "RockChip",
- methods: &camera_module_methods,
- dso: NULL,
- reserved: {0},
- },
- get_number_of_cameras: camera_get_number_of_cameras,
- get_camera_info: camera_get_camera_info,
- };
//CAMERA_DEVICE_NAME "/dev/video" 以下都是通过读取节点信息来获取摄像头的数目及摄像头设备信息
[cpp]
view plaincopy
- int camera_device_close(hw_device_t* device)
- {
- int ret = 0;
- rk_camera_device_t* rk_dev = NULL;
-
- LOGD("%s", __FUNCTION__);
-
- android::Mutex::Autolock lock(gCameraHalDeviceLock);
-
- if (!device) {
- ret = -EINVAL;
- goto done;
- }
-
- rk_dev = (rk_camera_device_t*) device;
-
- if (rk_dev) {
- if (gCameraHals[rk_dev->cameraid]) {
- delete gCameraHals[rk_dev->cameraid];
- gCameraHals[rk_dev->cameraid] = NULL;
- gCamerasOpen--;
- }
-
- if (rk_dev->base.ops) {
- free(rk_dev->base.ops);
- }
- free(rk_dev);
- }
- done:
-
- return ret;
- }
-
-
-
-
-
-
-
-
-
-
-
- int camera_device_open(const hw_module_t* module, const char* name,
- hw_device_t** device)
- {
- int rv = 0;
- int cameraid;
- rk_camera_device_t* camera_device = NULL;
- camera_device_ops_t* camera_ops = NULL;
- android::CameraHal* camera = NULL;
-
- android::Mutex::Autolock lock(gCameraHalDeviceLock);
-
- LOGI("camera_device open");
-
- if (name != NULL) {
- cameraid = atoi(name);
-
- if(cameraid > gCamerasNumber) {
- LOGE("camera service provided cameraid out of bounds, "
- "cameraid = %d, num supported = %d",
- cameraid, gCamerasNumber);
- rv = -EINVAL;
- goto fail;
- }
-
- if(gCamerasOpen >= CAMERAS_SUPPORTED_SIMUL_MAX) {
- LOGE("maximum number(%d) of cameras already open",gCamerasOpen);
- rv = -ENOMEM;
- goto fail;
- }
-
- camera_device = (rk_camera_device_t*)malloc(sizeof(*camera_device));
- if(!camera_device) {
- LOGE("camera_device allocation fail");
- rv = -ENOMEM;
- goto fail;
- }
-
- camera_ops = (camera_device_ops_t*)malloc(sizeof(*camera_ops));
- if(!camera_ops) {
- LOGE("camera_ops allocation fail");
- rv = -ENOMEM;
- goto fail;
- }
-
- memset(camera_device, 0, sizeof(*camera_device));
- memset(camera_ops, 0, sizeof(*camera_ops));
-
- camera_device->base.common.tag = HARDWARE_DEVICE_TAG;
- camera_device->base.common.version = 0;
- camera_device->base.common.module = (hw_module_t *)(module);
- camera_device->base.common.close = camera_device_close;
- camera_device->base.ops = camera_ops;
-
- camera_ops->set_preview_window = camera_set_preview_window;
- camera_ops->set_callbacks = camera_set_callbacks;
- camera_ops->enable_msg_type = camera_enable_msg_type;
- camera_ops->disable_msg_type = camera_disable_msg_type;
- camera_ops->msg_type_enabled = camera_msg_type_enabled;
- camera_ops->start_preview = camera_start_preview;
- camera_ops->stop_preview = camera_stop_preview;
- camera_ops->preview_enabled = camera_preview_enabled;
- camera_ops->store_meta_data_in_buffers = camera_store_meta_data_in_buffers;
- camera_ops->start_recording = camera_start_recording;
- camera_ops->stop_recording = camera_stop_recording;
- camera_ops->recording_enabled = camera_recording_enabled;
- camera_ops->release_recording_frame = camera_release_recording_frame;
- camera_ops->auto_focus = camera_auto_focus;
- camera_ops->cancel_auto_focus = camera_cancel_auto_focus;
- camera_ops->take_picture = camera_take_picture;
- camera_ops->cancel_picture = camera_cancel_picture;
- camera_ops->set_parameters = camera_set_parameters;
- camera_ops->get_parameters = camera_get_parameters;
- camera_ops->put_parameters = camera_put_parameters;
- camera_ops->send_command = camera_send_command;
- camera_ops->release = camera_release;
- camera_ops->dump = camera_dump;
-
- *device = &camera_device->base.common;
-
-
-
- camera_device->cameraid = cameraid;
-
- camera = new android::CameraHal(cameraid);
-
- if(!camera) {
- LOGE("Couldn't create instance of CameraHal class");
- rv = -ENOMEM;
- goto fail;
- }
-
- gCameraHals[cameraid] = camera;
- gCamerasOpen++;
- }
-
- return rv;
-
- fail:
- if(camera_device) {
- free(camera_device);
- camera_device = NULL;
- }
- if(camera_ops) {
- free(camera_ops);
- camera_ops = NULL;
- }
- if(camera) {
- delete camera;
- camera = NULL;
- }
- *device = NULL;
- return rv;
- }
-
- int camera_get_number_of_cameras(void)
- {
- char cam_path[20];
- char cam_num[3],i;
- int cam_cnt=0,fd=-1,rk29_cam[CAMERAS_SUPPORT_MAX];
- struct v4l2_capability capability;
- rk_cam_info_t camInfoTmp[CAMERAS_SUPPORT_MAX];
- char *ptr,**ptrr;
- char version[PROPERTY_VALUE_MAX];
-
- if (gCamerasNumber > 0)
- goto camera_get_number_of_cameras_end;
-
- memset(version,0x00,sizeof(version));
- sprintf(version,"%d.%d.%d",((CONFIG_CAMERAHAL_VERSION&0xff0000)>>16),
- ((CONFIG_CAMERAHAL_VERSION&0xff00)>>8),CONFIG_CAMERAHAL_VERSION&0xff);
- property_set(CAMERAHAL_VERSION_PROPERTY_KEY,version);
-
- memset(&camInfoTmp[0],0x00,sizeof(rk_cam_info_t));
- memset(&camInfoTmp[1],0x00,sizeof(rk_cam_info_t));
-
- for (i=0; i<10; i++) {
- cam_path[0] = 0x00;
- strcat(cam_path, CAMERA_DEVICE_NAME);
- sprintf(cam_num, "%d", i);
- strcat(cam_path,cam_num);
- fd = open(cam_path, O_RDONLY);
- if (fd < 0)
- break;
-
- memset(&capability, 0, sizeof(struct v4l2_capability));
- if (ioctl(fd, VIDIOC_QUERYCAP, &capability) < 0) {
- LOGE("Video device(%s): query capability not supported.
",cam_path);
- goto loop_continue;
- }
-
- if ((capability.capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING)) != (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING)) {
- LOGD("Video device(%s): video capture not supported.
",cam_path);
- } else {
- memset(camInfoTmp[cam_cnt&0x01].device_path,0x00, sizeof(camInfoTmp[cam_cnt&0x01].device_path));
- strcat(camInfoTmp[cam_cnt&0x01].device_path,cam_path);
- memset(camInfoTmp[cam_cnt&0x01].fival_list,0x00, sizeof(camInfoTmp[cam_cnt&0x01].fival_list));
- memcpy(camInfoTmp[cam_cnt&0x01].driver,capability.driver, sizeof(camInfoTmp[cam_cnt&0x01].driver));
- camInfoTmp[cam_cnt&0x01].version = capability.version;
- if (strstr((char*)&capability.card[0], "front") != NULL) {
- camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_FRONT;
- } else {
- camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_BACK;
- }
- ptr = strstr((char*)&capability.card[0],"-");
- if (ptr != NULL) {
- ptr++;
- camInfoTmp[cam_cnt&0x01].facing_info.orientation = atoi(ptr);
- } else {
- camInfoTmp[cam_cnt&0x01].facing_info.orientation = 0;
- }
- cam_cnt++;
-
- memset(version,0x00,sizeof(version));
- sprintf(version,"%d.%d.%d",((capability.version&0xff0000)>>16),
- ((capability.version&0xff00)>>8),capability.version&0xff);
- property_set(CAMERADRIVER_VERSION_PROPERTY_KEY,version);
-
- LOGD("%s(%d): %s:%s",__FUNCTION__,__LINE__,CAMERADRIVER_VERSION_PROPERTY_KEY,version);
-
- if (cam_cnt >= CAMERAS_SUPPORT_MAX)
- i = 10;
- }
- loop_continue:
- if (fd > 0) {
- close(fd);
- fd = -1;
- }
- continue;
- }
-
- if((strcmp(camInfoTmp[0].driver,"uvcvideo") == 0)) {
- camInfoTmp[0].facing_info.facing = (camInfoTmp[1].facing_info.facing == CAMERA_FACING_FRONT) ? CAMERA_FACING_BACK:CAMERA_FACING_FRONT;
- camInfoTmp[0].facing_info.orientation = (camInfoTmp[0].facing_info.facing == CAMERA_FACING_FRONT)?270:90;
- } else if((strcmp(camInfoTmp[1].driver,"uvcvideo") == 0)) {
- camInfoTmp[1].facing_info.facing = (camInfoTmp[0].facing_info.facing == CAMERA_FACING_FRONT) ? CAMERA_FACING_BACK:CAMERA_FACING_FRONT;
- camInfoTmp[1].facing_info.orientation = (camInfoTmp[1].facing_info.facing == CAMERA_FACING_FRONT)?270:90;
- }
- gCamerasNumber = cam_cnt;
-
- #if CONFIG_AUTO_DETECT_FRAMERATE
- rk29_cam[0] = 0xff;
- rk29_cam[1] = 0xff;
- for (i=0; i
- if (strcmp((char*)&camInfoTmp[i].driver[0],"rk29xx-camera") == 0) {
- if (strcmp((char*)&camInfoTmp[i].driver[0],(char*)&gCamInfos[i].driver[0]) != 0) {
- rk29_cam[i] = i;
- }
- } else {
- rk29_cam[i] = 0xff;
- }
- }
-
- if ((rk29_cam[0] != 0xff) || (rk29_cam[1] != 0xff)) {
- if (gCameraFpsDetectThread == NULL) {
- gCameraFpsDetectThread = new CameraFpsDetectThread();
- LOGD("%s create CameraFpsDetectThread for enum camera framerate!!",__FUNCTION__);
- gCameraFpsDetectThread->run("CameraFpsDetectThread", ANDROID_PRIORITY_AUDIO);
- }
- }
- #endif
- #if CONFIG_CAMERA_SINGLE_SENSOR_FORCE_BACK_FOR_CTS
- if ((gCamerasNumber==1) && (camInfoTmp[0].facing_info.facing==CAMERA_FACING_FRONT)) {
- gCamerasNumber = 2;
- memcpy(&camInfoTmp[1],&camInfoTmp[0], sizeof(rk_cam_info_t));
- camInfoTmp[1].facing_info.facing = CAMERA_FACING_BACK;
- }
- #endif
-
- memcpy(&gCamInfos[0], &camInfoTmp[0], sizeof(rk_cam_info_t));
- memcpy(&gCamInfos[1], &camInfoTmp[1], sizeof(rk_cam_info_t));
-
- camera_get_number_of_cameras_end:
- LOGD("%s(%d): Current board have %d cameras attached.",__FUNCTION__, __LINE__, gCamerasNumber);
- return gCamerasNumber;
- }
-
- int camera_get_camera_info(int camera_id, struct camera_info *info)
- {
- int rv = 0,fp;
- int face_value = CAMERA_FACING_BACK;
- int orientation = 0;
- char process_name[30];
-
- if(camera_id > gCamerasNumber) {
- LOGE("%s camera_id out of bounds, camera_id = %d, num supported = %d",__FUNCTION__,
- camera_id, gCamerasNumber);
- rv = -EINVAL;
- goto end;
- }
-
- info->facing = gCamInfos[camera_id].facing_info.facing;
- info->orientation = gCamInfos[camera_id].facing_info.orientation;
- end:
- LOGD("%s(%d): camera_%d facing(%d), orientation(%d)",__FUNCTION__,__LINE__,camera_id,info->facing,info->orientation);
- return rv;
- }
而对于为上层提供的HAL层接口函数,并不直接操作节点,而是间接的去调用CameraHal.cpp去操作节点。
[cpp]
view plaincopy
- int camera_start_preview(struct camera_device * device)
- {
- int rv = -EINVAL;
- rk_camera_device_t* rk_dev = NULL;
-
- LOGV("%s", __FUNCTION__);
-
- if(!device)
- return rv;
-
- rk_dev = (rk_camera_device_t*) device;
-
- rv = gCameraHals[rk_dev->cameraid]->startPreview();
-
- return rv;
- }
-
- void camera_stop_preview(struct camera_device * device)
- {
- rk_camera_device_t* rk_dev = NULL;
-
- LOGV("%s", __FUNCTION__);
-
- if(!device)
- return;
-
- rk_dev = (rk_camera_device_t*) device;
-
- gCameraHals[rk_dev->cameraid]->stopPreview();
- }
3.2CameraHal.cpp去操作节点来进行实际的操作。
//这个几个线程很关键,分别对应着各种不同的情况,但是一直在运行
[cpp]
view plaincopy
- CameraHal::CameraHal(int cameraId)
- :mParameters(),
- mSnapshotRunning(-1),
- mCommandRunning(-1),
- mPreviewRunning(STA_PREVIEW_PAUSE),
- mPreviewLock(),
- mPreviewCond(),
- mDisplayRuning(STA_DISPLAY_PAUSE),
- mDisplayLock(),
- mDisplayCond(),
- mANativeWindowLock(),
- mANativeWindowCond(),
- mANativeWindow(NULL),
- mPreviewErrorFrameCount(0),
- mPreviewFrameSize(0),
- mCamDriverFrmHeightMax(0),
- mCamDriverFrmWidthMax(0),
- mPreviewBufferCount(0),
- mCamDriverPreviewFmt(0),
- mCamDriverPictureFmt(0),
- mCamDriverV4l2BufferLen(0),
- mPreviewMemory(NULL),
- mRawBufferSize(0),
- mJpegBufferSize(0),
- mMsgEnabled(0),
- mEffect_number(0),
- mScene_number(0),
- mWhiteBalance_number(0),
- mFlashMode_number(0),
- mGps_latitude(-1),
- mGps_longitude(-1),
- mGps_altitude(-1),
- mGps_timestamp(-1),
- displayThreadCommandQ("displayCmdQ"),
- displayThreadAckQ("displayAckQ"),
- previewThreadCommandQ("previewCmdQ"),
- previewThreadAckQ("previewAckQ"),
- commandThreadCommandQ("commandCmdQ"),
- commandThreadAckQ("commandAckQ"),
- snapshotThreadCommandQ("snapshotCmdQ"),
- snapshotThreadAckQ("snapshotAckQ"),
- mCamBuffer(NULL)
- {
- int fp,i;
-
- cameraCallProcess[0] = 0x00;
- sprintf(cameraCallProcess,"/proc/%d/cmdline",getCallingPid());
- fp = open(cameraCallProcess, O_RDONLY);
- if (fp < 0) {
- memset(cameraCallProcess,0x00,sizeof(cameraCallProcess));
- LOGE("Obtain calling process info failed");
- } else {
- memset(cameraCallProcess,0x00,sizeof(cameraCallProcess));
- read(fp, cameraCallProcess, 30);
- close(fp);
- fp = -1;
- LOGD("Calling process is: %s",cameraCallProcess);
- }
-
- iCamFd = -1;
- memset(&mCamDriverSupportFmt[0],0, sizeof(mCamDriverSupportFmt));
- mRecordRunning = false;
- mPictureRunning = STA_PICTURE_STOP;
- mExitAutoFocusThread = false;
- mDriverMirrorSupport = false;
- mDriverFlipSupport = false;
- mPreviewCmdReceived = false;
- mPreviewStartTimes = 0x00;
- memset(mCamDriverV4l2Buffer, 0x00, sizeof(mCamDriverV4l2Buffer));
- memset(mDisplayFormat,0x00,sizeof(mDisplayFormat));
- for (i=0; i
- mPreviewBufferMap[i] = NULL;
- mDisplayBufferMap[i] = NULL;
- memset(&mGrallocBufferMap[i],0x00,sizeof(rk_previewbuf_info_t));
- mPreviewBufs[i] = NULL;
- mVideoBufs[i] = NULL;
-
- mPreviewBuffer[i] = NULL;
- }
-
-
- mRGAFd = -1;
-
- if (cameraCreate(cameraId) == 0) {
- initDefaultParameters();
-
- cameraRawJpegBufferCreate(mRawBufferSize,mJpegBufferSize);
-
- &