Chinaunix首页 | 论坛 | 博客
  • 博客访问: 175808
  • 博文数量: 28
  • 博客积分: 817
  • 博客等级: 军士长
  • 技术积分: 947
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-16 15:32
文章分类
文章存档

2012年(4)

2011年(18)

2010年(6)

我的朋友

分类: LINUX

2010-08-24 20:02:55

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的值实现的
阅读(3077) | 评论(0) | 转发(2) |
0

上一篇:解决camera的两个小问题

下一篇:网站收集

给主人留下些什么吧!~~