技术文章

了解最新技术文章

当前位置:首页>技术文章>技术文章
全部 5 常见问题 0 技术文章 5

H.2 ** Concepts and Methods

时间:2022-09-30   访问量:1104
简介

  Video CODEC 中文称为视频编解码器,分为编码器(encoder)和解码器(decoder)两部分。编码器的任务是压缩原始视频以便于存储和传输,而解码器的任务是从编码比特流中恢复原始视频播放。下图显示了编码器和解码器的典型应用场景。

  视频压缩是数据压缩的一个子方向,因此也适用于数据压缩的基本原理。广义的数据压缩可分为无损和有损。

无损压缩(lossless compression)主要采用数据统计冗余进行压缩,可以在不造成任何失真的情况下完全恢复原始数据,但压缩率受数据统计冗余的理论限制,一般为2:1至5:1。该方法广泛应用于文本文件、程序文件、特殊图像数据(如指纹图像、医学图像等)的压缩。有损压缩(lossy compression)主要利用人类对图像或声波中某些频率成分不敏感的特性,允许在压缩过程中丢失某些信息;虽然原始数据不能完全恢复,但损失的部分对理解原始图像的影响更小,但压缩比要大得多。语音、图像和视频数据的压缩广泛应用于有损压缩。

  压缩比的定义是输入数据与输出数据字节数之比。在视频压缩领域,每个编码器都规定了支持的输入数据格式YUV格式最多。

  评价图像质量损失的主要参数是峰值信噪比(Peak Signal-Noise Ratio, PSNR)基于均方误差的指标(Mean Squared Error, MSE)公式如下。

  图像质量评价标准:

  视频信息之所以有大量的压缩空间,是因为有大量的数据冗余。主要类型有:

空间冗余:视频帧内的相邻像素在颜色或结构上有相似的时间冗余:相邻的两帧内容相似,或运动匹配系统计冗余:编码视频后,不同码字的概率是不同的视觉冗余:人类视觉系统对视频中不同部分的敏感性不同(temporal do ** in)与空域(spatial do ** in)的概念

  针对这些不同类型的冗余信息,在各种视频编码的标准算法中都有不同的技术专门应对,以通过不同的角度提高压缩的比率。

刘斯宁:视频压缩和编解码的基本原理

  对称性是压缩编码的另一个关键特征。

对称压缩(symmetric compression)这意味着压缩和解压所需的计算能力和时间大致相同,主要适用于视频会议等实时压缩和传输视频的场景。在另一个应用场景中,视频制作是单独进行的,没有立等要求,因此可以采用不对称压缩(asymmetric compression)意味着压缩和解压缩所需要占用的算力和时间相差很大。在电子出版和其他多媒体应用中,视频压缩是一个单独的生产环节,制作人可以使用专业硬件操作非常复杂的算法压缩,在保持视频质量的前提下获得高压缩比,解压缩操作环境可能是手机计算能力较弱的嵌入式设备,或者必须同时解码服务器,解码需要确保实时性,所以解压缩的算法必须相对简单。

  图像压缩编码的技术维度:

  基于像素块的混合编码器方案一般采用主流的图像编码技术,包括:

宏块划分( ** croblock partition);编码和量化的转换(transform coding & quantization);运动估计和运动补偿(motion esti ** tion & motion compensation);熵编码(entropy coding)。H.2 ** 概述

  H.2 ** 是由ITU-T和ISO/IEC的联合开发组共同开发的国际视频编码标准。严格地讲,H.2 ** 标准是属于MPEG-四个家庭的一部分,即MPEG-4系列文档ISO-14496的第10部分也叫MPEG-4 ** C(H.2 ** )。同MPEG-4不同的灵活性和交互性,H.2 ** 强调更高的编码压缩率和传输可靠性,广泛应用于数字电视广播、实时视频通信、网络流媒体等领域。

  

  尽管网上介绍H.2 ** 有很多信息,但很少有人提到严格意义上的重要和关键事实H.2 ** 标准围绕解码器展开:H.2 ** 标准文件规定了二进制码流的语法结构和解码器在分析各种语法元素时应遵循的行为标准。它可能不同于许多人的直觉,H.2 ** 标准文档没有规定编码器的具体实现方法,所以每个制造商都可以根据自己的实际需要灵活地实现编码器。只要最终输出的二进制码流符合语法规定,标准解码器就可以正确解码。由于H.2 ** 该标准不规定编码器的具体行为,因此不能保证编码的质量,在这个问题上给各厂家留下了很大的竞争空间。下图说明了这个想法。

  在上图中,在图像开始编码之前可能需要一些预处理,通常需要预处理

调整格式,将RGB/YUV输入格式转换为编码器所需的YUV420格式;分辨率调整,通过硬件scaler将标准分辨率的图像缩放到所需的分辨率转图像(rotation/mirror/flip),图像的方向通过硬件调整(orientation)和镜像;降噪(noise reduction),通过硬件noise filter去除图像中的随机噪声;锐化(sharpen),降噪后图像细节会丢失,需要使用sharpen filter提升细节;OSD,在图像上叠加文本或logo;

  图像解码后得到YUV在某些情况下,420格式图像需要后处理,常见的后处理需求通常是

调整格式,将YUV420转换为其他格式;增强图像质量,包括gam ** , contrast, saturation, sharpen等操作;

  下图显示了编码器和解码器的内部功能框图。

  

  在有损无损维度上,H.2 ** 它是一种支持高压缩比的破坏性压缩算法。H.2 ** 支持输入视频格式YUV420、YUV422和YUV444,支持8bit和10bit位深,但具体选项和H.2 ** 规定的Profile有关。H.2 ** 共规定了四种配置规格(Profile),即

Baseline Profile, 缩写是 BPMain Profile, 缩写是 MPExtended Profile, 缩写是 XPHigh Profile, 缩写是 HiP,支持Fidelity Range Extensions (FRExt)

  各种Profile建议应用领域如下。

Baseline Profile (BP): Pri ** rily for lower-cost applications with limited computing resources, this profile is used widely in videoconferencing and mobile applications.Main Profile (MP): Originally intended as the ** instream consumer profile for broadcast and storage applications, the importance of this profile faded when the High profile was developed for those applications.Extended Profile (XP): Intended as the streaming video profile, this profile has relatively high compression capability and some extra tricks for robustness to data losses and server stream switching.High Profile (HiP): The pri ** ry profile for broadcast and disc storage applications, particularly for high-definition television applications (this is the profile adopted into HD DVD and Blu-ray Disc, for example).High 10 Profile (Hi10P): Going beyond today's ** instream consumer product capabilities, this profile builds on top of the High Profile adding support for up to 10 bits per sample of decoded picture precision.High 4:2:2 Profile (Hi422P): Pri ** rily targeting professional applications that use interlaced video, this profile builds on top of the High 10 Profile adding support for the 4:2:2 chro ** subsampling for ** t while using up to 10 bits per sample of decoded picture precision.High 4:4:4 Predictive Profile (Hi444PP): This profile builds on top of the High 4:2:2 Profile supporting up to 4:4:4 chro ** sampling, up to 14 bits per sample, and additionally supporting efficient lossless region coding and the coding of each picture as three separate color planes.

  各Profile支持的特征差异如下图所示。

  如果上图太详细,下图是简化版。

  W,很多中文资料都会Profile翻译成等级,其实这个翻译并不是特别准确,因为听起来有些高低贵贱的感觉。某字典对Profile一种解释是关于人或事的信息,useful infor ** tion about ** /sth so that you can give a description of them or it”。在英语语境中,Profile 这意味着描述一个人或一个企业的一般情况,例如"company profile"可以翻译为企业概况,一般会介绍企业做什么主营业务,规模如何等等。在H.2 ** 的语境中,Profile 事实上,这也意味着概况和概况,这意味着支持哪些特征,适合哪些应用领域,但更适合正式将其翻译成配置或规格。

  主要用于消费领域BP,它可以翻译成基线配置YUV420 8bit 输入格式。YUV420是在YUV以444为基础的降采样结果,通过降采样可以降低编码器的带宽压力,代价是部分视频质量的损失。其理论基础是,人类视觉系统对颜色的空间分辨率弱于亮度分辨率。如果一些颜色信息被悄悄地切断,人眼就不容易察觉。以日常消费为主要场景BP配置,YUV一般认为420提供的视频质量是足够的。下图显示了四种用途H.2 ** 配置组合(HP/MP & 熵编码)编码同一视频序列时图像质量的差异,可以看到1的最大差异dB左右。

  1080制作高清电影视频类型的应用场景P视频码率的分辨率一般控制在10Mbps左右,此时H.2 ** 典型的压缩率约为100~200。1080安全视频监控场景P视频的码率一般控制在2~4Mbps,此时压缩率可以达到200~500倍以上。下图显示了过去及未来的主流编码技术对1080P视频进行高质量编码时码率的演进情况。

  在对称非对称这个维度上,H.2 ** 是一种非对称压缩算法,编码器的算力消耗大约是解码器的5-10倍,这一般意味着10倍的时间、功耗、芯片面积、CPU占用等指标,或者简单概括就是10倍的算力成本。一般来说,在编码阶段消耗的算力越多,编码器能够识别并去除的信息冗余就越多,编出的二进制文件就越小,并且视频质量也越好。H.2 ** 解码器的工作则相对简单,只要按照码流中提供的指令进行视频重建即可,因此解码阶段消耗的算力基本正比于码流大小,而且通常会显著低于对称压缩算法的解码器。下图显示了MJPEG和H.2 ** 解码器的CPU占用率对比情况。

  H.2 ** 的编解码器可以以各种算力平台为载体,例如

通用CPU,典型的如Intel x86 系列CPU,支持MMX、SSE等指令集加速,软件可以使用开源的FFMPEG软件库;GPU,如NVidia系列GPU,厂家支持GPU编解码驱动软件;DSP,如TI DM ** 2等,为视频应用设计的DSP一般提供专用的向量运算指令集,厂家提供参考源代码;嵌入式CPU,如ARM Cortex 系列CPU,支持NEON指令集加速,软件可以使用移植版本的FFMPEG;FPGA平台,如Xilinx Spartan 系列FPGA,很多厂家在FPGA平台上实现了定制化的H.2 ** 编解码器,有些是设计的目的是服务于ASIC设计验证,有些是将编解码器设计作为独立的IP产品出售,有些则是将编解码器作为一个模块集成在更高层次的产品中;ASIC平台,如安防领域的Hi3516系列Camera SoC芯片,集成了H.2 ** 编解码器设计;混合平台,使用MCU+ASIC的方式,将部分算法硬化为ASIC设计,另一部分算法以软件(固件)的形式运行在MCU上,以保持灵活的算法升级能力。

  CPU、GPU、DSP 是典型的通用计算平台,在执行任何任务时,都需要消耗大量的能量在取指、解析、执行命令上,并且指令和数据的并行化程度一般不高(除了GPU)。相比之下,FPGA和ASIC 是典型的专用计算平台,通过专用的硬件设计可以实现很高的数据平行度,也不需要在取值、解析命令上消耗资源,所以计算的效率高,可以用较低的主频实现很大的算力。

  由于产品形态、运行环境差异巨大,厂家在实现编解码器时需要根据平台的技术特点和产品的规格需求对编解码器的功能进行取舍。尤其是对于算力、功耗约束较大的嵌入式计算平台,很多时候需要选择性地不支持某些高级特性(feature),以减轻算力成本的压力。

  解码器类产品还需要面临一个特殊的问题,如果解码器只需要支持有限几种编码器,并且这些编码器的特性是已知的,则可以放心大胆地裁掉这些编码器不会用到的语法特性。但如果解码器是作为通用产品设计的,需要配合市场上可能遇到的任何非特定编码器,则解码器必须做成全功能的产品,既支持H.2 ** 标准所规定的所有功能特性,并且需要具备严格的容错设计。如前所述,H.2 ** 标准并未明确规定如何处理码流中可能出现的错误,所以容错问题只能依靠厂家自己进行设计和。考虑到码流中的任何一个位置都存在出错的概率,以及近乎无穷多种的出错模式组合,容错设计既是一个开放的问题,也是一个繁琐复杂的问题,厂家需要保证解码设备在任何情况下都不能死机,这个需求往往是解码器类产品的最大挑战所在。

H.2 ** 工具

  JM代码是ISO和ITU官方提供的H.2 ** 编解码器参考模型,由德国HHI研究所实际开发,项目起始于2002年。JM中的J代表联合专家组(Joint),而M代表参考模型(Model)。JM代码实现了H.2 ** 的所有特性,因此几乎所有的学术研究都是在JM代码的基础上实现,并与JM的结果进行比较。JM代码结构冗长,编码复杂度高,一般认为其适合对H.2 ** 标准进行学习和研究,但不太适合工程应用。

** 是网上自由组织联合开发的兼容2 ** 标准码流的编码器,项目起始于2004年,创始人是法国巴黎中心学校(Ecole Centrale Paris,ECP)某研究中心(Centrale Réseaux)的一群学生。X2 ** 的特点是注重实用,引入了很多MMX、SSE等汇编指令提高编码速度,在网上口碑极佳。和JM相比,X2 ** 在不明显降低编码性能的前提下,努力降低编码的计算复杂度,放弃了H.2 ** 标准中一些对编码性能贡献微小但计算复杂度极高的特性,如多参考帧、帧间预测中不必要的块模式、CABAC等。

  Elecard公司成立于1988年,致力于提供编码、解码、过程处理、不同格式视频和音频数据的接收和传输软件(MPEG-2,MPEG-4,H.2 ** / ** C, MJPEG2000等)。Elecard是首批开发H.2 ** / ** C压缩标准视,其MPEG-2 解码器被认为是全球最好的解码器之一。

  Elecard Stream Analyzer 是一款专业对流媒体编码语言进行分析的视频解析工具,用于对流媒体编码语言进行解析并转换成可读的分析日志,可以帮助分析正常和异常码流之间的区别。Elecard StreamEye 用于对编码视频的可视化表现,码流结构分析等。

  

H.2 ** 设计思想

  数据格式

  在计算机领域最常用的颜色模型(color model)是RGB模型,它可以通过.601或.709公式转换成YUV颜色模型。RGB转成YUV后每个颜色点仍然具有三个分量,称为YUV444格式,再此基础上进行降采样后可以得到YUV422或YUV420数据格式。下图所示的是几种YUV格式的采样方法。

  

  如前所述,H.2 ** BP 配置支持YUV420数据格式,HP 配置支持YUV422和YUV444数据格式。

  下图举例说明了从RGB彩色图像中按照YUV420格式提取三种颜色分量的结果。

  

  帧内结构

  H.2 ** 处理编解码任务的基本单位是宏块(Macroblock,MB),每个宏块由16x16共256个像素构成,每个像素由Y,Cb,Cr三个分量构成。由于 BP 配置采用YUV420格式,所以每个宏块有256个Lu ** sample, ** 个Cb sample,以及 ** 个Cr sample。每一对(Cb, Cr)值需要被邻近的4个Lu ** sample共享,如下图所示。

  H.2 ** 将三种颜色分量组织成三个数据块,在编码时会按照Y,Cb,Cr的块顺序分别进行处理。

  H.2 ** 在编码过程中会按照一定标准对宏块做进一步切分(partition),以寻找最合理的切分方式,使最终的码流比特数最少

  H.2 ** 支持将输入图像划分为若干个切片(Slice),每个切片由整数个宏块组成。切片设计的主要价值在于控制错误传播。H.2 ** 规定一个切片内的数据只能引用本切片内部的数据,不可以引用其它切片的数据,这个规定可以将码流错误控制在一个切片以内,不会传播到整个图像中。

  因为支持切片需要增加逻辑,引入成本,所以某些编码器支持最多4个切片。最简单的情况是将整帧图像当作一个切片,这也是很多低成本编码器的首选方案。

  在某些场景下,使用更多的切片将有助于提高视频系统的实时性。典型的编码器会在完成一个切片编码之后发出一个硬件中断信号通知软件数据READY。如果只使用一个切片,READY信号是在一帧图像处理完成后发出。如果使用4个切片,则每编完1/4图像就会发出一个信号,于是软件就可以与硬件进行并行操作,编码器继续编码剩余的切片,软件则开始处理已完成的切片,这有助于改善系统的响应延迟(latency)指标。

  对低延迟话题感兴趣的读者可以参考这篇文章。

刘斯宁:Low Latency Camera Concepts

  

  帧序列结构

  H.2 ** 在顶层结构上将若干个图像帧组织成一个图像序列(sequence),每个序列作为一个编码周期,通常会包含一个或多个图像组(Group Of Pictures, GOP)。H.2 ** BP 配置支持两种类型的图像帧,即I帧和P帧。I帧依靠自身携带的数据就能解码,但是P帧必须引用某个I帧或P帧的数据才能解码。一个GOP由一个I帧和若干个P帧构成,如下图所示。

  每个序列通常会从一个序列参数集(SPS)和一个图像参数集(PPS)这两个语法结构开始,有时还可能跟随一个可选的SEI语法结构,然后就是一个接一个的slice语法结构(H.2 ** 没有引入frame级的语法结构)。

  理论上一个序列可以包含无穷多个GOP,换句话说,一部2个小时的电影可以封装到一个序列里。但实际上很少这么做,主要的考虑是万一SPS、PPS发生数据错误则整个序列都无 ** 确解码,或者很多解码器需要跳过片头,从码流中间某个位置处开始解码,所以需要每隔几个GOP就插入一个SPS/PPS。

  下图比较完整地显示了sequence->GOP->frame->slice->MB->sub-MB的层次结构。

  H.2 ** 编码器在对一帧图像进行编码之前,编码器需要知道这一帧应该是编成I帧还是P帧。一般惯例是,用户或者代表用户的软件需要为编码器设置一个GOP参数(如下图所示),这个参数决定了一个序列中两个I帧之间的间隔,编码器根据GOP参数决定下一帧是I帧还是P帧。

  下图所示的是一种最经典的H.2 ** 帧序列结构,可以认为GOP=4,每个GOP包含1个I帧和3个P帧。I帧凭借自身数据就可以解码,而P帧必须引用前一帧的数据。

  由于P帧的很多数据是从参考帧上直接 ** 过来的,在码流中传输的只是数据源在参考帧内相对当前宏块位置的坐标,并非传输数据本身,所以P帧的压缩比通常远大于I帧。从低码率的维度上看,图像序列中P帧越多越好,即GOP值越大越好。但在实际应用中还需要考虑误码因素,码流中一旦产生错误,只有I帧才能使解码器从误码状态中恢复出来,因此在I帧到来之前用户会看到画面一直存在撕裂伪像(tearing artifact),这是用户难以接受的图像质量问题。从这个意义上说,GOP值也不是越大越好。在安防监控场景中,习惯上设置GOP=22~50,即大约每秒或每两秒必须编一个I帧,以支持尽快纠错的目的。在制作影视节目时,则可能会设置每20秒编一个I帧,以尽量降低码率。

  除了使用已配置好的GOP参数之外,很多时候用户会需要编码器临时输出一个I帧,因此编码器的驱动软件会对上层应用暴露一个形如RequestKeyFrame的API接口,用户通过调用这个接口通知编码器尽快输出一个I帧。

  有一种特别的I帧被定义为IDR帧(Instantaneous Decoder Refresh),它被赋予了特定的功能,即通知解码器新的周期已经开始,后续将要到达的帧不会再参考IDR帧之前的任何帧。当解码器接收到一个IDR帧时,它会立即清空本地的历史帧缓存,准备开始一个新的解码周期。

  I帧与IDR帧的关系是:IDR帧一定是I帧,但I帧不一定是IDR帧。一个序列允许包含多个I帧,但是序列的第一个帧必须是IDR帧。在最典型的一种序列结构中,一个序列只包含一个GOP,即只有一个I帧,此时该I帧必须被标记为IDR帧,否则可能会导致解码器出错。

  

  码流结构

  在编码器输出的二进制码流中,码流的语法结构也是遵循Sequence/Slice/Macroblock的层次结构。下图显示的是图像序列的层次结构与码流语法结构之间的映射关系。

  H.2 ** 解码器的工作原理可以理解为一个有限状态机(Finite State Machine, F ** ),解码状态机在复位后,会首先从输入码流中提取slice层级的语法结构,这个层级包含SPS, PPS, SEI, slice 等语法结构。如果命中某个语法结构,则进入解析该语法的下级状态机进行处理。

Sequence 结构

  关于SPS,PPS的内容可参考

DaveBobo:H2 ** 码流中SPS PPS详解

  以slice语法结构为例,slice状态机首先会从码流中提取slice_header,解析出关于slice的各种参数,然后进入slice_data状态机,对各个宏块进行处理。

Slice 结构

  与slice语法结构类似,MB状态机会从码流中提取MB_header,解析出关于MB的类型和预测模式等信息,然后提取宏块编码数据,按照刚刚提取的参数进行解码。

Macroblock 结构

  在码流不存在任何错误的情况下,每个状态机都可以丝毫不差地提取出自己需要的一部分数据,下一个状态机接手码流时会刚好遇到自己期待的header结构,一切都十分完美。

  然而,码流在磁盘存储和网络传输过程中,难免会遇到误码等情况,由于状态机对码流的提取决策是在解码过程中动态生成的,那么码流中的错误就很可能导致解码器下次取数据的长度发生错误,于是后续的状态机就和码流失去了同步(lost sync),如何从这种状态中尽快恢复出来是一个极富挑战的课题,除了图像质量方面的损失之外,如果状态机的容错逻辑设计不周,解码器还有可能陷入死锁状态无法自拔。目前来看,FFMPEG 媒体库在码流容错问题上做得比较好,这也是其广为流行的原因之一。

  

  DCT变换

  尽管一帧图像的内容可以千差万别,但是在宏块尺度上,组成宏块的像素在多数情况下是高度相似的,宏块的尺寸越小,像素的相似性就越大,下图说明了这个原理。

  这种相似性就是图像的空间冗余性质,借助一定的数学工具,我们可以将像素块数据提炼为少数几个参数,这几个参数所携带的有用信息与像素块是等价的,但是占用的存储空间却远远小于像素数据本身。这个数学工具就是频域变换和量化,在CODEC领域最常用的频域变换方法有K-L变换,小波变换(wavelet),离散余弦变换(Discrete Cosine Transform, DCT)。

  频域变换的将像素数据从空域变换成频率系数,量化的作用是根据需要裁剪掉高频分量,保留少数低频分量,同时图像失真(distortion)保持在可接受水平。下图显示了裁掉不同程度的高频分量后图像质量的变化情况,可以看出图像中裁掉大量高频分量后仍然不妨碍对图像内容的理解。

  H.2 ** 标准中采用的是Nokia和Microsoft联合提出的整数离散余弦变换(IDCT)方案,该方案设计了与传统DCT不同的变换核(kernel),通过精心的优化,该方案可以基于16位整数的加法和移位运算实现,不需要使用硬件乘法器。在运算精度方面,16位IDCT方案的PSNR指标在多数情况下比32位DCT方案略有提升,少数序列观察到几乎可忽略的精度下降。

  假设宏块大小为NxN,二维DCT使用类似傅里叶变换的方法将宏块的像素数据从空域(spatial do ** in)变换到频域(frequency do ** in),从而将原始图像数据分解成NxN个频率分量,每个分量是频率空间中一个基底的系数。

  DCT变换最大的优点在于,如果图像数据的相似度很高,则变换到频域后,频域参数的“能量”主要集中在低频部分,代表图像块的基本性质(平均亮度),而代表图像细节波动的高频分量则能量较小,或者说对图像质量的贡献较小。如果用户愿意接受一部分图像质量损失,则可以考虑抛弃一部分高频分量,节省该部分数据的编码。

  下图显示了二维DCT变换提取图像频率分量的原理。

  

  在上面的例子中,图像数据有8x8= ** 个,经DCT变换后绝对值大于1.0的系数只有9个,如果只使用这9个系数做InverseDCT变换,得到的图像与原始图像在质量上相差不大。显然,对9个系数进行编码所需的比特数会远远小于对 ** 个数据进行编码。如果用户愿意接受更大的图像质量损失,则待编码系数的数量还可以进一步减少。

  

  K-L变换

  K-L变换( Karhunen-Loeve Transform)是建立在统计特性基础上的一种变换,有的文献也称为霍特林(Hotelling)变换,因他在1933年最先给出将离散信号变换成一串不相关系数的方法。K-L变换的突出优点是去相关性好,是均方误差(MSE,Mean Square Error)意义下的最佳变换,它在数据压缩技术中占有重要地位。

  K-L变换虽然具有MSE意义下的最佳性能,但需要先知道信源的协方差矩阵并求出特征值。求特征值与特征向量并不是一件容易的事,维数较高时甚至求不出来。即使能借助计算机求解,也很难满足实时处理的要求,而且从编码应用看还需要将这些信息传输给接收端。这些因素造成了K-L变换在工程实践中不能广泛使用。人们一方面继续寻求解特征值与特征向量的快速算法,另一方面则寻找一些虽不是“最佳”但也有较好的去相关与能量集中的性能且容易实现的一些变换方法。DCT是最接近K-L的一种正交变换,而K-L变换常常作为同类变换方法的性能评价标准。

  

  量化 Quantization

  从数学角度看,DCT变换本身是可逆的,DCT变换与反变换的过程并不导致任何信息损失。但H.2 ** 显然是有损压缩(lossy),所以其信息损失不是发生在DCT变换环节,而是在DCT之后的量化环节,正是量化操作导致了图像信息不可逆的损失,并以此换来了很高的压缩比。

  在数字信号处理领域,量化是指将信号的连续取值近似为有限个(数量较少的)离散值的过程。

  量化器设计时将标称幅度划分为若干份,称为量化级,一般为2的整数次幂。把落入同一级的样本值归为一类,并给定一个量化值(code value)。量化级数越多,量化误差就越小,质量就越好。例如8位的ADC可以将标称输入电压范围内的模拟电压信号转换为8位的数字信号。

  在图像处理等技术中,前端设备取得模拟信号的采样值后,在开始数字处理之前需要对数据进行量化。量化后的数值与原来的采样值是有误差的,这个数值就是量化精度。量化精度是指可以将模拟信号分成多少个等级,量化精度越高,所采集到的信号与原始信号越近似,更能反应实际情况 。

  量化过程存在量化误差,在还原信号的D/A转换后,这种误差称为量化噪声。增加量化位数能够把噪声降低到无法察觉的程度,但随着信号幅度的降低,量化噪声与信号之间的相关性变得更加明显。

  H.2 ** 定义了一个QP参数(Quantization Parameter),该参数提供了52个量化等级,对应QP值0..51。

  在编码器内部实际使用Qstep参数用于队DCT参数Y进行量化

  H.2 ** 标准以表格的形式规定了Qstep与QP参数的对应关系,

  显然,QP 值越小量化精度越高,图像质量越好。在安防领域中,QP的典型取值范围经常是22~32。再小的QP会导致码率过大,再大的QP会导致图像质量不可接受。

  熵编码 Entropy Coding

  经过量化操作后,DCT系数绝对值变小,非零系数变少,有利于降低码流。

  下图显示了一个比较典型的例子,8x8的DCT分量经过量化后只存在少数的非零数据,如果使用特殊的Zigzag顺序读取这些数据,排在尾部的高频分量很多是零,从而不需要进行编码。

Zigzag 扫描顺序

  {7, -1, -1, 0, 1, 3, 1, 0, 0, 0, 0, 1, 0, 2, 2, 4, 3, -1, 1, 1, 2, 1, -1, 0, 0, 0, -1, 1, 1, 0, 3, 2, 2, 1, 0, 2, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0 ,0}

  以上数据在抛弃不需要编码的尾零(trailing zeros)后,剩下的数据可以根据统计特性进行高效的编码,称为熵编码。

  In infor ** tion theory an entropy encoding is a lossless data compression scheme that is independent of the specific characteristics of the medium. One of the ** in types of entropy coding creates and assigns a unique prefix-free code to each unique symbol that occurs in the input. These entropy encoders then compress data by replacing each fixed-length input symbol with the corresponding variable-length prefix-free output codeword. The length of each codeword is approxi ** tely proportional to the negative logarithm of the probability of occurrence of that codeword. Therefore, the most common symbols use the shortest codes.

  在信息理论中,熵编码是一种与介质无关的无损数据压缩方法。一种典型的熵编码方法是为每个输入数据中可能出现的符号(symbol)赋予一个特定的无前缀编码(prefix-free code)。熵编码器将输入数据的定长符号替换成变长的无前缀编码,每个码字(codeword)的长度大致上反比于该码字出现的频率,因此,频率最高的符号会使用最短的码字,以此实现数据压缩。

  H.2 ** BP 配置支持内容自适应变长编码(Context Adaptive Variable Length Coding,C ** LC),MP 配置支持基于内容的自适应二进制算术编码(Context-based Adaptive Binary Arithmetic Coding,CABAC)。

  H.2 ** PPS 语法结构中使用 "entropy_coding_mode_flag" 指示熵编码的类型。

  下面的链接介绍了C ** LC编码的具体流程。

H.2 ** / ** C Context Adaptive Variable Length Coding

  

  码率优化

  下图定性地说明了三种编码情况的码率变化情况。

  从图中可以看出,I帧占用的带宽远大于P帧,在极端条件下,差距可能达到甚至超过1000倍。

  下图显示了一种路面监控场景,在24小时内监控画面中运动区域占画面比例的变化情况。显然,从早9点到晚9点间是画面繁忙的高峰时间,这段时间由于画面运动引起的视频编码和存储压力较高。

  另外,上图中没有传递的信息是,从晚9点到凌晨5点这段时间内,由于低照度引起的画面噪声会给视频编码和传输带来较大压力,甚至会超过白天画面运动带来的压力。

  对软件设计者来说,H.2 ** 的这种码率波动特性为存储和带宽管理带来了很大的挑战,就和中国的春运对铁路运输系统带来巨大的挑战是一样的道理。对于存储来说,巨大的I帧需要巨大的缓存,而小的P帧只需要小的缓存,软件需要设计一套复杂的方案才能高效地对内存进行管理。对传输来说,巨大的I帧可能会瞬间占满可用的网络带宽,影响其它网络用户,而且会使码率预测和码率控制变得困难。因此,人们常常需要使用各种办法控制I帧的大小,一种主要的手段就是控制图像质量。

  QP是编码器控制图像质量的主要工具,H.2 ** 支持针对每个宏块设置一个QP值,以此为基础,编码器的驱动软件可以动态地为每帧图像的每个宏块配置一个不同的QP值,以最大程度地适应场景的实时变化,在图像质量和码率之间取得最好的平衡。

  一种流行的码率优化技术称为QP ** p,它可以有很多种具体的实现形式,一种基本的形式是用户预先将画面分割称MxN个网格,并为每个网格指定一个固定的QP值,其背后的思想是某些网格容易出现高价值的目标,应该使用很小的QP以保证图像质量,而其它网格几乎不可能出现高价值的信息,可以使用很高的QP以节约码率。

  H.2 ** 支持一种特殊的宏块即P_Skip宏块,也称COPY宏块。如果当前帧的宏块和参考帧里某一位置处的宏块像素几乎完全一致,则编码器可以将当前宏块编码为P_Skip宏块。这种宏块既不传输像素残差,也不传输运动矢量残差(MVD),因此编码效率最高。如果进一步分析,即使当前宏块和参考宏块并非完全一致,甚至是完全不一致,也并不妨碍编码器将当前宏块编为P_Skip,反正解码器是完全不关心图像一不一致这个问题的,只有最终用户才会关心。再进一步分析,如果该宏块的位置不是很重要,比如是画面的背景部分,则很多时候用户其实也并不太关心。因此编码器可以利用这个情况多编一些P_Skip宏块,对控制码率会很有帮助。尤其是当画面背景中存在随风飘动的植物枝叶时,如果不使用P_Skip技术,则这些背景植物的运动必然会消耗大量的比特位,并且可能会影响画面前景的编码质量。

  在某些应用系统中,编码器所在的芯片中存在ISP、NPU等图像处理单元,可以向编码器提供关于场景的一些结构化信息,比如背景静止信息、目标运动信息、人脸检测信息等,通过这些信息编码器可以更加准确地识别哪些区域是高价值的,哪些区域是低价值的,从而对宏块QP做出更及时、合理的调整,这会比使用预定义的QP ** p取得更佳的效果。

  图像质量优化

  研究表明,在码率一定的情况下,帧间预测的PSNR指标一般会高于帧内预测的PSNR,典型差异在2dB左右。这说明的原理是图像的时间冗余远大于空间冗余,在码率一定的情况下帧间预测可以支持更高的图像质量。

  关于GOP size的研究显示,对于大多数图像序列,GOP size 越大编码效率越高,相同码率可以支撑更好的PSNR。但是也存在例外情况,对于场景变化较多的序列,可能会出现PSNR指标随GOP变大反而降低的情况,如下图中的Ducks Take Off 序列。

  下图的例子说明了当场景突变时,使用P帧导致PSNR下降的原理:在场景发生切换时,相邻两帧之间几乎不存在时间冗余关系,所以各种帧间预测模式的SAD值都很大。如果编码器在编P帧(或者B帧)时只使用帧间预测技术,不使用帧内预测技术,则图像质量还不如编I帧。

  有人专门研究了这种情况下图像序列的PSNR-GOP关系,得到的曲线如下图所示。

  相关研究指向的结论是,对于场景变化非常复杂的序列,适当增加I帧数量(减小GOP size)有助于改善序列的整体质量。

  在某些应用中,网络带宽存在一定的富裕,可以允许系统中有一定比例的设备短期地超标占用带宽,以输出更好的图像质量。因此,有些编码器会支持一种S ** rt GOP 特性,它的主要功能是,当编码器检测到图像的重要区域(Region Of Interest, ROI)存在运动时,会自动启用一个临时的GOP参数,这个临时的GOP使用了更多的I帧,会显著提高图像的质量。

  尽管S ** rt GOP特性有助于在特定场景下提升图像质量,但是也有人建议避免使用这个功能,主要原因是兼容性方面的考虑,有些解码器在设计时就没有考虑GOP可能会动态变化的需求,所以用户在使用视频时可能会遇到解码故障。一种可能的场景是,用户的安防摄像机启用了S ** rt GOP功能,在发生事件后警方会将视频拷走,后续还会有检方、 ** 等部门需要播放此视频。这些部门使用的播放设备一般是不同供应商提供的,技术规格可能存在较大差别,所以容易出现兼容性问题。

  另有研究表明,QP 参数对I帧P帧图像质量的影响也是有所区别的,下图比较了相同序列使用I帧、P帧编码在PSNR指标上的区别。结果显示,P帧的PSNR受QP值变化的影响更大。

  H.2 ** 支持一种特殊的帧内编码模式,即I_PCM,在该模式下,编码器直接传输图像的像素值,而不经过预测和变换。在一些特殊的情况下,特别是图像内容不规则或者量化参数非常低时,该模式比常规的操作(帧内预测--变换--量化--编码)效率更高。

  I_PCM 模式允许编码器精确地表示像素值,避免编码和量化引入的图像质量损失。在某些极端条件下,如极高噪声、极低QP条件下,常规的编码方法可能码率很大,甚至出现压缩比反转(输出码率大于输入码率),此时可以使用I_PCM 模式,反而有助于控制码率。

  宏块大小

  JPEG标准将图像切分成最小编码单元(Minimum Coded Unit,MCU),每个MCU又按照Y、Cr、Cb分量分为若干个数据单元(Data Unit, DU)。数据单元的大小固定为8*8。

JPEG 8x8

  H.2 ** 将图像切分成宏块,每个宏块大小为16x16,在后续处理时可进一步分成子宏块。

  H.265将图像切分成编码树单元(Coding Tree Unit, CTU),CTU的大小为 ** x ** ,可以采用四叉数的形式递归划分成编码单元(Coding Unit, CU),CU大小可取8、16、32、 ** 。

H.265 典型 Coding Block 尺寸H.265 CTU 切分的四叉树结构

  一般而言,像素块尺寸越大块内图像的相关性越低,块内更容易包含两种不同的材质,或者两个不同方向的运动目标,这种像素块经过DCT变换后高频分量会较多,不利于降低码率。但是也有例外情况,在图像的平坦区域块内,大像素块的相关性也可以很高,编码效率就高,并且大的块尺寸可以减少总的块数量,所以大像素块在平坦区域优势很大。

  如果像素块尺寸小,则块内部像素相关性会高,在编码纹理细节丰富的区域时图像质量更好,但是总的块数量会很多,每个块都需要占用一个语法结构,消耗一定数量的比特位,所以不利于码率。另一个问题是,块尺寸越小,计算结果受噪声的影响越大,因此高噪声的图像容易出现选择错误。

  编码器在确定一个宏块的最佳切分模式时,主要的挑战在于无法事先预知当前区域是平坦的还是纹理的,只有将各种切分可能性全部试过一遍之后才能知道,所以像素块尺寸选项越多,消耗的算力也就越大,计算成本就越高。所谓天下没有免费的午餐,编码效率的提升只能是以算力消耗为代价的,效率越高的算法必然意味着算力需求越大。这也是为什么JPEG只支持一种块尺寸,H.2 ** 支持4~16,而H.265支持8~ ** 的主要原理。

  

  省点是点

  H.2 ** 需要使用三种整数DCT变换核(kernel),如下图所示。

  H.2 ** 对16x16的亮度宏块进行编码时,将其切分为16个4x4的子块,并对每个子块单独进行整数DCT变换(使用H1 kernel),变换之后会得到16个直流分量,如下图所示。

  只要稍加思考就会注意,这16个直流分量其实是存在很强的统计关联性的,利用这个特性我们可以进一步去除统计冗余减少码率。H.2 ** 标准将这16个分量排成一个4x4大小的像素块,对这个特别的像素块进行4x4 Hada ** rd变换(使用H2 kernel),再经过一次量化之后,有很多参数变成0不需要编码了。

  H.2 ** 对8x8大小的色度宏块进行编码时也采取了同样的方法,将Cb/Cr色度数据切成4个4x4大小的块,分别进行整数DCT变换,然后将直流分量提取出来,组合成2x2大小的DC块,每种色度需要进行一次2x2 Hada ** rd变换(使用H3 kernel)。

  

  这种省点是点的思想在H.2 ** 标准中得到了充分的应用,它不仅适用于处理像素块的直流分量,还适用于处理像素块的预测模式,只要块与块之间存在某种统计关联,就可以将这些关联数据合并起来进行处理,将主要信息集中到几个低频参数中,通过抛弃高频小信号进一步去除信息冗余。

  研究表明,4x4大小的像素块的最优预测模式与周围像素块的预测模式的相关度符合“上方>左方>右上方”规律,最优预测方案约有62%的机会产生于这三个预测模式之中。

  

  预测编码

  预测编码的思想是根据离散信号之间存在着一定关联性的特点,使用前面一个或多个信号的值来预测下一个信号的值,然后将实际值和预测值做减法得到误差,实际对误差进行编码。如果预测比较准确,误差就会很小。在同等精度要求的条件下,可以用比较少的比特进行编码,从而达到压缩数据的目的。

  在视频压缩技术中,“预测”指的是在当前像素块周围相邻的一些像素块中找出(或者用一定的方法构造一个)与待编码数据最接近的像素块。这里“相邻”可以是空间意义上的相邻也可以是时间意义上相邻。实际像素块和预测像素块之间的误差一般称为残差(residue),预测编码的主要工作是对残差进行编码。

  在预测过程中,编码器需要选择某种定量的标准以度量残差的大小,最常用的度量标准有SAD,SSD等。SAD是对像素误差的绝对值进行累加(sum of absolute difference),而SSD是对像素误差的平方进行累加(sum of squared difference)。

SAD原理

  SAD,SSD这两个指标主要考虑了视频质量的损失(distortion),但有时编码器也需要考虑预测模式对后续码率(rate)的影响,很多时候令SAD/SSD指标最优的预测模式不一定保证码率也是最优的,因此H.2 ** 编码器引入了RDO算法(rate distortion optimization)以更好地平衡视频质量和码率的关系。RDO的原理是寻找一个目标函数J 的最小值,J 定义为

  预测编码可以用于处理视频中的时间和空间域的冗余,分别对应H.2 ** 中采用的帧内预测和帧间预测技术。

  帧内预测

  在消除空间冗余方面,H.2 ** 支持帧内预测编码(intra predictive coding)。在对像素块进行预测时,只利用当前块左侧和上方已完成编码的像素值对待编码的像素块进行预测,如下图所示。

  帧内预测的压缩比一般不太高,与传统的JPEG算法相比有一定优势但并不特别显著。

  H.2 ** 标准中,用于帧内预测的像素块大小有16x16和4x4两种规格。针对16x16规格定义了4种预测模式,如下图所示。

  

  下面举例说明Intra16x16预测模式的使用原理。

输入图像的16x16宏块图像,待编码参考图像中对应宏块的四种Intra16x16预测模式,SAE最小的预测模式胜出

  H.2 ** Intra4x4 预测的思想是使用参考4x4像素块上方和左侧共13个相邻像素(编号A~M)对目标像素块进行预测,一共定义了9种预测模式,如下图所示。

  

  

  下面举例说明Intra4x4预测模式的使用原理。

输入图像的4x4子宏块,待编码使用参考图像的已存在像素进行Intra4x4预测,SAE最小的模式胜出

  对于宏块中色度值,分割方法是和是亮度一样的,但由于4:2:0的采样关系,色度块的大小是亮度块的一半。每个帧内编码宏块的8×8色度成分由已编码左上方色度像素预测而得,两种色度成分使用同一种预测模式。

  色度块的4种预测模式非常类似于Lu ** 块的Intra16×16预测预测模式,即

DC(模式0)水平(模式1)垂直(模式2)平面(模式3)

  对比Intra16x16模式发现,色度块的预测模式只是将编号顺序调整了一下,将更短的码字赋予出现频率更高的模式,这有利于节约码率。

  上述17种预测模式(加上I_PCM)是H.2 ** 标准支持的全集,但有些预测模式对某些特定坐标位置处的像素块并不适用。举个极端的例子来说,位于图像左上角的第一个16x16像素块,它既没有源于左侧的参考像素,也没有源于上方的参考像素,因此H.2 ** 规定这种情况下,DC预测模式所有256个预测值都固定采用128。

  模式概率

  研究发现,在典型的QP范围(20~35)内,编码器采用Intra4x4模式的概率显著大于采用Intra16x16模式的概率,如下图所示。

  根据这个图可以得到的结论是,在正常PQ范围内,如果强制使用Intra16x16预测模式,不使用Intra4x4预测模式,则在PSNR和码率方面会有一定的损失。

  

  MPM

  MPM=Most Probable Mode,即最可能的预测模式。考虑到同一宏块内不同子块的预测结果(Mode)有较大概率会存在某种程度的关联,H.2 ** 还提供了相应的语法以利用这种统计关联进一步提高编码效率,基本思路是根据已获取的Mode值预测下一个Mode,如果预测命中,则可以用更少的比特数来编码这个事件,而不需要对每个Mode本身进行编码。

  

  帧间预测

  在消除时间冗余方面,H.2 ** 支持帧间预测编码(inter predictive coding),这是面向单张静态图像压缩的算法(如JPEG)所不具备的特性,可以实现很高的压缩比。

  帧间预测的主要思想是以像素块为基本单位,在本地缓存的最近几个历史参考帧中挑选与当前像素块最接近的历史像素块,这个过程称为运动估计(motion esti ** tion)。运动估计的结果是输出一个参考帧编号和一个运动向量(motion vector),根据这些信息可以将参考像素块 ** 出来作为当前像素块的预测值。其原理如下图所示。

  H.2 ** 规定解码器最大需要支持16个历史参考帧。研究显示,使用5个参考帧比只用1个参考帧码率可减少5~10%。当然,效率的提升是以增加算力成本为代价的,所以绝大多数基于硬件的解码器最大支持3~4个参考帧,再多就会引起解码困难或者干脆拒绝服务。很多算力有限的嵌入式编码器则只支持1个或2个参考帧。下表显示了编解码速度和参考帧数量之间的关系。

参考帧数量编解码速度备注1very fast2fast3medium4slow and abovefor blu-ray; constrained by level 4.1 and resolution5slow8slower16veryslowplacebo(安慰剂)实际没什么用处

  有些社会责任感不强的编码器并不会在码流中如实汇报自己需要使用几个参考帧,导致解码器不得不按照最坏的可能性去为码流分配解码内存,造成不必要的内存浪费。这是实际应用中经常会遇到的一种问题。

  运动向量的定义是参考帧中的匹配块(Candidate MB)相对当前块(Current MB)的相对坐标,一般将运动向量的方向定义成从当前块左上角像素出发到匹配块左上角像素截止,但是有很多资料会把运动向量的方向画反,比如下图这个。

注:本图箭头方向标反了MV的箭头方向以此图为准

  

  如果一帧图像只使用帧内预测技术,完全不使用帧间预测技术,则这帧图像称为I帧。当一帧图像既使用帧内预测技术又使用帧间预测技术,则这帧图像称为P帧。有些资料上会说P帧是只使用了帧间预测技术的帧,这个说法是不正确的。当一个像素块使用帧内预测的收益大于帧间预测时,编码器会毫不犹豫地选择对该像素块使用帧内预测(至少应该如此)。

  帧间预测不仅支持16x16大小的宏块,还支持对宏块进行切分(partition)成子块,每个子块可以独立进行预测。

  帧间预测支持将16x16大小的宏块切分成4种模式,其中一种是切成4个8x8子块,而一个8x8子块可以进一步切分出3种新的子模式,所以帧间预测总共支持7种预测模式,如下图所示。

  最复杂的一种情况是,将宏块切分成16个4x4大小的子块,每个子块在多个(例如4个)历史参考帧中搜索最匹配的像素块,理论上这样的搜索需要重复16x4= ** 次。当然,这种情况消耗的算力实在是太大了,在需要实时编码的产品中几乎没有人会这样设计,但是在制作影视节目的场景到也问题不大,反正是让编码服务器去慢慢找,慢点也可以接受。

  考虑到同一宏块内不同子块的预测结果(运动矢量,MV)有较大概率会存在某种程度的关联,H.2 ** 还提供了相应的语法以利用这种统计关联进一步提高编码效率,基本思路是根据已获取的MV值预测下一个MV,如果预测命中,则可以用更少的比特数来编码这个事件,而不需要对每个MV值本身进行编码。

运动估计 Motion Esti ** tion

  运动估计的意思是在指定的参考帧、指定的搜索窗口中寻找一个与当前像素块(Current Block)最相似的候选块(Candidate Block),并给出候选块相对当前块的运动矢量(Motion Vector, MV)。

  显然,待搜索的参考帧数量,以及搜索窗口的大小将直接决定搜索的算力需求,影响产品的成本,因此在设计编码器时,首先需要规划好计划使用的参考帧数量,并确定一个系统参数p,(N+2p)决定了搜索窗口的大小。

  搜索窗口大小确定之后,接下来就需要确定具体的搜索方法。一种最显然的搜索方法叫做Full Search Block Matching Algorithm(FSBMA),即全搜索块匹配算法,就是在这个已经确定大小的搜索窗口中进行逐块比较,采用遍历的方法寻找与给定像素块最匹配的参考块。

  对于消费类camera产品,视频中的运动物体一般速度都不快,一个原因是需求不典型,另一个原因是非专业的设备不具备捕捉高速物体的技术条件,所以p值可以定的比较小(7~15)。对于广播电视等专业级camera产品,一方面会经常需要捕捉高速运动的物体,另一方面需要在多个参考帧之间搜索匹配宏块,多帧意味着时间间隔拉大,所以物体的运动范围就更大,因此p值必须定的很大(47~49)。

  H.2 ** 支持以多种精度对ME搜索窗口进行搜索,以提高ME的精度,比如

整数像素精度,需要匹配像素位置 0,1,2,3,...;1/2像素精度,需要匹配像素位置 0, 1/2, 1, 3/2, 2, ...;1/4像素精度,需要匹配像素位置 0, 1/4, 1/2, 3/4, 1, 5/4, 3/2, 7/4, 2, ...;

  显然,亚像素位置的像素值需要按照规定的方法从整数位置处的像素进行插值才能得到。亚像素插值的工作原理如下图所示,其中红色块表示图像中的整像素点的位置,绿色块表示两个正像素之间的1/2像素插值的位置,紫色块表示1/4像素插值的位置。

  研究表明,使用1/4像素精度进行运动估计,图像的峰值信噪比指标(PSNR)可以提高1.3dB以上。

1/4像素精度QSAD VLSI方案

  运动补偿 Motion Compensation

  根据运动估计得到的MV值可以对宏块进行运动补偿,与输入宏块做减法后得到的残差块(residual block)能量更小,下面举例说明运动补偿的原理。

相邻两帧图像直接做减法得到的残差

  

使用MV进行运动补偿后再做减法得到的残差

  

  

  三步法ME

  整数像素ME方法可以找出一个令SAD值最优的整像素位置,从该位置出发搜索周围的8个1/2像素位置,可以找出令SAD值更佳的1/2像素位置,然后再从该像素出发,搜索周围的8个1/4像素位置,找出最终的ME像素位置。这个方法称为三步法,与整数像素ME方法相比,三步法增加了16次搜索,代价并不是特别大。

  接下来还需要解决一个问题,就是整数像素ME如何实现。关于这个问题学术界已经提出了很多种方法,其中最经典的一种是全搜索块匹配算法(FSBMA)。

  全搜索块匹配 Full Search Block Matching

  如果已知某1000万人口的大城市中,有一些人已经感染了某种病毒,现在想把这些人筛选出来,最有效的方法是什么呢?

  没错,准确率最高的办法就是全搜索(full search),暴力搜索(bruteforce search),无脑搜索(dumb search),穷举搜索(exhaustive search)。这些术语描述的都是同一个方法,就是一个像素一个像素地遍历,指导思想是不计成本,不放过一个,具体效果是一力降十会。下图以伪代码的形式描述了全搜索的计算流程。

  以N=16,p=12为例,搜索窗口的大小是40x40,如果只考虑整像素精度,则完成一个窗口的搜索需要计算25*25=625个SAD值,每个SAD值涉及256x2=512个加法,一个窗口就需要使用320K个加法操作,而一帧1920x1080分辨率的图像共有8100个这样的窗口,一共涉及2.6G个加法操作,对于一帧图像来说,这个运算量是相当巨大的。具体大到什么程度呢?假设一个CPU主频是2.6GHz,每个时钟周期可以完成一个加法操作,则处理一帧图像的ME就需要1秒钟。

  

  根据实验评测,一个典型的编码器可能会将超过80%的计算资源消耗在SAD和ME任务上。

  根据C. Y. Chen 等人的研究,当H.2 ** BP 编码器启用亚像素ME算法时,消耗在ME/MC上的算力更是高达97%以上。

  为了节省计算成本,有些编码器设计者会选择对搜索区域进行降采样,以减少搜索次数,但代价是牺牲一点匹配精度。但即便是使用了这些技巧之后,如何快速高效地完成搜索仍然是一个很有挑战的课题。于是,systolic array comes to the rescue!

  

  脉动阵列 Systolic Array

  脉动阵列其实是一个比较古老的概念,早在1982年就出现了。近些年随着AI的兴起,Google的AI加速芯片TPU(Tensor Processing Unit)采用了这个结构进行设计,于是脉动阵列模型又再次成为热点,吸引了广泛的关注。

  脉动阵列是一种经典的阵列式计算架构,这里脉动的意思是计算机的工作方式和过程(尤其是数据流动的方式)可以类比成人体血液循环系统的工作方式和过程。在这种特定的阵列结构中,数据在时钟“脉搏”的驱动下,按照确定的路径和方式在阵列的处理单元(Processing Element, PE)间有节奏地“流动”。在数据流动的过程中,所有的处理单元并行地对流经它的数据进行处理,通过增加PE的数量,系统可以取得很高的处理速度的吞吐率(throughput)。同时,预先设计好的数据流动模式可以使数据在完成一个工作循环后即完成了所有应做的处理,以后无需再次从存储器中回顾这些数据 ,这是对数据利用率最高的使用方式。另一方面,只有位于阵列“边界”处的处理单元负责与外界进行数据交互,接口逻辑清晰直观,计算方便,体现了“简单就是美”的设计哲学。以上种种方法实现了在不增加阵列机输入、输出速率的条件下,提高阵列机的处理速度。由于阵列和处理单元的结构简单、规则一致 ,可达到很高的模块化程度,非常适合超大规模集成电路(VLSI)的设计和制造。

  下图以一维脉动阵列为例显示了脉动阵列模型相对传统计算模型提高处理效率的原理。

  

  

  脉动阵列ME

  ME模块的整体架构一般需要包含数据存储单元、地址生成单元、处理单元、MV/SAD寄存器等功能模块,模块之间的关系如下图所示。

  下图显示的是使用一种经典的二维脉动阵列方案计算像素块的SAD值。图中左侧的FeedData模块可以理解为地址单元和数据存储单元的结合体,负责向阵列提供参考像素(Y)。在这个设计中,脉动阵列本身预先存储了当前像素块的值(X),FeedData 按照光栅扫描的顺序向阵列提供Y数据,理想情况下每个时钟周期可以输出一列Y值(N个数据),每次输出(N+2p)列数据之后自动触发回车和换行,下个时钟周期从下一行的首部继续提供数据,如此重复(2p+1)个循环,直到一个搜索区域遍历完成,中间不应该中断。

  在上图所示的脉动阵列结构中,数据在系统时钟的驱动下沿两个不同的方向流动,流动方向如下图所示。

  其中,参考图像的Y数据沿水平方向流动,每个时钟周期从PE的输入端(左)移动到PE的输出端(右)。|X-Y|的累加和则是沿垂直方向流动,每个时钟周期从PE的上端移动到PE的下端。

  每个PE的内部逻辑如下图所示。

  按照这样的设计,每个像素块的第一个数据Y(0,0)在t=1时刻流入PE阵列,之后沿着"L"形路径先向下再向右流动,途中不断地与其它像素产生的delta值进行累加,在48个时钟周期后得到一个像素块的完整SAD值,并在t=49时刻流入缓存最终结果的SAD寄存器。从t=49开始,每个时钟周期会有一个完整像素块的SAD值流入SAD寄存器,直到整个搜索区域完成,任务结束,整个过程共持续48+625个时钟周期,前48个时钟周期SAD寄存器的数据都是无效的(脏数据)。如果系统时钟频率是100MHz,则消耗的绝对时间是6.7us。仍以1080p图像为例,完成8100次搜索总共耗时54ms,虽然比1s已经好了很多,但仍然不满足30fps实时视频的要求。

  当一个设计方案面临性能不足的问题时,通常有两种可能的解决方案,一种是提高主频,代价是增加系统功耗,并且很多情况下潜力比较有限。另一种常用的方法是增加硬件实现乒乓操作,代价是增加面积成本,但理论上潜力很大。在上面的例子中,如果设计两个同样结构的脉动阵列,每次同时处理两个像素块,则主频不变的情况下完成8100次搜索总共耗时27ms,已经能够满足30fps实时视频的要求。

  需要注意的是,如果采用每次处理两个宏块的方案,那么编码器会要求图像的实际宽度(pic width)或者存储宽度(line size/stride)必须是32的整数倍。某些应用场景可能还存在最大分辨率与降采样分辨率(deci ** ted resolution)混合显示的需求,此时会要求图像宽度必须是 ** 的整数倍。

  对于同样的设计,如果需要支持4K分辨率,则可以考虑把主频提高到400MHz。如果需要进一步支持4K@60fps,则需要考虑把主频提高到800MHz。这个频率刚好是目前ASIC平台编解码器的典型频率等级。

  另一种设计方法与之类似,区别在于X数据(图中的c)并不事先存储在PE里,而是由一个单独的FeedData模块与Y数据(图中的r)同步提供,Y数据沿水平方向移动,每个时钟周期移动一个PE,垂直方向上既流动X数据也流动Delta(图中的AD代表Absolute Difference)。两种设计在功能上是等价的,但时序上存在一定的区别。

  本方案在时序上主要的特点是,X数据和AD数据在垂直方向上的流动速度必须是2:1的关系,即X数据每个时钟周期移动一个PE,而AD数据是每两个时钟周期移动一个PE。为了匹配这种时序关系,图中的每个*必须代表两个时钟周期的延迟才可以,这是串行移位方案所必须引入的延迟,看起来会比预先存储X数据的方案latency稍大一点点,但实际上也不一定,因为第一个方案在PE阵列内部存储X值的过程显然不可能是瞬间完成的,必然也需要消耗一定时间,因此两个方案总的时间消耗应该是相差不多的。

  树形结构 Tree-based Architecture

  树形结构也是VLSI中经常使用的计算结构,设计者可以例化N个并行的PE单元,每个时钟周期可以同时计算N个基础操作。根据芯片的面积预算情况,N可以选择4,8,16,256不等。如果选择N=256,则每个时钟周期可以完成一个16x16宏块所需的全部Delta运算,再经过8个时钟周期的累加运算后就可以得到该宏块的SAD结果。而完成一个40x40区域的搜索共需要8+625个时钟周期,比脉动阵列方案稍快一点点。

  与上述的脉动阵列方案相比,本例中的树形结构需要FeedData模块每个时钟周期提供256个Y数据,对存储Cache的要求更高。

  可变块尺寸ME

  H.2 ** 标准支持7种帧间预测模式,涉及7种预测块的尺寸。如果编码器需要支持全部7种块尺寸,则需要对前面的设计进行改进。一种思路是从大处着手,硬件单元原生支持16x16块模式,然后在PE阵列内部增加控制逻辑和探针节点,使其可以根据需要提前读出已完成的子块。另一种思路是从小处着手,硬件单元原生支持4x4的小块模式,然后对FeedData模块进行控制,将大于4x4尺寸的模式分解成若干次执行,最后把执行结果累加起来。

  台湾清云科技大学的Ou Chien-Min等人于2005年提出了一种脉动阵列方案。

  他们将PE阵列设计成4x4的单元模式,在顶层上包含16个同样的单元,共有256个PE。每个4x4单元的结构如下图所示。

每个单元包含4个 1D array 每个 1D array 内部包含4个PE

  每个PE的内部结构是

  这两种方案都会存在控制逻辑比较复杂的问题,会增加硬件设计的负担,不如对需求进行裁剪,硬件只支持一种固定的预测模式。

  下图比较了多种脉动阵列ME方案的设计和性能指标。

  

  下图分析了几种不同的运动估计算法在图像质量维度上的差异,显然,Full search方法是所有方法中PSNR最大的方法。

  

  数据复用 Data Reuse

  典型的编码器需要在片外存储器(DDR memory)中保持若干个参考帧,在执行ME过程中,ME模块需要反复从DDR中读取大量数据。由于片外DDR一般距离主控芯片较远,访问DDR通常延迟较大,不利于频繁随机读取。另一方面,访问DDR涉及active、precharge、burst等较为复杂的时序约束,数据到达ME模块的时序会存在较大的不确定性,不利于精确控制算法时序。基于以上原因,很多设计者会在ME模块内部安排一个片内SRAM当作高速缓存(Cache),由SRAM直接为ME模块提供数据,可以降低访问延迟,消除时序的不确定性。

  如前所述,某些设计为了满足性能要求,需要同时处理两个(或更多)像素块。最自然的情况当然是两个像素块在空间上是相邻的,因此两个像素块的搜索区域(search area)会有重叠的区域,即下图中斜线所示的部分。一个合理的设计应该在SRAM中复用这部分数据,从片外DDR中只读出一次。更理想的情况是,这些数据在SRAM中也只有一份拷贝,通过控制逻辑实现复用。

  研究发现,数据复用主要存在四种可能的方式。

  

  更多的运动估计方法可以参考本专栏的其它文章

刘斯宁:H.2 ** 概念解析 - 运动估计刘斯宁:H.265 概念解析 - 运动搜索算法H.2 ** 编码器

  H.2 ** 编码器的设计一般会遵循"encoding by decoding"的设计思想,意思是说,编码器内部会实现一个解码器,编码器输出的码流会立即被内部的解码器解码并重建出图像,通过这种设计,编码器会非常精确地知道码流解码后的图像是什么效果,下一帧图像的编码将建立在已重建图像的基础之上,因此编码器和未来实际处理码流的解码器在逻辑上是永远同步的,在不考虑误码的情况下,不存在解码误差积累的问题。

  如前所述,编码器的驱动软件需要维护一组参数,包括GOP、QP等,编码器工作时需要随时引用这些参数。

  上图中的 "Mode Select" 单元负责决定一个宏块是进行Intra还是Inter编码,它做决策的依据是:

如果根据GOP设置当前帧是I帧,则所有宏块都是Intra编码;如果当前帧是P帧,且ME单元给出的最佳SAD值小于Intra预测的最佳SAD值,则当前宏块采用Inter编码;如果当前帧是P帧,但ME单元给出的最佳SAD值大于等于Intra预测的最佳SAD值,则当前宏块采用Intra编码;

  下图从另一个视角对编码器的功能进行了归类。

  

  I帧编码

  一个序列的第一帧一定是I帧,所有宏块都必须采用帧内预测模式(Intra Prediction)。第一帧第一行宏块没有上方像素可供参考,所以只可能采取Mode1预测模式。

  但是第一帧第一行第一个宏块连左方像素也没有,所以只能作为一个特例处理,所有像素的预测值都是128。

  编码器在完成一个宏块的预测后,会对该宏块进行编码、解码、重建,于是在帧缓存里就有了这个宏块解码后的像素值。

  从第二行宏块开始,帧缓存里已经有了当前宏块的上方像素可供参考,于是编码器可以遍历17种帧内预测模式(4种16x16,9种4x4,4种色度8x8),从中选出SAD值最小的模式。第三行以后则以此类推。

  如果是面向VLSI的硬件编码器,一般会考虑下图所示的并行计算架构,同时计算17个预测模式的SAD值,很快就能求出最优预测模式。

  下图总结了帧内预测模式的变换和量化处理流程。

  在按上图完成对一个宏块的处理后,需要按照下图所示的-1,0,1,2,...,24,25顺序对4x4块数据进行编码,并把编码后的数据追加到输出码流中。

   P帧编码

  如果GOP参数决定当前帧是P帧,则对每个输入宏块都需要启动ME和MC单元的处理。ME的任务是输出最佳运动矢量MV、MV所在的参考帧编号(Reference Frame Index, RFI)、以及失真指数SAD。MC单元根据MV值从DPB缓存中访问参考帧,从参考帧中的指定位置处提取匹配块,如下图所示。

步骤1:生成预测块

  如果MV支持亚像素精度,则MC单元需要对参考块进行插值以生成最终的像素块,这个像素块就是inter prediction的结果,接下来它会与输入宏块做减法生成residue block。

步骤2:生成残差块

  得到残差块后,"Mode Select" 单元会决定该宏块是使用Intra还是Inter编码,然后将获胜的残差块送给"Transform"单元进行后续处理。下图显示了变换和量化单元的工作原理,图中的虚线红圈表示遍历所有可能的Intra/Inter预测模式,以找出失真最小的预测模式。

  

  RDO

  比较简单的"Mode Select" 工作逻辑是只比较失真指标,不考虑预测模式对码率的影响。更为复杂的逻辑是将码率大小引入考量,此时预测模式的胜出因素是失真和码率两个参数的加权之和,这个特性称为率-失真优化(Rate-Distortion Optimization, RDO)。

  RDO特性引入的最大区别是需要为每个预测模式都计算一遍码率,这会使熵编码单元的算力需求成倍增加,成为一大设计挑战。

  

H.2 ** 解码器

  H.2 ** 解码器的工作原理框图如下图所示。

  

  下图是一种硬件解码器实现方案的结构框图。

  

  

H.2 ** 功能裁剪

  如前所述,H.2 ** 标准支持(13+4+1)种帧内预测模式和(7+1)种帧间预测模式。在对一个像素块进行编码时,理想情况下编码器应该穷举所有可能的预测模式,然后根据每种模式的RDO结果挑选出最优的预测模式。然而,在很多场景下,这种做法的成本太大了,往往会超出系统的频率或面积约束,所以不得不进行裁剪。

  帧内预测

  在某些应用场景中,编码器所在的芯片内部存在其它硬件模块可以提供关于图像的直方图统计,有人提出可以利用直方图判断待编码的16x16宏块是否平坦,通过这种方法可以裁剪掉一些计算分支,适用于在CPU或DSP平台上进行软编码的场景。

   从最终效果上看,采用这种方法后图像质量基本没有变化,但码率出现了显著的增加,甚至接近了40%,这说明这种方法经常预测错误,看起来不是一种很优秀的方法。

  H.2 ** Intra4x4 支持9种预测模式,但是JM参考代码中只实现了统计频率最高的6种。研究表明,这种裁剪方法可以使计算成本下降30%,但图像质量下降不多。

  比上面方法更激进的做法是直接裁剪掉所有4x4模式的分支,即所有宏块都使用16x16编码方式。随着技术的进步,图像分辨率总是越来越高,捕获图像的sensor像素特征尺寸越来越小,所以在宏块尺度上图像的空间相似性一般很大,这种裁剪的方法也是具有相当的可行性的。

  帧间预测

  与帧内预测的情况类似,帧间预测时也可以考虑裁剪掉所有4x4模式的分支,所有宏块都使用16x16预测方式,这个做法可以大幅减少编码器的设计工作量,降低实现成本。前面介绍的脉动阵列方法用于计算固定大小的像素块是很合适的,但是如果需要支持可变大小的像素块,比如帧间预测规定的16x8, 8x16, 8x8, 4x4等块尺寸,则需要对脉动阵列进行额外的设计,这就会增加设计的复杂度和硬件成本。从这个角度看,ME只支持16x16的像素块也是有一定合理性的。

  有人研究了参考帧数量和ME块尺寸对编码质量、码率和耗时的影响,结果如下表所示。

  数据说明,与5个参考帧相比,使用一个参考帧在图像质量损失不大,PSNR下降0.1~0.4dB左右,码率方面有8%~14%左右的增加,但耗时明显减少,仅为多参考帧的42~46%,所以有利于提高编码的实时性。

  SDAD

  在对像素块进行预测时,编码器需要为每个预测模式对应的Distortion进行度量(打分),最常用的度量指标是SAD,即Sum of Absolute Difference。为了节省计算成本,很多时候可以选择跳过一些像素,比如跳过1/4或者1/2像素,得到的指标称为SDAD,即Sum of Deci ** ted Absolute Difference。

  Deci ** tion 一词源于古罗马军队中的一种制度,如果某个部队打了败仗或者触犯了某条军纪,作为惩罚措施,将该部队每十个人中抽出一个人处决,以示警告。-- 再次证明,学会如何站队真是太重要了--

  Deblocking Filter

  由于H.2 ** 是以宏块为基本单位进行编码的,所以块与块之间不可避免地会存在一些边界效应,特别是图像在大屏幕上播放时,方块效应会很明显,影响视觉体验。H.2 ** Baseline 支持去块效应滤波器,但这是一个可选的特性,如果启用它可以平滑宏块之间的边界,改善用户体验。低成本的编码器可以考虑裁剪掉这个特性,这可以节约一些硬件成本。

  有人对块效应滤波器的裁剪问题做了专题研究,实验表明,块效应滤波器大约会消耗1/3的解码算力,对于某些序列,打开滤波器后图像质量(PSNR)会有一定程度的提高(大约0.5dB),但是对另一些序列则提高不明显。

  当然,这里存在一个问题是,PSNR指标并不能完全代表人的主观感受。有些序列可能PSNR指标没有明显的差异,但在人眼看来图像质量感受却大不相同。这就引出了另一个问题,就是使用什么样的评价指标可以更好地反映人的感受,这也是图像编解码领域的一个研究课题。

  B 帧

  H.2 ** MP 和 EP 配置支持B帧(bi-directional predictive frame),特点是会参考(在时间轴上)左右两侧的I帧、P帧,从中找出最佳的匹配块。

  与纯I帧和P帧构成的序列相比,B帧编码效果更高,但是也需要消耗更多的算力。另一方面,由于B帧在时序上对未来才会诞生的P帧存在依赖关系,所以必须等未来帧到达后先编P帧,然后才开始编B帧,这样就不能第一时间完成对B帧的编码,不利于提高码流的实时性。对于非常关注低延迟的应用场景,比如安防监控,则一般不使用B帧。

  

  

  

  

  

  

  

  

上一篇:Netflix VMAF 视频质量评估工具概述

下一篇:外媒英特尔Tiger Lake处理器 ** 1性能:相比前代提升巨大

发表评论:

评论记录:

未查询到任何数据!

在线咨询

点击这里给我发消息 售前咨询专员

点击这里给我发消息 售后服务专员

在线咨询

免费通话

24小时免费咨询

请输入您的联系电话,座机请加区号

免费通话

微信扫一扫

微信联系
返回顶部