Linux&UVC驱动
+ -

LINUX&UVC驱动枚举视频帧大小和帧率

2024-04-01 1 0

UVC视频分为视频格式、帧大小及帧率。不过一般帧率和帧大小(分辨率)合并在一起的。
视频格式通过VIDIOC_ENUM_FMT获取到,但该视频格式下可能支持多种帧率和帧大小(分辨率)。故在应用层通过VIDIOC_ENUM_FRAMESIZES控制码来枚举该视频格式下的帧分辨率及帧率。
帧分辨率在UVCC&LINUX驱动中为:

const struct v4l2_ioctl_ops uvc_ioctl_ops = {
    .vidioc_enum_frameintervals = uvc_ioctl_enum_frameintervals,
    .vidioc_enum_frameintervals = uvc_ioctl_enum_frameintervals,
}

通过淅代码可知,其首先通过指定的视频格式找到其对应的struct uvc_format,然后再在该视频格式枚举其下的帧分辨率。

static int uvc_ioctl_enum_framesizes(struct file *file, void *fh,
                     struct v4l2_frmsizeenum *fsize)
{
    struct uvc_fh *handle = fh;
    struct uvc_streaming *stream = handle->stream;
    struct uvc_format *format = NULL;
    struct uvc_frame *frame = NULL;
    unsigned int index;
    unsigned int i;

    /* Look for the given pixel format */
    for (i = 0; i < stream->nformats; i++) {
        if (stream->format[i].fcc == fsize->pixel_format) {
            format = &stream->format[i];
            break;
        }
    }
    if (format == NULL)
        return -EINVAL;

    /* Skip duplicate frame sizes */
    for (i = 0, index = 0; i < format->nframes; i++) {
        if (frame 
            && frame->wWidth == format->frame[i].wWidth 
            && frame->wHeight == format->frame[i].wHeight)
            continue;
        frame = &format->frame[i];
        if (index == fsize->index)
            break;
        index++;
    }

    if (i == format->nframes)
        return -EINVAL;

    fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
    fsize->discrete.width = frame->wWidth;
    fsize->discrete.height = frame->wHeight;
    return 0;
}

而帧率的相关函数为:

static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh,
                     struct v4l2_frmivalenum *fival)
{
    struct uvc_fh *handle = fh;
    struct uvc_streaming *stream = handle->stream;
    struct uvc_format *format = NULL;
    struct uvc_frame *frame = NULL;
    unsigned int nintervals;
    unsigned int index;
    unsigned int i;

    /* Look for the given pixel format and frame size */
    for (i = 0; i < stream->nformats; i++) {
        if (stream->format[i].fcc == fival->pixel_format) {
            format = &stream->format[i];
            break;
        }
    }
    if (format == NULL)
        return -EINVAL;

    index = fival->index;
    for (i = 0; i < format->nframes; i++) {
        if (format->frame[i].wWidth == fival->width &&
            format->frame[i].wHeight == fival->height) {
            frame = &format->frame[i];
            nintervals = frame->bFrameIntervalType ?: 1;
            if (index < nintervals)
                break;
            index -= nintervals;
        }
    }
    if (i == format->nframes)
        return -EINVAL;

    if (frame->bFrameIntervalType) {
        fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
        fival->discrete.numerator =    frame->dwFrameInterval[index];
        fival->discrete.denominator = 10000000;
        uvc_simplify_fraction(&fival->discrete.numerator,&fival->discrete.denominator, 8, 333);
    } else {
        fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
        fival->stepwise.min.numerator = frame->dwFrameInterval[0];
        fival->stepwise.min.denominator = 10000000;
        fival->stepwise.max.numerator = frame->dwFrameInterval[1];
        fival->stepwise.max.denominator = 10000000;
        fival->stepwise.step.numerator = frame->dwFrameInterval[2];
        fival->stepwise.step.denominator = 10000000;
        uvc_simplify_fraction(&fival->stepwise.min.numerator,&fival->stepwise.min.denominator, 8, 333);
        uvc_simplify_fraction(&fival->stepwise.max.numerator,&fival->stepwise.max.denominator, 8, 333);
        uvc_simplify_fraction(&fival->stepwise.step.numerator,&fival->stepwise.step.denominator, 8, 333);
    }

    return 0;
}

0 篇笔记 写笔记

UVC修改相机分辨率帧率
熟悉UVC规范的都知道,UVC摄像头或相机可以通过UVC视频流接口支持多种分辨率和格式,但是一般都会有一个默认的视频数据格式和分辨率。如本人手中的一个UVC摄像头,可以看到其支持多种格式和分辨率,我们可以通过potplayer来查看。可以看到,其支持MJPG,YUY2两种各式和多种的分辨率。当然,这......
LINUX&UVC驱动枚举视频帧大小和帧率
UVC视频分为视频格式、帧大小及帧率。不过一般帧率和帧大小(分辨率)合并在一起的。视频格式通过VIDIOC_ENUM_FMT获取到,但该视频格式下可能支持多种帧率和帧大小(分辨率)。故在应用层通过VIDIOC_ENUM_FRAMESIZES控制码来枚举该视频格式下的帧分辨率帧率帧分辨率在UVCC......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!