[RK1108][Linux3.1]camera系列-摄像头模式(IR&YUV)的切换

平台 内核版本
RK1108 Linux3.1

需求分析

本博客将讲解RK1108平台的摄像头模式的切换:

  • IR(红外模式)
  • YUV(彩色模式)

模式切换的场景:

  • 车辆进入隧道导致对内的驾驶员监控系统摄像头无法有效获取图像。
  • 晚上时间段摄像头无法有效获取图像

IR图像如下图所示:
在这里插入图片描述

摄像头模式切换

通过代码的分析我们将熟悉rk1108camera HAL
首先介绍下rk摄像头的描述结构体
目录external/libcamerahal/CameraHal10_Release/CameraHal/HAL/include/CamHwItf.h

#define RK_SUPPORTED_CAMERA_NUM_MAX 10
struct rk_cams_dev_info {
  int num_camers;
  struct rk_cam_video_input_infos*  cam[RK_SUPPORTED_CAMERA_NUM_MAX];
  struct rk_isp_dev_info isp_dev;
  struct rk_cif_dev_infos cif_devs;
  struct rk_usb_cam_dev_infos usb_devs;
};

因此应用层定义rk_cams_dev_info类型结构体,并获取其信息:

struct rk_cams_dev_info Camera::camera_devive_;
CamHwItf::getCameraInfos(&camera_devive_);

HAL层对应接口分析:
目录external/libcamerahal/CameraHal10_Release/CameraHal/HAL/src/CamHwItf.cpp

shared_ptr<CamHwItf> getCamHwItf(struct rk_isp_dev_info* isp_dev_info) {
  shared_ptr<CamHwItf> instance;
#ifdef RK_ISP10
  instance = shared_ptr<CamHwItf>(new CamIsp10DevHwItf(isp_dev_info));
  mCamIsp10DevHwItf = static_cast<CamIsp10DevHwItf*>(instance.get());
  return instance;
#endif

#ifdef RK_ISP11
  instance = shared_ptr<CamHwItf>(new CamIsp11DevHwItf(isp_dev_info));
  mCamIsp11DevHwItf = static_cast<CamIsp11DevHwItf*>(instance.get());
  return instance;
#endif
}

因此应用层需要进行实例化操作,我们后摄是isp

instance->camera_instance_  = getCamHwItf(&camera_devive_.isp_dev)

可以看出上面返回的是shared_ptr<CamHwItf>智能指针 ,那么我就先看下这个类:
目录external/libcamerahal/CameraHal10_Release/CameraHal/HAL/include/CamHwItf.h

class CamHwItf : virtual public enable_shared_from_this<CamHwItf> {
  ...
  CamHwItf(void);
  virtual ~CamHwItf(void) {};
  //controls
  virtual bool initHw(int inputId) = 0;
  virtual void deInitHw() = 0;
  ...
  //>0 means IRCUT is working
  virtual int getIrCutState();
  virtual int setIrCutState(int state);
  virtual void setNightMode(bool night_mode);
  virtual bool getNightMode();
  virtual void setDayNightSwitch(enum HAL_DAYNIGHT_MODE sw);
  virtual enum HAL_DAYNIGHT_MODE getDayNightSwitch();
  ...
}

应用调用其方法进行摄像头模式的切换


shared_ptr<CamHwItf> camera_instance_;
if(camera_instance_.get() != nullptr){
	camera_instance_->setDayNightSwitch(HAL_DAYNIGHT_NIGHT);
}

HAL 代码分析

目录:/external/libcamerahal/CameraHal10_Release/CameraHal/HAL/source/CamHwItf.cpp

void CamHwItf::setDayNightSwitch(enum HAL_DAYNIGHT_MODE sw) {
  mDayNightSwitch = sw;
}

enum HAL_DAYNIGHT_MODE CamHwItf::getDayNightSwitch() {
  return mDayNightSwitch;
}

目录:/external/libcamerahal/CameraHal10_Release/CameraHal/HAL/source/CamIsp11CtrItf.cpp

bool CamIsp11CtrItf::threadLoop() {
...
//ircut
  //not do this in convertIAResults, that will cause deadlock now
  bool night_mode = mCamHwItf->getNightMode();
  enum HAL_DAYNIGHT_MODE day_night_sw = mCamHwItf->getDayNightSwitch();
  if (night_mode == true) {
    int is_night = CIFISP_LS_INVAL;

    switch (day_night_sw) {
      case HAL_DAYNIGHT_DAY:
        is_night = LIGHT_MODE_DAY;
        break;
      case HAL_DAYNIGHT_NIGHT:
        is_night = LIGHT_MODE_NIGHT;
        break;
      default:
        if (ia_results.aec.Night_Trigger != TRIGGER_OFF){
          if (ia_results.aec.Night_Trigger == LIGHT_SENS)// for Light-senstive Trigger
            is_night = mIspStats[v4l2_buf.index]->subdev_stat.ls.val;
          else if (ia_results.aec.Night_Trigger == NO_LIGHT_SENS)// without Light-senstive Trigger
            is_night = ia_results.aec.DON_LightMode;
        }
        break;
    }

    if (is_night != CIFISP_LS_INVAL){
      if (ia_results.aec.Night_Mode == WHITE_BLACK){// This case requires switch the IR cut filter.
        switchSubDevIrCutMode(!is_night);
      }
      mCamIA_DyCfg.LightMode = is_night ? LIGHT_MODE_NIGHT : LIGHT_MODE_DAY;
    }
  } else {
    switchSubDevIrCutMode(1);
    mCamIA_DyCfg.LightMode = LIGHT_MODE_DAY;
  }
#endif
...

目录:/external/libcamerahal/CameraHal10_Release/CameraHal/HAL/source/CamIsp1xCtrItf.cpp

 mCamHwItf->setIrCutState(1);	

目录:/external/libcamerahal/CameraHal10_Release/CameraHal/HAL/source/CamHwItf.cpp

int CamHwItf::setIrCutState(int state) {
  return mSpDev->setCtrl(V4L2_CID_BAND_STOP_FILTER, state);

}

目录:external/libcamerahal/CameraHal10_Release/CameraHal/HAL/source/V4l2DevIoctr.cpp

int V4L2DevIoctr::setCtrl(unsigned int id, unsigned int value) {
  struct v4l2_control ctrl;
  int ret;

  ctrl.id = id;
  ctrl.value = value;
  ret = ioctl(mDevFp, VIDIOC_S_CTRL, &ctrl);
  if (ret < 0) {
    LOGE("ERR(%s):VIDIOC_S_CTRL(id = %#x (%d), value = %d) failed ret = %d\n",
         __func__, id, id - V4L2_CID_PRIVATE_BASE, value, ret);
  }

  return ret;
}
发布了295 篇原创文章 · 获赞 99 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/qq_33487044/article/details/104557071