camera学习(一)--参数设置

zhuanzi: http://blogold.chinaunix.net/u3/116954/showart_2309015.html

 

fsl的camera hal层没有实现上层到下层的设置参数的接口,所以需要自己实现。好在从应用到hal层的参数已经弄好,否则工作量就更大了。
参数设置在hal层调用的函数是status_t CameraHal::setParameters(const CameraParameters& params)。在这个函数里实现对每个参数的设置。参数设置主要通过 CameraParameters这个类实现的。通过观察这个类发现,里面有个get()函数,可以分别得到各个参数。如
      const char *white_balance = params.get(CameraParameters::KEY_WHITE_BALANCE);这个可以得到目前白平衡的参数即返回值。然后根据返回值判断是哪种情况,如
    if (strcmp(white_balance,  CameraParameters::WHITE_BALANCE_AUTO) == 0) {   //判断为自动白平衡
        LOGV("white_balance to ioctl is auto !/n");
        ctl.id = V4L2_CID_AUTO_WHITE_BALANCE;    //自动白平衡命令,ctl为v4l2_control结构,该结构很有用
        ctl.value = 1;
        if (ioctl(camera_device, VIDIOC_S_CTRL, &ctl) < 0){   //通过 VIDIOC_S_CTRL把ctl结构体传下去
            LOGE("set control failed/n");
                //return -1;
        }
    }else if(strcmp(white_balance,  CameraParameters::WHITE_BALANCE_INCANDESCENT) == 0){  //白炽灯模式
        LOGV("white_balance to ioctl is incandescent !/n");
        ctl.id = V4L2_CID_DO_WHITE_BALANCE;   //其它白平衡情况都用该命令
        ctl.value = 2;  //根据用户自己定义的白平衡模式数目排列
        if (ioctl(camera_device, VIDIOC_S_CTRL, &ctl) < 0){  //同样通过 VIDIOC_S_CTRL把ctl结构体传下去,然后在根据value值分情况讨论
            LOGE("set control failed/n");
                //return -1;
        }
    }

传到驱动的mxc_v4l2_capture.c文件的mxc_v4l_ioctl中,mxc_v4l_ioctl调用mxc_v4l_do_ioctl,mxc_v4l_do_ioctl对命令的解释如下
    /*!
     * V4l2 VIDIOC_S_CTRL ioctl
     */
    case VIDIOC_S_CTRL: {
        pr_debug("   case VIDIOC_S_CTRL/n");
        retval = mxc_v4l2_s_ctrl(cam, arg);
        break;
    }
这样就到了mxc_v4l2_s_ctrl。在mxc_v4l2_s_ctrl通过对ctl.id分情况调用
switch (c->id) {
    ......
    case V4L2_CID_AUTO_WHITE_BALANCE:
        ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
        ret = vidioc_int_s_ctrl(cam->sensor, c);  //该函数是v4l2对应ov7670驱动中的s_ctl
        ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
        break;
    case V4L2_CID_DO_WHITE_BALANCE:
        ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
        ret = vidioc_int_s_ctrl(cam->sensor, c);
        ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
        break;
     ......
其中vidioc_int_s_ctrl()是v4l2对应ov7670驱动中的 ioctl_s_ctrl,具体代码怎么对应由于篇幅原因就不贴出来。
根据ctl结构体的id分情况去实现即可。
    switch (vc->id) {
    .....
    case V4L2_CID_AUTO_WHITE_BALANCE:
        retval = ov7670_autowhitebalance(vc->value);
        break;
    case V4L2_CID_DO_WHITE_BALANCE:
        retval = ov7670_dowhitebalance(vc->value);
        break;
    ......
下面是whitebalance函数的实现
static int ov7670_autowhitebalance(int value)
{
    unsigned char v = 0;
    int ret;
    printk("0v7670_autowhitebalance called/n");
    ret = ov7670_read(ov7670_data.i2c_client, REG_COM8, &v);
    if (value)
        v |= COM8_AWB;  //自动白平衡

    msleep(10);  /* FIXME */
    ret += ov7670_write(ov7670_data.i2c_client, 0x01, 0x56);
    ret += ov7670_write(ov7670_data.i2c_client, 0x02, 0x44);
    ret += ov7670_write(ov7670_data.i2c_client, REG_COM8, v);

    return ret;   
}

static int ov7670_dowhitebalance(int value)
{
    unsigned char v = 0;
    int ret;
    printk("0v7670_dowhitebalance called value:%d/n",value);
    ret = ov7670_read(ov7670_data.i2c_client, REG_COM8, &v);
    if (value)
        v &= ~COM8_AWB;  //关闭自动白平衡

    msleep(10);  /* FIXME */
    ret += ov7670_write(ov7670_data.i2c_client, REG_COM8, v);
    if(value == 2) //INCANDESCENCE  //这个值就是ctl的value值
    {
        ret += ov7670_write(ov7670_data.i2c_client, 0x01, 0x8c);
        ret += ov7670_write(ov7670_data.i2c_client, 0x02, 0x59);
    }else if(value == 3)  //FLUORESCENT
    {
        ret += ov7670_write(ov7670_data.i2c_client, 0x01, 0x7e);
        ret += ov7670_write(ov7670_data.i2c_client, 0x02, 0x49);        
    }else if(value == 4)  //DAYLIGHT
    {
        ret += ov7670_write(ov7670_data.i2c_client, 0x01, 0x52);
        ret += ov7670_write(ov7670_data.i2c_client, 0x02, 0x66);
    }

    return ret;   
}
其中函数中ox01、0x02分别是蓝红通道的增益的寄存器。

上面是白平衡从hal层最终到sensor的参数设置过程。其它如色彩效果、取景模式等都是同样的过程。
取景模式根据具体的情况如夜间模式等设定具体的寄存器即可
色彩效果主要通过设置uv的值实现的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章