V4L2框架概述 Xilinx视频编解码详解

电子说

1.3w人已加入

描述

  1. 1、V4L2框架概述

  2. V4L2是Video for Linux2的简称,为Linux中关于视频设备的内核驱动。在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写。

  3.  

    1.1 V4L2设备应用层流程

  4.    注册的设备节点有/dev/video和/dev/v4l2-subdev;其应用层操作video设备主要流程如下:

  5.    1) 通过打开video设备设置video参数;

  6.    2) 设置采集方式;

  7.    3) 将数据取出、处理、放回,可循环处理;

  8.    4) 完成相应的任务后关闭。

  9.  

  10. 1.2 内核V4L2模块

        应用层流程可以通过打开文件一样打开视频输入设备,并且配置设备相关参数, 这是由于内核相关模块做了很多基础工作。跟V4L2相关的模块如下图所示:

 Xilinx

                   图1 V4L2基本框架

      1.3 典型捕获管道:

Xilinx

                          图2 Xilinx视频典型捕获管道

  1.   1、硬件视图

  2.       1)多种组合可以开发一个捕获管道;

  3.       2)使用标准化接口(AXI总线接口)在管道中缝合多个IP。

  4.   2、软件视图

  5.       1)复杂性存在于软件级别,以支持多种组合;

  6.       2)由于没有任何标准的方法来配置管道中的不同元素,这给软件开发人员带来了更大的复杂性。

  7.  

  8.      1.4  具有流媒体和/或内存接口的基于帧的视频管道视频捕获设备:

  9.     1)视频存储器到存储器设备;

  10.     2)视频输出设备(无图形);

  11.     3)DMABUF:0拷贝缓冲区共享Media controller;

  12.     4)描述逻辑拓扑和数据流;

  13.     5)多媒体库 GStreamer、FFMPEG、OpenCV、OpenMAX、LibAV、VLC媒体播放器、MPlayers。

  14.  

  15. Xilinx

  16.                   图3 V4L2框架对应设备

  17.  

  18.   2、 Xilinx 视频编解码

     在使用gst命令创建pipeline 完成视频输入到编码输出的过程如下:

Xilinx

           图4 Xilinx 视频输入设备及相关内核模块

     当使用gst 命令处理HDMI视频输入时,我们会使用下面的命令:gst-launch-1.0 -v v4l2src device=/dev/video0 io-mode=4 !video/x-raw(memory:XLNXLL), format=NV16_10LE32, width=3840, height=2160,framerate=60/1 ! omxh265enc num-slices=8 periodicity-idr=240 cpb-size=500gdr-mode=horizontal initial-delay=250 control-rate=low-latencyprefetch-buffer=true target-bitrate=25000 gop-mode=low-delay-p ! video/x-h265,alignment=nal ! rtph265pay ! udpsink buffer-size=60000000 host=192.168.25.89port=5004 async=false max-lateness=-1 qos-dscp=60 max-bitrate=120000000 -v      其中/dev/video0设备对应我们的HDMI输入,使用omxh265enc进行编码,在使用rtph265pay完成RTP封装后,在通过udpsink使用udp将编码后的码流发送出去。这个实现我们可以通过V4L2接口来完成,本身gst 插件也是调用了V4L2接口完成,下面是使用V4L2接口完成上述工作的过程。
  1.     2.1 应用程序通过V4L2接口采集视频数据步骤

  2.      1)打开视频设备文件,通过视频采集的参数初始化, 通过V4L2接口设置视频图像属性;

  3.      2)申请若干视频采集的帧缓存区,并将这些帧缓冲区从内核空间映射到用户空间,便于应用程序读取/处理视频数据;

  4.      3)将申请到的帧缓冲区在视频采集输入队列排队,并启动视频采集;

  5.       4)驱动开始视频数据的采集,应用程序从视频采集输出队列中取出帧缓冲区,处理后,将帧缓冲区重新放入视频采集输入队列,循环往复采集连续的视频数据。最后停止视频采集。 

              流程图如下所示

Xilinx

  1.    2.2 V4L2ioctl控制符

  2.   1)VIDIOC_QUERYCAP    查询设备的属性;

  3.   2)VIDIOC_ENUM_FMT 帧格式;

  4.   3)VIDIOC_S_FMT 设置视频帧格式,对应struct v4l2_format;

  5.   4)VIDIOC_G_FMT 获取视频帧格式等;

  6.   5)VIDIOC_REQBUFS 请求/申请若干个帧缓冲区,一般为不少于3个;

  7.   6)VIDIOC_QUERYBUF 查询帧缓冲区在内核空间的长度和偏移量;

  8.   7)VIDIOC_QBUF 将申请到的帧缓冲区全部放入视频采集输出队列;

  9.   8)VIDIOC_STREAMON 开始视频流数据的采集;

  10.   9)VIDIOC_DQBUF 应用程序从视频采集输出队列中取出已含有采集数据的帧缓冲区;

  11.   10)VIDIOC_STREAMOFF 应用程序将该帧缓冲区重新挂入输入队列。

  12.  

  13.    2.3 控制字符解析和使用用例:

       1)VIDIOC_QUERYCAP-------->struct v4l2_capability         例如:         if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ==V4L2_CAP_VIDEO_CAPTURE)           {                    printf("Device %s: supports capture. ", FILE_VIDEO);            }      if ((cap.capabilities & V4L2_CAP_STREAMING) ==V4L2_CAP_STREAMING)         {          printf("Device %s: supports streaming. ", FILE_VIDEO);         }

    2)VIDIOC_ENUM_FMT-------->struct v4l2_fmtdesc

       //通过这个结构体,可以显示对应的摄像头所支持视频帧格式。例如

         struct v4l2_fmtdesc fmtdesc;         fmtdesc.index = 0;         fmtdesc.type =V4L2_BUF_TYPE_VIDEO_CAPTURE;          printf("Supportformat:/n");         while(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1)         {               printf("/t%d.%s/n",fmtdesc.index+1,fmtdesc.description);               fmtdesc.index++;          }     3)VIDIOC_G_FMT-------->struct v4l2_format 查看视频帧格式     4)VIDIOC_S_FMT 设置视频帧格式     5) VIDIOC_CROPCAP-------->struct v4l2_cropcap结构体     6) 设置Stream信息,主要设置帧率              VIDIOC_G_PARM&VIDIOC_S_PARM-------->structv4l2_streamparm      7)设置Stream信息,主要设置帧率               VIDIOC_G_PARM&VIDIOC_S_PARM-------->structv4l2_streamparm      8)设置Stream信息,主要设置帧率              VIDIOC_G_PARM&VIDIOC_S_PARM-------->structv4l2_streamparm       9)申请和管理缓冲区                           VIDIOC_REQBUFS-------->struct v4l2_requestbuffers      10) 应用程序从视频采集输出队列中取出已含有采集数据的帧缓冲区          VIDIOC_QUERYBUF-------->struct v4l2_buffer           应用程序从视频采集输出队列中取出已含有采集数据的帧缓冲区            intioctl(int fd, VIDIOC_DQBUF, struct v4l2_buffer *argp)       11) 开始视频采集和关闭视频采集            VIDIOC_STREAMON&VIDIOC_STREAMOFF           int ioctl(int fd, VIDIOC_STREAMON, const int *argp)           int ioctl(int fd, VIDIOC_STREAMOFF, const int *argp)         12) 应用程序将该帧缓冲区重新挂入输入队列VIDIOC_QBUF            intioctl(int fd, VIDIOC_QBUF,struct v4l2_buffer *argp)  

3、Xilinx V4L2 Demo

Xilinx

                     图5:Xilinx V4L2 demo

 

Xilinx

          图6:Xilinx V4L2 + CTRLSW encode

  1.       3.1 Xilinx使用V4L2实现视频输入的代码

  2.         Xilinx

  3.  

  4.       Xilinx

 

Xilinx

3.2 应用程序将帧缓冲区重新排入输入队列

       ioctl(fd_v4l2,VIDIOC_QBUF, &buf)

XilinxXilinx  
  1.    3.3   开始视频流数据的采集

  2.   ioctl(fd_v4l2,VIDIOC_STREAMON, &type)

 

   Xilinx

3.4 应用程序将视频采集输出队列中取出已含有采集数据的帧缓冲区           ioctl(fd_v4l2, VIDIOC_DQBUF, &buf)

  Xilinx

3.5 停止视频采集     ioctl(fd_v4l2,VIDIOC_STREAMOFF, &tpe)Xilinx  上面为主要功能函数介绍,具体代码等等请参考如下链接:https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/1010303367/Zynq+UltraScale+MPSoC+VCU+TRD+2020.2+-+Xilinx+Low+Latency+PS+DDR+NV12+HDMI+Audio+Video+Capture+and+Display  

       审核编辑:汤梓红


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分