1 引言
H.264 视频压缩标准具有很高的压缩效率和很好的网络支持, 非常适应于无线多媒体和基于Internet 的应用。在信息传输的过程中,不可避免的就是噪声。H.264 本身具有很好的抗噪声技术,如SPS,PPS 和图像数据的分开打包, 一帧中可有多个Slice,灵活宏块顺序(FMO)等。但是也有很多情况错误无法被完全修复。H.264 具有很高的压缩率(7~50 倍),这就意味着图像中的冗余已经被大大消除,要从其余的码流中恢复图像有很大困难。此外,H.264 压缩标准采用变长编码的CAVLC 和CABAC,一旦在这些地方出错, 解码器将无法判断下一个变长码开始的位置,导致错误的扩散。
在硬件方面,解码过程中各部分的实现都有其固定的结构,如果不及时检出错误,会导致如内存溢出、查表错误、状态机进入死循环等。解码出的图像会错位或者变形, 更严重的时候整个解码器会停止运行。
所以在解码器中加入纠错功能,及早地发现码流噪声并将解码器恢复到正常的状态是非常有意义而且非常必要的。
本项目的解码器是基于SoC 的ASIC 解决方案,它具有高速、低功耗、低成本的特点。添加纠错功能可以提高解码器的适用性和稳定性,另一方面,应该尽量减少纠错模块对原有芯片的面积和速度的影响。
2 码流结构和错误检出
H.264 标准压缩的码流具有严格的格式。公共信息被提取出来作为SPS(序列参数集), PPS(图像参数集)单独打包,与像素信息分离。SPS 和PPS 是码流中极为重要的信息,将它们单独打包可以在传输环境较差的情况下多次传送,这在一定程度上增强了码流传输的抗干扰能力。每个包被称作一个NAL 单元,根据NAL 类型,各个数据包中的数据按照协议中规定的句法元素顺序紧密排列。这为纠错提供了两点便利:(1)各个NAL 中的错误不会蔓延,即如果当前NAL 中检测出了错误而且又无法确定错误终止的地方,那么可以将当前包丢弃,直到下一个NAL 开始;(2)很多句法元素都有其固定的范围。检测解码出的元素值是否超出范围限制是一个非常有用的办法,也能尽早发现错误,避免解码器进入异常状态。
H.264 视频码流包括五个层次的信息: 序列层,图像层,片层,宏块层,子宏块层,分别与NAL 类型的SPS,PPS,Slice(包括片头,宏块,子宏块信息)相对应。
宏块是编解码处理的基本单位,也是进行错误修补的基本单位。H.264 视频码流结构如图1 所示。
图1 H.264 码流结构
在上面的几个层次中,每一层都具有其特定的句法元素结构,以及相应句法的处理办法,整个错误检测功能就是基于此实现的。目前可以检测到的错误基于以下几类:
(1)保留位错误。这是最容易检测出的错误。在H.264 协议中规定了一些保留位, 如NAL 起始的forbidden_zero_bit,SPS 中的reserved_zero_4bits 等。解码器顺序读入码流时要确定这些保留位的值是正确的,如果有误,就应该丢弃当前的包或者标记错误,做进一步的处理。
(2)句法元素值不在指定范围。大多数的句法元素,尤其是在SPS 和PPS,都有一个指定的范围。如用于计算最大帧数的log2_max_frame_num_minus4 必须在0~12 之间,如果读入的值超出这个范围,即可以判断当前读入的码流有错误。
(3)相关句法元素矛盾。有一些句法元素读入了一个错误的值,但仍然在正确的范围内,单单通过当前语句是无法检测出的。这时候就要利用句法元素之间的相关性,判断读出的值是否合理。例如PPS 中要指定当前图像所引用的序列参数信息, 即PPS->seq_parAMEter_set_id。如果当前引用的SPS 的ID 在所有收到的SPS 中不存在, 即可判断SPS 或者当前PPS 有一方出了问题; 对于slice_type 的I,B,P 各种类型,mb_type 的查表方法也不同, 如果在I slice 中出现了帧间预测的宏块类型,也可以判断出错。
以上方法都是可以通过句法元素本身的值判断出来的,可以在读入码流的同时处理,即在处理PPS、SPS 的相应语句后加入判断,不会对原有解码器造成太大的影响。