FPGA实现HDMI视频H265压缩网络推流输出,基于VCU架构,HDMI2.0输入支持4K60帧,提供工程源码和技术支持
1、前言
Xilinx Zynq UltraScale+ ZUEV系列FPGA自带VCU视频编解码功能,VCU有以下特点:
• 支持多达 32 个流的同步编码和解码 (最大聚合带宽为3840x2160 @ 60fps)
• 低时延速率控制
• 灵活的速率控制:CBR、 VBR 和常量 QP
• 支持分辨率高达 4K UHD @ 60 Hz 的同步编码和解码
• 支持 8 K UHD (~15 Hz) 的降低帧速率
工程概述
本设计采用Zynq UltraScale+MPSoCs–XCZU4EV的高端型号FPGA做基于VCU的H265视频压缩,输入视频源使用笔记本电脑,接收显示设备使用4K显示器;输入视频首先接入板载的HDMI2.0输入接口,然后经过板载的PS8409或其他同等功能的芯片做均衡处理;然后输入差分视频信号直接连到FPGA的GT BANK2上;然后调用Xilinx官方的Video PHY Controller IP核接收4K输入视频并做解串工作,将原来高速串行信号解为3路20bit的AXI4-Stream并行数据,该IP需使用FPGA GT资源;然后调用Xilinx官方的HDMI 1.4/2.0 Receiver Subsystem IP核做4K 高清视频的解码工作,IP 同时解码出音频流和视频流,以AXI4-Stream流输出;然后然后调用Xilinx官方的Video Processing Subsystem IP核做图像缩放操作;然后然后调用Xilinx官方的Video Frame Buffer Write IP核将图像写入PS侧的DDR4中缓存;然后然后调用Xilinx官方的Zynq UltraScale+ VCU IP核读出图像并作H265压缩;至此,整个FPGA工程已经完成;然后编译工程,导出.xsa文件,并在PetaLinux中做嵌入式Linux启动文件,在Linux软件设计中,将压缩的H265视频码流通过TCP协议从网口发送出去,在PC端可通过LVC播放器播放压缩的H265码流;然后将做好的Linux启动文件复制到TF卡中,插上TF卡即可启动Linux系统,在Xshell中即可操作终端进行配置;
本设计提供资源如下:
• 提供一套XCZU4EV开发板
• 提供一套Vivado2020.2版本的工程源码
• 提供一套编译好的固件,可启动Linux系统
本博客详细描述了Xilinx系列Zynq UltraScale+MPSoCs–XCZU4EV的高端型号FPGA做基于VCU的H265视频压缩的设计方案,工程代码可综合编译上板调试,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做学习提升,可应用于医疗、军工等行业的高速接口或图像处理领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;
免责声明
本工程及其源码即有自己写的一部分,也有网络公开渠道获取的一部分(包括CSDN、Xilinx官网、Altera官网以及其他开源免费获取渠道等等),若大佬们觉得有所冒犯,请私信批评教育;部分模块源码转载自上述网络,版权归原作者所有,如有侵权请联系我们删除;基于此,本工程及其源码仅限于读者或粉丝个人学习和研究,禁止用于商业用途,若由于读者或粉丝自身原因用于商业用途所导致的法律问题,与本博客及博主无关,请谨慎使用。。。
2、相关方案推荐
我这里已有的视频图像编解码方案
我这里有图像的JPEG解压缩、JPEG-LS压缩、H264编解码、H265编解码以及其他方案,后续还会出更多方案,我把他们整合在一个专栏里面,会持续更新,专栏地址:
直接点击前往
3、详细设计方案
设计框图
本设计使用的工程详细设计方案框图如下:
FPGA开发板
本UP主有下列FPGA开发板均可实现4K@60Hz视频 HDMI2.0的收发,本博客仅仅是介绍了其中Zynq UltraScale+系列的开发板实现方案,关于本博客使用的这款开发板详细信息,请参考我之前的博客,对这块开发板感兴趣的朋友可以咨询本UP获得;博客链接如下:
点击直接前往
视频输入
工程源码1的视频输入为笔记本电脑,前提是你的笔记本电脑要能够输出4K@60Hz分辨率才行,可通过查看显示驱动版本确定是否支持4K@60Hz分辨率,参考如下:
一般驱动版本在20.0以上就是支持输出4K的;
Video PHY Controller
用XIlinx方案做4K HDMI2.0视频收发必须要用到此IP,Video PHY Controller IP核主要做解串和串化的工作,利用FPGA GT资源,即利用GTH;在接收端接收4K 高清视频并做解串工作,将原来高速串行信号解为3路20bit的AXI4-Stream并行数据,在发送端做4K 高清视频并做串化工作,将原3路20bit的AXI4-Stream并行数据串化为高速串行信号;Video PHY Controller配置如下:
关于Video PHY Controller收发HDMI2.0的用法,请参考我之前的博客,博客地址如下:
点击直接前往
HDMI 1.4/2.0 Receiver Subsystem
用XIlinx方案做4K HDMI视频收发必须要用到此IP,4K HDMI输入视频经过Video PHY Controller解串后输入HDMI 1.4/2.0 Receiver Subsystem IP,该IP做4K 高清视频的解码工作,IP 同时解码出音频流核视频流,以AXI4-Stream流输出;HDMI 1.4/2.0 Receiver Subsystemr配置如下:
关于HDMI 1.4/2.0 Receiver Subsystem接收HDMI2.0的用法,请参考我之前的博客,博客地址如下:
点击直接前往
Video Processing Subsystem
这里介绍一下Video Processing Subsystem;
Video Processing Subsystem有缩放、去隔行、颜色空间转换等功能,这里仅使用图像缩放功能;其特点如下:
适用于Xilinx所有系列的FPGA器件;
支持最大分辨率:8K,即可以处理高达8K的视频;
输入视频格式:AXI4-Stream;
输出视频格式:AXI4-Stream;
需要SDK软件配置,其本质为通过AXI_Lite 做寄存器配置;
模块占用的FPGA逻辑资源更小,相比于自己写的HLS图像缩放而言,官方的Video Processing Subsystem资源占用大约减小30%左右,且更高效:
Video Processing Subsystem逻辑资源如下,请谨慎评估你的FPGA资源情况;
Video Processing Subsystem IP配置如下:这里配置为仅缩放模式,最高4K;
在Linux设计中可以对输入视频进行缩放,通过终端指令配置缩放视频分辨率;
关于Video Processing Subsystem图像缩放的详细用法,请参考我之前的博客,博客地址如下:
点击直接前往
Video Frame Buffer Write
Video Frame Buffer Write相当于精简版的VDMA,只具有视频写入DDR的功能,与VDMA相比具有YUV视频写入的功能,配置如下:
在Linux设计中可以对视频写入的基地址进行配置,通过终端指令配置;
Zynq UltraScale+ VCU
Zynq UltraScale+ VCU是Xilinx Zynq UltraScale+ ZUEV系列FPGA才有的IP,可以实现最高4K60帧的视频压缩和解压,IP的官方文档是《PG252》,读者可以自行前往阅读,Zynq UltraScale+ VCU配置如下:
输入视频格式为YUV420,最高分辨率配置为4K60帧;
PetaLinux 工程编译
注意!!!
注意!!!
注意!!!
本博主已经提供好已制作完成的启动文件,理论上PetaLinux 工程编译不不要您重复再做,如果您感兴趣,则可以做这一步。。。
PetaLinux版本:PetaLinux版本为2020.2,因为vivado用的vivado202.2,为了兼容性,建议使用与之配套的PetaLinux2020.2;
运行环境:Ubuntu操作系统,我用的Win10上虚拟机搭建的Ubuntu,当然也可以使用直接装Ubuntu操作系统的电脑;
第1步:导出vivado工程的.xsa文件,并放到Ubuntu下你新建的文件夹中;同时下载我们提供的BSP包,也放到Ubuntu下你新建的文件夹中;然后改变其用户权限,如下图:
• 终端指令:sudo chmod -R 777 文件名
第2步:配置PetaLinux2020.2环境变量,如下图:
• 终端指令:source /opt/pkg/petalinux/2020.2/settings.sh
第3步:建立基于BSP包的PetaLinux2020.2工程,如下图:
• 终端指令:petalinux-create -t project -s zu402_sd.bsp -n zu402_sd
第4步:将.xsa硬件信息导入PetaLinux2020.2工程,如下图:
• 终端指令:petalinux-config --get-hw-description=/home/文件路径/zu402_sd
在编译环境设置时,建议使用离线编译,当然,选择在线编译也是可以的,离线编译配置如下:
Yocto Settings → Add pre-mirror url如下,路径要改为你自己 download 及 ssate 的解压路径;
Yocto Settings → Local sstate feeds settings如下,路径要改为你自己 download 及 ssate 的解压路径;
其他配置保持默认即可,然后保存退出,如下:
第5步:修改设备树文件,如下图:
将我们提供的设备树文件替换掉PetaLinux工具自动生成的用户设备树文件;
• 终端指令:ln -sf zu402_hdmirx.dtsi system-user.dtsi
• 终端指令:ls -l
第6步:编译PetaLinux2020.2工程,如下图:
• 终端指令:petalinux-build
如果编译中途有报错信息,请复制报错信息并百度寻找解决办法,因为每个人的电脑配置不一样,环境配置不一样,遇到的问题也不一样,无法给出统一的答案;
第7步:生成镜像,如下图:
• 终端指令:cd images/linux
• 终端指令:petalinux-package --boot --fsbl zynqmp_fsbl.elf --u-boot u-boot.elf --pmufw pmufw.elf --fpga
system.bit
然后把PetaLinux2020.2工程生成的如下几个文件连同我们提供好的脚本文件一起放入SD卡中,如下:
到此们就可以插入SD卡上电跑系统了;
VLC播放器
压缩后的H265码流可通过VLC播放器播放,关于VLC播放器的安装与使用,请参考下面的博客链接:
点击直接前往
工程源码架构
工程源码架构包括vivado Block Design逻辑设计和PetaLiux软件设计;
Block Design逻辑设计架构截图如下:
综合后的源码架构如下:
需要注意的是,在对Block Design进行Generate Output Products时需要选择Global模式,如下:
4、Vivado工程源码详解
开发板FPGA型号:Xilinx–Zynq UltraScale+MPSoCs–xczu4ev-sfvc784-2-i;
开发环境:Vivado2020.2;
输入:笔记本电脑,HDMI2.0,最高分辨率4K @60Hz;
输出:RJ45网口,H265压缩码流;
视频压缩方案:Zynq UltraScale+ VCU–H265;
工程源码架构请参考前面第3章节中的《工程源码架构》小节;
工程作用:此工程目的是让读者掌握FPGA基于VCU的H265视频压缩的设计能力,以便能够移植和设计自己的项目;
工程的资源消耗和功耗如下:
5、工程移植说明
vivado版本不一致处理
1:如果你的vivado版本与本工程vivado版本一致,则直接打开工程;
2:如果你的vivado版本低于本工程vivado版本,则需要打开工程后,点击文件–>另存为;但此方法并不保险,最保险的方法是将你的vivado版本升级到本工程vivado的版本或者更高版本;
3:如果你的vivado版本高于本工程vivado版本,解决如下:
打开工程后会发现IP都被锁住了,如下:
此时需要升级IP,操作如下:
FPGA型号不一致处理
如果你的FPGA型号与我的不一致,则需要更改FPGA型号,操作如下:
更改FPGA型号后还需要升级IP,升级IP的方法前面已经讲述了;
其他注意事项
1:由于每个板子的DDR不一定完全一样,所以MIG IP需要根据你自己的原理图进行配置,甚至可以直接删掉我这里原工程的MIG并重新添加IP,重新配置;
2:根据你自己的原理图修改引脚约束,在xdc文件中修改即可;
3:纯FPGA移植到Zynq需要在工程中添加zynq软核;
6、上板调试验证并演示
准备工作
FPGA开发板,推荐使用本博的开发板;
笔记本电脑,仅作输入源;
带显卡的电脑主机,显卡越贵越好;
网线;
开发板具体连接见资料包里的连接图:
开发板有启动模式选择拨码开关,SD卡启动方式如下,请将开发板拨到如图的配置:
然后将资料中的如下图所示压缩包解压,并将解压后的全部文件复制到TF卡中:
然后插上TF卡,然后将串口线和网线连接到电脑,安装串口驱动,资料包中已经提供,上电;
配置Xshell
我们使用Xshell连接开发板模拟Linux终端的操作,Xshell配置如下:
配置开发板IP
首先需要配置开发板IP,配置为和你的电脑在同一网段即可,因为开发板压缩的码流视频需要发送给电脑;首先查看你的电脑IP,以我的为例如下:
然后在Xshell依次输入如下指令配置配置开发板IP,具体配置要根据你的电脑IP而定,这里只是以我的为例,如果这一步都看不懂建议不要往下看了。。。
• 终端指令:ifconfig
• 终端指令:ifconfig ethe 169.254.86.135
如下:
然后ping电脑IP,一定要能ping通,不然后面的操作就没意义了,如下:
• 终端指令:ping 169.254.86.136
配置输入视频
需要检测输入视频的格式,配置视频缩放,如下:
• 终端指令:media-ctl -p -d /dev/media0
可以看到我的输入视频为1080P,其中 RBG888_1X24/1920x1080为 HDMI 输入的视频格式,后面配 VPSS 参数会用到,接着配置视频缩放,如下:
• 终端指令:media-ctl -d /dev/media0 -V ““a0080000.v_proc_ss”:0 [fmt:RBG888_1X24/1920x1080 field:none]”
• 终端指令:media-ctl -d /dev/media0 -V ““a0080000.v_proc_ss”:1 [fmt:RBG888_1X24/1920x1080 field:none]”
如果输入的视频为4K,则指令变为如下:
• 终端指令:media-ctl -d /dev/media0 -V ““a0080000.v_proc_ss”:0 [fmt:RBG888_1X24/3840x2160 field:none]”
• 终端指令:media-ctl -d /dev/media0 -V ““a0080000.v_proc_ss”:1 [fmt:RBG888_1X24/3840x2160 field:none]”
配置H265视频压缩
输入如下指令:
• 终端指令:gst-launch-1.0 v4l2src device=/dev/video0 io-mode=4 ! video/x-raw, format=NV12, width=1920, height=1080, framerate=60/1 ! omxh265enc qp-mode=auto gop-mode=basic gop-length=60 b-frames=0 target-bitrate=60000 num-slices=8 control-rate=constant prefetch-buffer=true low-bandwidth=false filler-data=true cpb-size=1000 initial-delay=500 periodicity-idr=60 ! video/x-h265,profile=main, alignment=au ! queue ! mpegtsmux alignment=7 name=mux ! rtpmp2tpay ! udpsink host=192.168.3.125 port=5004
注意!!!
注意!!!
注意!!!
上述指令中的《udpsink host=192.168.3.125 port=5004》
这里的IP是根据我自己的电脑配置的,你的电脑请根据实际情况修改;端口号5004为固定值;
如果输入的视频为4K,则指令变为如下:
• 终端指令:gst-launch-1.0 v4l2src device=/dev/video0 io-mode=4 ! video/x-raw, format=NV12, width=3840, height=2160, framerate=60/1 ! omxh265enc qp-mode=auto gop-mode=basic gop-length=60 b-frames=0 target-bitrate=60000 num-slices=8 control-rate=constant prefetch-buffer=true low-bandwidth=false filler-data=true cpb-size=1000 initial-delay=500 periodicity-idr=60 ! video/x-h265,profile=main, alignment=au ! queue ! mpegtsmux alignment=7 name=mux ! rtpmp2tpay ! udpsink host=192.168.3.125 port=5004
配置VLC播放器
开发板网线连接电脑,打开VLC播放器,配置如下:
这里一定要注意:这里的IP是根据我自己的电脑配置的,你的电脑请根据实际情况修改;
注意!!!
注意!!!
注意!!!
电脑端一定要用有显卡的电脑,不要用笔记本电脑,不然延时很大,根本无法播放。。。
VLC播放H265码流视频演示
VLC播放H265码流视频演示如下:
FPGA实现H265视频压缩
7、福利:工程源码获取
福利:工程代码的获取
获取方式:私,或者博客末尾的V名片;
此外,有很多朋友给本博主提了很多意见和建议,希望能丰富服务内容和选项,因为不同朋友的需求不一样,所以本博主还提供以下服务: