一、H.264简介
H.264是一种视频高压缩技术,同时称为MPEG-4 AVC,或MPEG-4 Part10。ITU-T从1998年就H.26L的H.26S两个分组,H.26L研制节目时间较长的高压缩编码技术,H.26S则指短节目标准制订部 门。前面的H.263就是H.26S标准化技术,而H.264标准是在H.26L基础上发展而来的。为了不引起误解,ITU-T推荐使用H.264作为这一标准的正式名称。
H.264集中体现了当今国际视频编码解码技术的最新成果。在相同的重建图像质量下,H.264比其他视频压缩编码具有更高的压缩比、 更好的IP和无线网络信道适应性。
H.264标准分为三档:基本档次;主要档次(可用于SDTV、HDTV和DVD等);以及扩展档次(用于网络的视频流)。其中H.264的基本档次是免费,用户可以无偿使用,现得到美国苹果公司和美国Cisco系统公司、中国联想公司、诺基亚、美国On2技术公司、德国西门子、TI公司等的支持; 其许可体系要比MPEG-4单纯,公正无差别对待用户和专利持有者。H.264替代MPEG-4的呼声很高,除了其高性能外,低额专利费和公正的无差别许 可制度也至关重要。由于技术的日益成熟,半导体厂商已在进行H.264的编码/解码LSI的开发。特别是HDD录像机和DVD录像机等设备中,采用H.264的实例已很多,更引起了半导体厂商的关心。加之,H.264采用的动画编码方式和音频编码方式具有多样化特性,今后几乎将会是全部厂商的主要规格之一。
二、H.264码流分析
H.264中把图像分成一帧(frame)或两场(field),而帧又可以分成一个或几个片(Slilce);片由宏块(MB)组成。宏块是编码处理的基本单元。
I frame、P frame和B frame区别:
- I frame 是自己独立编码,不依赖于其他frame 数据。
- P frame 依赖 I frame 数据。
- B frame 依赖 I frame, P frame 或其他 B frame 数据。
Slice也有三种编码模式:I_slice、P_slice、B_slice 。区别如下:
- I_slice为帧内预测模式编码;
- P_slice为单向预测编码或帧内模式;
- B_slice 中为双向预测或帧内模式。
NAL指网络提取层,里面放一些与网络相关的信息,是用来将编码的数据进行打包的。H.264视频流是以NAL单元传送的。但在一个NAL单元里面,可能既存放I-Slice(P-Slice或B-Slice),同时也可能存放图像的其他信息 。nal_unit_type的五种类型:
1(非IDR图像的编码条带)
2(编码条带数据分割块A)
3(编码条带数据分割块B)
4(编码条带数据分割块C)
5(IDR图像的编码条带)
H.264解码中首先过滤码流获得参数集,参数集是H.264标准的一个新概念,是一种通过改进视频码流结构增强错误恢复能力的方法。众所周知,一 些关键信息比特的丢失(如序列和图像的头信息)会造成解码的严重负面效应,而H.264把这些关键信息分离出来,凭借参数集的设计,确保在易出错的环境中能正确地传输。这种码流结构的设计无疑增强了码流传输的错误恢复能力。
H.264的参数集又分为序列参数集(Sequence parameter set)和图像参数集(Picture parameter set)。其中,序列参数集包括一个图像序列的所有信息,即两个IDR图像间的所有图像信息。图像参数集包括一个图像的所有分片的所有相关信息,包括图像 类型、序列号等,解码时某些序列号的丢失可用来检验信息包的丢失与否。多个不同的序列和图像参数集存储在解码器中,编码器依据每个编码分片的头部的存储位 置来选择适当的参数集,图像参数集本身也包括使用的序列参数集参考信息。
H.264码流第一个 NALU 是 SPS(序列参数集Sequence Parameter Set)。H.264码流第二个 NALU 是 PPS(图像参数集Picture Parameter Set)。H.264码流第三个 NALU 是 IDR(即时解码器刷新)。如果要对字节流进行解析,可参看H264标准文档 7.3.3 规定的语法进行解析
I 帧和 IDR 帧的区别:
IDR 帧属于 I 帧。解码器收到 IDR frame 时,将所有的参考帧队列丢弃 (用 x264_reference_reset 函数实现——在 encoder.c 文件中) 。这点是所有 I 帧共有的特性,但是收到 IDR 帧时,解码器另外需要做的工作就是:把所有的 PPS 和 SPS 参数进行更新。由此可见,在编码器端,每发一个 IDR ,就相应地发一个 PPS&SPS_nal_unit。
先说明:所有的 IDR 帧都是 I 帧,但是并不是所有 I 帧都是 IDR 帧。就是说, IDR 帧是 I 帧的子集。 (我们程序中设定的是每250帧出现一个 IDR 帧) 。