太极者 2015-10-28 07:58 采纳率: 0%
浏览 2177

关于Linux下V4L2获取设置参数

问题描述如下:
我在linux下使用V4L2对免驱摄像头进行操作,由于项目需求,需要通过USB线获取
摄像头板的GPI的状态,这个属于扩展功能,摄像头工程师是这么做的:由于我们的摄像头的GAMMA值不会被用到,因此当摄像头板检测到GPI电平有变化时,它就将
GAMMA对应的寄存器的值设置成另外一个值,然后我通过V4L2的函数ioctl,参数为VIDIOC_G_GAMMA来获取当前的GAMMA值,但是读不到其变化。问题是,我在windows下又可以读到
GAMMA值的变化,似乎是linux下的底层驱动没有刷新(个人感觉,但又找不到刷新的相关函数),
求大神指导

  • 写回答

1条回答 默认 最新

  • 幸福快乐fyf 2023-07-01 17:37
    关注

    针对这个问题,建议尝试使用 V4L2 的事件通知机制来获取 GPI 的状态变化。可以通过以下步骤实现:

    1、使用 ioctl 函数打开事件通知功能:

    int enable_event(int fd, uint32_t type, uint32_t id)
    {
        struct v4l2_event_subscription sub;
        memset(&sub, 0, sizeof(sub));
        sub.type = type;
        sub.id = id;
        return ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
    }
    

    其中,fd 是摄像头设备文件描述符,type 是要订阅的事件类型,可以是 V4L2_EVENT_ALL 或者其他具体类型,id 是要订阅的事件 ID,可以是 V4L2_EVENT_CTRL 等。

    2、在主循环中等待事件通知,如果收到 V4L2_EVENT_CTRL 类型的事件,说明 GPI 状态发生了变化,此时可以调用 ioctl 函数获取 GAMMA 值:

    void main_loop(int fd)
    {
        /* 订阅事件 */
        if (enable_event(fd, V4L2_EVENT_CTRL, 0x009a0901) == -1) {
            printf("Error: Cannot enable event\n");
            return;
        }
    
        while (1) {
            fd_set fds;
            FD_ZERO(&fds);
            FD_SET(fd, &fds);
    
            struct timeval timeout;
            timeout.tv_sec = 2;
            timeout.tv_usec = 0;
    
            int ret = select(fd + 1, &fds, NULL, NULL, &timeout);
            if (ret == -1) {
                printf("Error: Cannot waiting for data\n");
                return;
            } else if (ret == 0) {
                printf("Error: No data coming in time\n");
                return;
            }
    
            /* 处理事件 */
            struct v4l2_event event;
            if (ioctl(fd, VIDIOC_DQEVENT, &event) == -1) {
                printf("Error: Cannot dequeue event\n");
                return;
            }
            if (event.type == V4L2_EVENT_CTRL && event.u.ctrl.changes & V4L2_CTRL_CHG_EVENT_VALUE) {
                /* GPI 状态发生了变化 */
                uint32_t gamma;
                if (ioctl(fd, VIDIOC_G_GAMMA, &gamma) == -1) {
                    printf("Error: Cannot get gamma value\n");
                    return;
                }
                printf("Gamma value: %d\n", gamma);
            }
        }
    }
    

    在上述代码中,0x009a0901 是对应 GPI 状态的控制 ID,可以根据摄像头驱动程序的文档或者源代码中找到。

    需要注意的是,不同的摄像头设备可能会有所不同,这里提供的方法仅供参考。

    评论

报告相同问题?

悬赏问题

  • ¥15 Matlab怎么求解含参的二重积分?
  • ¥15 苹果手机突然连不上wifi了?
  • ¥15 cgictest.cgi文件无法访问
  • ¥20 删除和修改功能无法调用
  • ¥15 kafka topic 所有分副本数修改
  • ¥15 小程序中fit格式等运动数据文件怎样实现可视化?(包含心率信息))
  • ¥15 如何利用mmdetection3d中的get_flops.py文件计算fcos3d方法的flops?
  • ¥40 串口调试助手打开串口后,keil5的代码就停止了
  • ¥15 电脑最近经常蓝屏,求大家看看哪的问题
  • ¥60 高价有偿求java辅导。工程量较大,价格你定,联系确定辅导后将采纳你的答案。希望能给出完整详细代码,并能解释回答我关于代码的疑问疑问,代码要求如下,联系我会发文档