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

1、v4l2框架概述
v4l2是video for linux2的简称,为linux中关于视频设备的内核驱动。在linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写。
1.1 v4l2设备应用层流程
   注册的设备节点有/dev/video和/dev/v4l2-subdev;其应用层操作video设备主要流程如下:
   1) 通过打开video设备设置video参数;
   2) 设置采集方式;
   3) 将数据取出、处理、放回,可循环处理;
   4) 完成相应的任务后关闭。
1.2 内核v4l2模块
        应用层流程可以通过打开文件一样打开视频输入设备,并且配置设备相关参数, 这是由于内核相关模块做了很多基础工作。跟v4l2相关的模块如下图所示:
图1 v4l2基本框架
      1.3 典型捕获管道:
图2 xilinx视频典型捕获管道
  1、硬件视图
      1)多种组合可以开发一个捕获管道;
      2)使用标准化接口(axi总线接口)在管道中缝合多个ip。
  2、软件视图
      1)复杂性存在于软件级别,以支持多种组合;
      2)由于没有任何标准的方法来配置管道中的不同元素,这给软件开发人员带来了更大的复杂性。
1.4  具有流媒体和/或内存接口的基于帧的视频管道视频捕获设备:
    1)视频存储器到存储器设备;
    2)视频输出设备(无图形);
    3)dmabuf:0拷贝缓冲区共享media controller;
    4)描述逻辑拓扑和数据流;
    5)多媒体库 gstreamer、ffmpeg、opencv、openmax、libav、vlc媒体播放器、mplayers。
图3 v4l2框架对应设备
2、 xilinx 视频编解码
     在使用gst命令创建pipeline 完成视频输入到编码输出的过程如下:
图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接口完成上述工作的过程。     2.1 应用程序通过v4l2接口采集视频数据步骤
     1)打开视频设备文件,通过视频采集的参数初始化, 通过v4l2接口设置视频图像属性;
     2)申请若干视频采集的帧缓存区,并将这些帧缓冲区从内核空间映射到用户空间,便于应用程序读取/处理视频数据;
     3)将申请到的帧缓冲区在视频采集输入队列排队,并启动视频采集;
      4)驱动开始视频数据的采集,应用程序从视频采集输出队列中取出帧缓冲区,处理后,将帧缓冲区重新放入视频采集输入队列,循环往复采集连续的视频数据。最后停止视频采集。 
              流程图如下所示
2.2 v4l2ioctl控制符
  1)vidioc_querycap    查询设备的属性;
  2)vidioc_enum_fmt 帧格式;
  3)vidioc_s_fmt 设置视频帧格式,对应struct v4l2_format;
  4)vidioc_g_fmt 获取视频帧格式等;
  5)vidioc_reqbufs 请求/申请若干个帧缓冲区,一般为不少于3个;
  6)vidioc_querybuf 查询帧缓冲区在内核空间的长度和偏移量;
  7)vidioc_qbuf 将申请到的帧缓冲区全部放入视频采集输出队列;
  8)vidioc_streamon 开始视频流数据的采集;
  9)vidioc_dqbuf 应用程序从视频采集输出队列中取出已含有采集数据的帧缓冲区;
  10)vidioc_streamoff 应用程序将该帧缓冲区重新挂入输入队列。
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
图5:xilinx v4l2 demo
图6:xilinx v4l2 + ctrlsw encode
      3.1 xilinx使用v4l2实现视频输入的代码
3.2 应用程序将帧缓冲区重新排入输入队列
       ioctl(fd_v4l2,vidioc_qbuf, &buf)
     3.3   开始视频流数据的采集
  ioctl(fd_v4l2,vidioc_streamon, &type)
3.4 应用程序将视频采集输出队列中取出已含有采集数据的帧缓冲区           ioctl(fd_v4l2, vidioc_dqbuf, &buf)


PCB传统四层堆叠的缺点
中国制造正在迎来一波新趋势——5G联结万物的浪潮下,从“制造”向“智造”转变
基于SaaS的人工智能培训将改变游戏规则
三大特高压直流电向华东电网输送电量突破5000亿千瓦时
ZPDN-Z1208C-S005光电二极管阵列概述
V4L2框架概述 Xilinx视频编解码详解
数字电源补偿器设计流程解密
贪多嚼不烂 小米最大的敌人是自身
电力线通信技术应用时需要注意的问题
MoveAbsJ指令特点及应用案例分享
CMOS图像传感器开始步入划时代
替换锂离子电池,还需要多久才能实现
解锁石墨烯的抗菌潜力
木林森公布了2018年年度报告,营收增长超一倍
一加5最新消息:隐藏天线+高颜值的一加5来袭,估计小米和华为很难抵挡!
小而强大的银联宝充电器ic U6215
新能源汽车动力电池的安全标准-贝尔试验箱
伺服电机中32位MCU的应用
CBB81(CB221)、CBB92型高压聚丙烯电容器
数据中心机房建设的痛点:投资与运维之间的博弈