Linux&UVC驱动
+ -

LINUX&UVC元数据(MetaData)节点

2024-03-28 9 0

LINUX的V4L2提供了除视频节点的另一个种节点,叫做元数据节点(MetaDataNode)。
元数据是V4L2的一个特性,它允许驱动程序和应用程序传递关于视频流的元数据。LINUX&UVC驱动对V4L2提供了USB总线级的回调支持。

元数据可以包含各种信息,例如关于帧速率、比特率、编解码器类型、场景变化检测(SCM)的结果等的信息。

在LINUX&UVC驱动中。通过uvc_register_video注册视频节点,而通过uvc_meta_register注册元数据节点。注册的函数由uvc_register_terms实现。

/*
 * Register all video devices in all chains.
 */
static int uvc_register_terms(struct uvc_device *dev,
    struct uvc_video_chain *chain)
{
    struct uvc_streaming *stream;
    struct uvc_entity *term;
    int ret;

    list_for_each_entry(term, &chain->entities, chain) {
        if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
            continue;

        stream = uvc_stream_by_id(dev, term->id);
        if (stream == NULL) {
            uvc_printk(KERN_INFO, "No streaming interface found "
                   "for terminal %u.", term->id);
            continue;
        }

        stream->chain = chain;
        //注册视频节点
        ret = uvc_register_video(dev, stream);
        if (ret < 0)
            return ret;

        /* Register a metadata node, but ignore a possible failure,
         * complete registration of video nodes anyway.
         */
         //注册元数据节点
        uvc_meta_register(stream);

        term->vdev = &stream->vdev;
    }

    return 0;
}

相当于视频数据提供的v4l2_ioctl_ops,详见:LINUX&UVC驱动向V4L2提供的回调接口v4l2_ioctl_ops https://www.usbzh.com/article/detail-1343.html
元数据提使用相同的结构体,但提供的回调函数就少了很多。

static const struct v4l2_ioctl_ops uvc_meta_ioctl_ops = {
    .vidioc_querycap        = uvc_meta_v4l2_querycap,
    .vidioc_g_fmt_meta_cap        = uvc_meta_v4l2_get_format,
    .vidioc_s_fmt_meta_cap        = uvc_meta_v4l2_set_format,
    .vidioc_try_fmt_meta_cap    = uvc_meta_v4l2_try_format,
    .vidioc_enum_fmt_meta_cap    = uvc_meta_v4l2_enum_formats,
    .vidioc_reqbufs            = vb2_ioctl_reqbufs,
    .vidioc_querybuf        = vb2_ioctl_querybuf,
    .vidioc_qbuf            = vb2_ioctl_qbuf,
    .vidioc_dqbuf            = vb2_ioctl_dqbuf,
    .vidioc_create_bufs        = vb2_ioctl_create_bufs,
    .vidioc_prepare_buf        = vb2_ioctl_prepare_buf,
    .vidioc_streamon        = vb2_ioctl_streamon,
    .vidioc_streamoff        = vb2_ioctl_streamoff,
};

这些回调函数都对应于在应用层的ioctl请求。所以在应用层也是使用2个节点来进行区分。
如使用命令查看电脑中的一个UVC视频设备,可以看到2个节点:
metadata采集

这里出现了两个设备节点:dev/video0、dev/video1,是因为一个是图像/视频采集,一个是metadata采集。

metadata节点可以像正常的视频节点打开,然后进行元数据的传输。

应用代码

使用数下代码,可以打开视频节点。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
int main(int argc, char**argv)
{
    if(argc != 2)
    {
        printf("%s </dev/video0,1...>\n", argv[0]);
        return -1;
    }
    //打开摄像头设备
    int fd = open(argv[1], O_RDWR);
    if(fd < 0)
    {
        perror("打开设备失败");
        return -1;
    }
    //获取摄像头支持格式,使用ioctl函数int ioctl(int fd, unsigned long request, ...);
    struct v4l2_fmtdesc v4fmt;
    struct v4l2_capability cap;
    v4fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    //选择视频抓取
    int i = 0;
    while(1)
    {
        v4fmt.index = i;
        i++;
        int ret = ioctl(fd, VIDIOC_ENUM_FMT, &v4fmt);
        if(ret < 0)
        {
            perror("获取格式失败");
            break;
        }
        printf("index = %d\n", v4fmt.index);
        printf("flags = %d\n", v4fmt.flags);
        printf("descrrption = %s\n", v4fmt.description);
        unsigned char *p = (unsigned char*)&v4fmt.pixelformat;
        printf("pixelformat = %c%c%c%c\n", p[0],p[1],p[2],p[3]);
        printf("reserved = %d\n", v4fmt.reserved[0]);
    }

    int ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
    if(ret < 0)
        perror("获取功能失败");

    printf("drivers:%s\n", cap.driver);//读取驱动名字
    if(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
        printf("%s 支持视频捕获\n", argv[1]);
    if(cap.capabilities & V4L2_CAP_STREAMING)
        printf("%s 支持流读写\n", argv[1]);
    close(fd);
    return 0;

}

其输出结果如下:
151834611425

  • 运行结果说明我的摄像头视频节点支持视频捕获,同时支持流读写支持两种像素格式YUYV和MJPG。
  • 读不到video1支持的像素格式,说明该摄像头的两个设备节点仅video0用于视频采集,video0用于元数据传输。

本文部分内容来源于:https://blog.csdn.net/qq_41007891/article/details/134619621

0 篇笔记 写笔记

LINUX&UVC元数据(MetaData)节点
LINUX的V4L2提供了除视频节点的另一个种节点,叫做元数据节点(MetaDataNode)。元数据是V4L2的一个特性,它允许驱动程序和应用程序传递关于视频流的元数据。LINUX&UVC驱动对V4L2提供了USB总线级的回调支持。元数据可以包含各种信息,例如关于帧速率、比特率、编解码......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

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

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