在去年的一个视频处理类重点项目中,需要使用到一个15-20倍左右的视频编解码算法,同时处理处理延迟有比较严苛的要求,整系统的处理延迟要控制在10ms以内。基于这个需求,陆续调研了JPEG、JPEG XS、VC-2、TICO等浅压缩算法,最终发现JPEG2000是比较符合预期的。其它几种算法主要是在压缩倍数方面不符合预期,例如JPEG的压缩倍数在10倍左右,JPEG XS的压缩倍数在6倍左右,超过这个范围画质会急剧下降;而JPEG2000可以在20倍压缩情况,达到视觉无损的效果。当然,为了达成这种效果,代价也是很明显的,JPEG2000需要采用DWT做数据处理,在相同处理性能的情况下,整个IP的资源占用是接近JPEG XS的1.5倍。
先简单介绍一下JPEG2000算法。JPEG2000的正式名称为ISO15444。它是由ISO/IEC JTC 1 SC29标准化小组负责制定的新一代静止图像压缩标准。JPEG2000作为JPEG的升级版,其压缩率比JPEG2000高约30%;像JPEG一样,JPEG2000也同时支持无损编码和有损压缩,并且保持算法兼容。JPEG2000算法部分主要包括DWT离散小波变换、符号编码和MQ算术编码,其中无损编码采用的是5/3小波,有损编码采用的是9/7小波。JPEG2000还有渐进传输、感兴趣区域(RIO)等特性,这些特定设计之初的目的是为了在JPEG2000格式的图片在web上能够更快的传输。目前JPEG2000在高质量图像应用,例如彩页打印、数码相机中都有使用;其中最重要的应用之一就是数字电影规范(DCI)选定JPEG2000作为存储、传输标准。
在选定了JPEG2000作为浅压缩算法后,下一步就是去找市面上有没有JPEG2000的IP供应商。那有没有现成的JPEG2000 IP供应商呢?答案是有的,但不幸的是对方的一些规格不完全符合我们的需求。我们希望编码+解码的总延迟控制在10ms以内,但现有的IP总延迟在50ms左右,这个是我们完全没法接受的参数。因为我们产品的应用场景是浅压缩分布式视频系统,延迟参数是最关键的参数之一,延迟太大会导致鼠标移动的时候有人眼可感知的滞后感,体验感会很差,像我这样的暴躁老哥是忍不了的。另外一个重要因素就是资源问题,我们希望把一些不需要的特性做简化,降低资源使用率,但不幸的是我们能找到的仅有的两家供应商都是国外的,不支持按我们的需求进行定制。
既然买不到合适的,就只能自己造了,就当是为国产化JPEG2000 IP做贡献了。在开始开发之前,我们其实已经做了大量的准备工作,对JPEG2000的原理,以及开源的参考软件都已经做了比较深入的解读,但实际开发的时候还是遇到了大量的困难。下面先贴上JPEG2000的算法框图:
从代码开发工作量的角度,工作量最大的是DWT/IDWT、熵编码(符号编码和MQ算术编码)以及码率控制。整个IP编写代码花的时间占比大约为1/4,1/4的时间用在了仿真以及跟软件对比算法数据,另外大约1/4的时间用在了代码优化(资源优化和时序优化),最后1/4的时间用在上板debug。当然,上面提到的工作并不是串行的,事实上是我们用比较快的时间就写出了个雏形,然后又不断的优化架构然后重新仿真以及debug,为了在我们的目标器件上放下JPEG2000 编解码IP,我们前后迭代了4个大版本,才达到最终比较理想的状态。在这个过程中,不断的重复着写代码、仿真、代码优化、上板调试,混杂在一起。
挑几个比较难受的点,让大家感受下FPGA工程师的苦难。对着仿真波形,检查计算精度误差,是个费时又费眼睛的过程,真是差点把眼睛看报废;为了平衡逻辑资源以及对DDR4内存带宽的占用率,顶着进度压力,将调好的版本推倒其中的1/3,重新规划数据流程;MQ计算过程中,因为前后级计算之前的串行性,无法将复杂的组合逻辑拆分,导致逻辑级数太大时序无法通过,为了优化这部分的时序,不断的迭代,花费巨大的时间精力将时序问题修复。 虽然过程比较曲折,最终的结果还是比较完美的。经过团队的不懈努力,最终还是把JPEG2000完整的实现了,并且还结合我们的应用场景,做了一些优化。下面是我们最终IP的技术规格:
性能:4K@60fps(3840x2160)
支持的颜色空间:RGB、YUV444、YUV422
延迟:端到端8.5ms(HDMI输入-编码-网络传输-解码-HDMI输出)
压缩率:4%-100%,即1-25倍的压缩效果,支持动态切换
支持码率控制,最终压缩率跟设置的压缩率误差小于1%
支持3级9/7小波
支持的色深:8-10-12
CB size:64x8
支持多路视频同时解码
编码后的文件格式是私有格式(为了减少延迟)。
其中,低延迟特性是我们IP的关键特色,在保证高画质的前提下,不足一帧的延迟,比同类浅压缩算法实现要小几倍。在与JPEG2000规范保持兼容的前提下,我们的IP实现更适用于在对延迟要求比较敏感的应用场景中(例如KVM)。更详细的技术规格可以移步到我司官网:北格逻辑 。 额外提一句,JPEG2000的有损压缩算法性能指标优异,但无损编码效果确不如JPEG-LS,且FPGA资源使用量偏大,所以我们在选择无损编码算法时,并没有选择JPEG2000,而且基于JPEG无损算法和JPEG-LS的基础上,自研了一套自己的无损算法,用很小的资源使用量,就能实现4K@60fps的无延迟实时编码了,且平均压缩倍数可以达到2.5倍左右。当前,这是另外一个故事了。
原文链接:JPEG2000 FPGA IP开发后记 - 知乎 (zhihu.com)