FPGA实现SDI视频编解码目前有两种方案:
一是使用专用编解码芯片,比如典型的接收器GS2971,发送器GS2972,优点是简单,比如GS2971接收器直接将SDI解码为并行的YCRCB,GS2972发送器直接将并行的YCRCB编码为SDI视频,缺点是成本较高,可以百度一下GS2971和GS2972的价格;
另一种方案是使用FPGA实现编解码,利用FPGA的GTP/GTX/GTH资源实现解串,优点是合理利用了FPGA资源,GTP/GTX/GTH资源不用白不用,缺点是操作难度大一些,对FPGA水平要求较高。
本文详细描述了Zynq ultrascale+系列FPGA使用GTH实现SDI视频回环的实现设计方案,工程代码编译通过后上板调试验证,文章末尾有演示视频,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像传输领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;
在此之前,我使用Kintex7的GTX实现过SDI视频收发,也写过几篇文章,如果感兴趣,可以参考我之前写过的:
文章1:Kintex7使用GTX实现SDI接收点击查看文章
文章2:Kintex7使用GTX实现SDI收发点击查看文章
文章3:Kintex7使用GTX实现SDI的SFP光纤收发点击查看文章
本文与之前写的3篇文章的区别在于:
1、使用的器件不同,前者是Kintex7-325T,本文是Zynq ultrascale+XCZU7EV;
2、使用的高速接口资源不同,前者是GTX,本文是GTH;
3、使用的SDI编解码IP,不同,前者是SMPTE-SDI,本文是SMPTE UHD-SDI;
4、使用的vivado版本不同,前者是vivado2019.1,本文是2021.1;
读者可根据自己的实际项目选择不同的版本文章进行学习或者参考;
SDI 接口即数字分量串行接口(Serial Digital Interface),是 1989 年由 SMPTE(电影和电视工程师协会)标准化的一系列数字视频接口。SMPTE 最初定义的标准数据速率是 270Mbps,用来满足标清数据的传输。随着用户对视频分辨率的要求越来越高,在 SMPTE 259M 的标准上,又提出了更高清晰度的串行数字化接口的标准,例如SMPTE 292M、SMPTE 372M 等等。对应的 SMPTE 标准如下:
SDI 视频采用带有 BNC 连接头的同轴电缆传输,标称阻抗 75 欧姆 。
各种 SDI 标准均使用 75 欧姆阻抗同轴电缆和 BNC 连接器进行传输,这和模拟视频场合中使用的传输媒介一致。源端信号峰峰值幅度为 800mV±10%。由于信号衰减,接收端收到的信号幅度小于该峰峰值,因此传输距离受限,一般来说,SD-SDI 传输距离小于 300m,HD-SDI 传输距离小于 100m,3G-SDI 传输距离则更短。
SDI 数据将控制信号嵌入到了串行数据中,在接收端解串后,得到的也是一组数据流,需要用户逻辑来将嵌入式数据流转换为行场同步的数据。
以 3G-SDI 为例:在同轴线缆上,数据以 NRZI(翻转不归零码)形式传输,数据速率为 2.97Gbps。那么这个2.97Gbps 是如何得来的呢?在传输 1080P60 的视频图像时,虽然有效像素为 1920*1080 个,但是视频时序中还包含行场消隐时间,如下图:
这样在计算时,就需要计算包含了行消隐区和场消隐区在内的总时钟。在 1080P60 制式下H_Total = 2200,V_Total=1125 ,那么计算如下:
2200×1125×60=148500000;
看起来很熟悉的数据,也就是 SDI 基准时钟。同时,在 SDI 视频传输中,一个像素由 20bits 数据表示,包含10bits的亮度数据 Y[9:0]和10bits 的色度数据 C[9:0] 。那么当使用串行传输时,数据速率也就是 2.97Gbps。
148500000×20=2970000000
那么,问题来了? 在并行传输时,有行场同步信号、数据使能信号等信号线用来判断有效像素区域。串行传输呢,只有一根信号线,怎么判断像素区域呢?这就有了数字同步信号,将帧、场、行等信息通过嵌入式控制字来表示,也就是SAV\EAV(有效视频区域的开始\结束)。
在后面的视频流提取中,笔者会对这个信号做详细介绍。
设计思路和架构如下:
输入:
4路3G-SDI摄像头,分辨率1080P@30Hz;
均衡EQ:
使用LMH0384芯片均衡EQ;
GTH解串:
使用GTH资源实现高速串行数据到并行数据的转换,调用官方的Ultrascale Fpgas transceivers wizard IP实现;
SDI解码:
解码出SDI中的有效视频数据,调用官方的SMPTE UHD-SDI IP实现;
FIFO回环:
将接收到的SDI视频返回按照GTH+SDI架构发送出去,中间没有经过DDR缓存,只是经过了FIFO缓冲就直接送出去;
SDI编码和GTH串化:
是解串和解码的逆过程;
增强驱动:
使用LMH0302SQ芯片增强驱动
SDI转HDMI盒子:
用的绿联的盒子,将SDI转为HDMI,方便显示器显示;
开发板:Zynq ultrascale+XCZU7EV;
开发环境:vivado2021.1;
输入:3G-SDI摄像头,1080P,分辨率1920x1080@30Hz;
输出:SDI转HDMI盒子,最后送显示器;
本工程参考了Xilinx给的架构,如下:
我们可以看到主要的逻辑模块包含了SMPTE SDI Core、Control Module、GTH Wizard IP 以及 GTH Common。Audio Embedder 是可选的,不包含在核心实例中。
工程代码架构如下:
代码中设置了4路视频的收发,可根据自己的项目修改视频路数,设置了参数可自由修改,如下:
如果你只需要1路SDI收发,则将4改为1即可。。。
从上图可以看到主要的逻辑模块包含了 SMPTE SDI Core、Control Module、GTH Wizard IP 以及 GTH Common。
Control Module :
控制模块包含以下几种功能:
1、用于控制 GTH 收发器的复位逻辑 ;
2、允许 RX 和 TX 串行分频器进行动态切换,以支持 SD-SDI、HD-SDI 和 3G-SDI 不同模式;
3、TX 参考时钟的动态切换,用以支持 HD-SDI和 3G-SDI 标准中的两种不同比特率: HD-SDI 模式下的 1.485 Gb/s 和 1.485/1.001 Gb/s 比特率、3G-SDI 模式下的2.97 Gb/s 和 2.97/1.001 Gb/s 比特率;
4、数据恢复单元,用于以 SD-SDI 模式下恢复数据 5、RX 比特率检测,以确定接收器正在接收整数帧速率信号还是分数帧速率信号。
实例化了一个 UltraScale/ UltraScale+ fpga GTH 收发器,包含 GTHE3/4_CHANNEL 原语的实例和相应的控制模块。
GTH Common:
例化了一个 GTH Quad 的 GTHE3/4_COMMON 原语。如果使用到 Quad 上的 QPLL0/1 时钟,就必须例化 GTHE3/4_COMMON,参考时钟输入最好同一个 Quad 上。如果使用的是 CPLL 则不需要例化。具体内容参照后面的收发器时钟结构。
Ultrascale Fpgas transceivers wizard IP 配置
GTH 收发器及其时钟结构
首先,我们来看一下 xilinx 的 ultrascale 和 ultrascale+的 GTH 收发器结构,如下图所示,可以看到,收 GTH 高速收发器通常使用 Quad 来划分,一个 Quad 由四个 GTHE3/4_CHANNEL 原语和一个 GTHE3/4_COMMON 原语组成。
每个 GTHE3/4_COMMON 中包含 QPLL0 和 QPLL1,用于给四个收发器通道提供时钟,是四个通道公用的。只有在应用程序中使用 QPLL 时,才需要实例化 GTHE3/4_COMMON,同时我们可以看到有两个 IBUFDS_GTE3/4/OBUFDS_GTE3/4,这就允许用户在设计中提供两个不同的基准时钟。。每个 GTHE3/4_CHANNEL 由一个 channel PLL(CPLL)、一个 transmitter,和一个 receiver 组成。一个参考时钟可以直接连接到一个 GTHE3/4_CHANNEL 原语,而不需要实例化 GTHE3/4_COMMON;
由下图可知,这个 GTHE3/4_COMMON 就是一个基准时钟选择器,用来选择不同来源的时钟作为收发器的基准时钟。GTHE3/4_COMMON 支持 7 种基准时钟源的选择。当然,一般来说,性能最好的基准时钟源就是最近的这个 Quad 自身的 refclk,也就是 GTREFCLK00 和 GTREFCLK10。
在高清视频传输中,美国、加拿大等使用 NTSC 标准,基准时钟为 148.35MHZ、74.176MHZ。中国、德国等国家采用的 PAL 标准,基准时钟为 148.5MHZ 和 74.25MHZ。在高清视频领域,这两者的差别只在于基准时钟,而视频时序都是相同的。这也造成了在设备上我们经常看到两种帧率,如 60hz 和 59.94hz。
我们这里选择本地时钟 GTREFCLK 作为参考时钟。这里必须实例化其相应的 IBUDFS_GTE3/4 原语来使用这些专用参考时钟。我们将这个时钟通过 IBUFDS_GTE3/4 连接到 GTH 收发器的 GTHE3/4 _ COMMONE 的原语端口上。
SMPTE UHD-SDI 内核支持从 SD-SDI 到 12G-SDI 的 SMPTE SDI 数据速率,内核支持同时发送和接收。SMPTE UHD-SDI 允许在发送端嵌入不同类型的辅助数据,包括音频。任何嵌入在 SDI 数据流中的辅助数据都会显示在 SMPTE UHD-SDI 接收端输出的数据流上。它还兼容 7 系列 GTX 收发器和 UltraScale™和UltraScale+™GTH 收发器。
下图是 SMPTE UHD-SDI 接收端的框图。来自串行收发器 RX 的数据通过 rx_data_in 端口进入 SMPTE UHD-SDI接收器,对于SD、HD 和 3G 模式,每个时钟周期 20 位;对于 6G 和 12G 模式,每个时钟周期 40 位。在 SD 模式下,rx_data_in 上的 20 位数据转到 DRU (data recovery unit), DRU 从 11 倍过采样数据中恢复 10 位数据。数据由 SDI解扰器解扰,然后由 SDI 成帧器进行字对齐。之后就是同步位恢复功能。 此功能可还原由变送器修改的 3FF 和 000值,以减少 6G 和 12G-SDI 模式下的运行长度。这三个模块以全 rx_clk 速度运行,并根据 SDI 模式在每个时钟周期处理 40、20 或 10 位数据。 数据进入 stream demux,该 demux 确定有多少数据流交织在一起,然后在单独的数据路径上分离每个数据流,最多支持 16 个数据流。
每路数据流进入一个处理单元,该单元进行 CRC 错误检查、行号捕获和 ST 352 包捕获。还可以从 stream demux 中提取视频时序并产生 rx_eav,rx_sav 和 rx_trs 时序信号。这些时序信号由 SDI 模式检测并给传输检测模块使用。
下图是 SMPTE UHD-SDI 发射端的框图。最多可以支持 16 路 SDI 数据流,数据流首先通过 ST 352 插入模块,可以有选择地插入 ST 352 有效负载 ID 数据包,从 ST 352 插入模块输出的数据流称为 tx_ds1_st352_out 至tx_ds16_st352_out。输出这些流可以方便用户在 ST 352 数据包后插入辅助数据。 发送器的其余部分可以直接使用ST 352 数据包插入模块输出的流,也可以使用 16 个 tx_ds1_anc_in 到 tx_ds16_anc_in 数据流。请注意,如果使用tx_dsn_anc_in 数据流,则它们必须是完整的 SDI 数据流,而不仅仅是辅助数据。
通常情况下,每个 Y/C 数据流对的 Y 数据流中只插入 ST 352 包。而在 3G-SDI level A mode-only 模式下,数据流 1 和数据流 2 都必须插入 ST 352 报文。然后每对 Y / C 数据流经过一个数据流处理模块,该模块可以进行进行行号插入和 CRC 生成及插入。在流处理之后,数据流被 MUX 交织,形成 40、20 或 10 位宽的多路复用 SDI 数据流。然后,由 SDI 加扰器对多路复用的数据流进行加扰。最后,数据在 tx_txdata 端口上输出到对应的串行收发器。
4进4出的SDI接口
SDI相机
SDI转HDMI盒子
输出效果
毕竟是3G-SDI,效果还是很清晰的。。。
福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:私,或者文章末尾的V名片。
网盘资料如下: