【问题标题】:How to get list of supported frame size and frame interval of webcam device using video4linux api?如何使用 video4linux api 获取网络摄像头设备支持的帧大小和帧间隔列表?
【发布时间】:2013-02-27 12:27:02
【问题描述】:

我正在尝试使用 V4L2 api 枚举网络摄像头设备支持的帧大小和帧速率。我尝试使用以下代码进行操作但没有成功。 ioctl 函数总是返回 -1。

#include <stdio.h>
#include <fcntl.h>
#include "linux/videodev2.h"
int main(int argc, char **argv) {
    int fd = open("/dev/video0", O_RDWR);
    struct v4l2_frmivalenum frmsize;
    memset(&frmsize, 0, sizeof (struct v4l2_frmsizeenum));
    ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS , &frmsize);
    printf("%u \n", frmsize.he);
    return 0;
}

【问题讨论】:

  • open() 也返回 -1 吗?
  • 不,它没有。实际上 ioctl 与命令 VIDIOC_QUERYCAP 一起工作。我想也许我以错误的方式使用 API。也许我应该在使用 VIDIOC_ENUM_FRAMEINTERVALS 之前设置像素格式。

标签: c v4l2 video4linux


【解决方案1】:

您应该在ioctl VIDIOC_ENUM_FRAMESIZES 之前设置 in 参数以获取帧大小:

Table A.34. struct v4l2_frmivalenum
__u32   index               IN: Index of the given frame interval in the enumeration.
__u32   pixel_format        IN: Pixel format for which the frame intervals are enumerated.
__u32   width               IN: Frame width for which the frame intervals are enumerated.
__u32   height              IN: Frame height for which the frame intervals are enumerated.

ioctl VIDIOC_ENUM_FRAMEINTERVALS 获取帧间隔:

Table A.31. struct v4l2_frmsizeenum
__u32   index               IN: Index of the given frame size in the enumeration.
__u32   pixel_format        IN: Pixel format for which the frame sizes are enumerated.

那么枚举帧大小和帧间隔的实现可能是:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "linux/videodev2.h"
void printFrameInterval(int fd, unsigned int fmt, unsigned int width, unsigned int height)
{
    struct v4l2_frmivalenum frmival;
    memset(&frmival,0,sizeof(frmival));
    frmival.pixel_format = fmt;
    frmival.width = width;
    frmival.height = height;
    while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival) == 0) 
    {
        if (frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) 
            printf("[%dx%d] %f fps\n", width, height, 1.0*frmival.discrete.denominator/frmival.discrete.numerator);
        else
            printf("[%dx%d] [%f,%f] fps\n", width, height, 1.0*frmival.stepwise.max.denominator/frmival.stepwise.max.numerator, 1.0*frmival.stepwise.min.denominator/frmival.stepwise.min.numerator);
        frmival.index++;    
    }
}

int main(int argc, char **argv) {
    unsigned int width=0, height=0;;
    int fd = open("/dev/video0", O_RDWR);
    struct v4l2_frmsizeenum frmsize;
    memset(&frmsize,0,sizeof(frmsize));
    frmsize.pixel_format = V4L2_PIX_FMT_JPEG;
    while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) == 0)
    {
        if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) 
        {
            printFrameInterval(fd, frmsize.pixel_format, frmsize.discrete.width, frmsize.discrete.height);
        }
        else
        {
            for (width=frmsize.stepwise.min_width; width< frmsize.stepwise.max_width; width+=frmsize.stepwise.step_width)
                for (height=frmsize.stepwise.min_height; height< frmsize.stepwise.max_height; height+=frmsize.stepwise.step_height)
                    printFrameInterval(fd, frmsize.pixel_format, width, height);

        }
        frmsize.index++;
    }
    return 0;
}

【讨论】:

    【解决方案2】:

    我认为您使用的驱动程序没有实现vidioc_enum_frameintervals

    请注意,每个视频驱动程序都会注册v4l2_ioctl_ops

    例如,在内核 3.7 中,drivers/media/usb/s2255/s2255drv.c 实现了它。 drivers/staging/media/go7007/go7007-v4l2.c 也实现了。

    但是,虚拟视频驱动程序drivers/media/platform/vivi.c 没有实现它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      相关资源
      最近更新 更多