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的值實現的

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