1. 视频编码
1.1 编码技术的背景
图像,简单来说,就是静止的画面,它捕捉并记录了一个特定时刻的空间信息。就像一张照片,图像由大量的像素(Picture Elements)组成,每个像素都有自己的颜色和亮度值。
视频,则是动态的图像序列,它通过连续播放一系列的图像帧(Frames),给人以连续运动的错觉。每个视频帧都是一张独立的图像,当这些图像帧以足够的速度连续显示时(通常是每秒24帧或以上),我们的大脑就会将这些静止的图像融合,感知到流畅的动作和场景变化。视频除了图像信息外,通常还包含音频轨道,以提供完整的视听体验。
视频编码,简单来说,就是将原始的视频数据转换成另一种格式的过程,目的是为了高效地存储和传输视频文件。这个过程涉及到对视频内容的压缩,以便在保持尽可能好的视频质量的同时,减少视频文件的大小。可参考下述表格,我们假设有一个未压缩的原始视频数据,其大小为1GB(即1024MB),H.265/HEVC传输1分钟视频仅需128MB的带宽。
视频编码标准 | 空间效率比较 | 带宽占用比较 |
---|---|---|
无编码(未压缩) | 100% (基准) | 100% (基准) |
H.264 | 25% | 25% |
H.265/HEVC | 12.5% | 12.5% |
VP9 | 20% | 20% |
AV1 | 10% | 10% |
1.2 编码技术的发展
1.3 编码技术的流程
- 预处理:在这个阶段,原始视频素材可能需要转换色彩空间(如从RGB到YUV),进行去噪处理以减少不必要的视觉噪声,以及调整分辨率以匹配目标输出要求。这些操作有助于提高编码效率和最终视频质量。
- 分帧:视频被分解成一系列连续的画面或帧。根据编码标准(如H.264、H.265),这些帧会被标记为I帧、P帧、B帧等,用于实现不同级别的压缩和解码依赖关系。
- 编码器分析:通过运动估计识别帧间变化,确定哪些区域是静态的,哪些是动态的,以及如何用前一帧的信息预测当前帧的内容,这一步骤对于P帧和B帧尤为重要。
- 变换编码:使用如DCT这样的技术,将图像数据从空间域转换到频率域,这样可以更高效地去除视觉上不敏感的高频信息。
- 量化:量化是对变换后的系数进行舍入处理,减少数据的精确度。这是损失压缩的主要来源,量化步长越大,压缩比越高,但图像质量损失也越大。
- 熵编码:利用统计学方法,如霍夫曼编码,根据数据出现的频率来分配不同长度的编码,使常见数据用较短的码字表示,从而进一步压缩数据量。
- 封装:最后,编码后的视频数据、音频数据(如果有的话)、字幕、元数据等被组合在一起,并按照特定的容器格式(如MP4、MKV)打包,形成可以在不同设备和平台上播放的完整视频文件。
H.264
和H.265
是两个广泛使用的视频编码标准,它们都是由国际电信联盟(ITU-T)视频编码专家组(VCEG)和国际标准化组织(ISO)动态图像专家组(MPEG)联合开发的,旨在提供高效的视频压缩技术,减少视频文件的大小,同时保持高质量的图像输出。这两种编码格式的广泛应用以及在GB/T 28181协议中主流视频格式,在这里我们重点介绍一下。
2. H.264/AVC(高级视频编码)
H.264
,即Advanced Video Coding(AVC),是国际电信联盟(ITU-T)和国际标准化组织(ISO/IEC)联合推出的一种高度高效视频压缩标准。它通过采用先进的预测编码、熵编码和运动补偿技术,实现了在保证视频质量的同时大幅度减少所需带宽,广泛应用于从高清电视广播、网络视频、视频会议到移动设备和监控系统的各类视频服务中,是目前最普遍使用的视频压缩技术之一。
2.1 整体结构
- 序列位于最顶层,定义了整个视频的基本参数,并且可以包含多个GOP。
- 每个GOP以一个I/NALU开始,随后是P/NALU和/或B/NALU,形成了依赖关系链。
- NAL单元(包括SPS、PPS、I/NALU、P/NALU、B/NALU等)是数据传输和处理的基本单位,每个NAL单元都带有自己的头部和负载数据。
- SPS和PPS在视频流中通常位于序列或GOP的开头,为解码器提供必要的解码参数。
2.1.1 概念点
-
序列(Sequence)
- 定义: 视频序列是视频编码的最高层级结构,代表了一段连续的视频内容。一个序列始于序列头(Sequence Header),包含了整个序列的全局参数设置,比如图像尺寸(宽x高)、帧率、色彩空间信息等。
- 作用: 定义整个视频的基本编码环境,确保解码器能够正确初始化并准备解码后续的图像数据。
-
GOP(Group of Pictures)
-
定义: GOP是一组连续的图像(帧),通常以一个独立解码的关键帧(I帧)开始,随后是依赖于该关键帧的预测帧(P帧和B帧)。
因此I帧,尤其是IDR帧,是GOP的明显标志
。 -
组成:
-
I帧(Intra-coded picture,帧内编码图像):I帧是视频编码中的一种基本帧类型,它采用帧内预测的方式进行编码,即只考虑本帧内的信息而不参考前后帧的内容。I帧包含了重构该帧所需的所有数据,相当于一个独立的、经过压缩的图像,可以独立解码显示,不需要其他帧的信息辅助。
-
自包含性:I帧不依赖于视频流中的其他帧,可以独立解码,适合做随机访问点。
-
恢复点:在视频播放中断或错误时,从最近的I帧开始解码可以恢复画面。
-
压缩效率:相对于P帧和B帧,I帧的压缩效率较低,因为没有利用时间冗余信息。
IDR帧(Instantaneous Decoding Refresh frame,即时解码刷新帧):IDR帧是一种特殊的I帧,除了具备I帧的所有属性外,还具有“即时解码刷新”的特性。当解码器遇到IDR帧时,它会清空解码缓冲区中的所有先前帧信息,包括P帧和B帧的参考数据,强制从IDR帧开始全新的解码过程,确保了视频流的干净起点。
- 强制刷新:IDR帧之后的帧不能引用IDR帧之前的任何帧,实现了解码状态的完全重置。
- 错误隔离:这种机制有效防止了错误传播,一旦网络出现丢包,从下一个IDR帧开始即可恢复正确解码,而不影响之后的帧。
- 快速定位:IDR帧也是视频流中的理想随机接入点,便于快速跳转播放。
NAL单元类型标识非IDR I帧通常标记为类型5,IDR帧(一种特殊的I帧)标记为类型1
-
-
P帧(Predictive-coded picture,预测编码图像)是一种基于运动补偿的帧类型,它利用了视频序列中前后帧之间的时空相关性来实现高效的压缩。P帧是I帧之后的帧,通过参考其前一帧(通常是I帧或之前的P帧)来预测当前帧的改变部分,仅编码变化或新增的信息,大大减少了所需的比特数,提高了压缩效率。
- 运动估计:P帧编码的第一步是进行运动估计。编码器会分析当前P帧与参考帧(通常是前一帧)之间的差异,计算出画面中物体的运动矢量。这意味着找到图像块的最佳匹配位置,以预测P帧中每个宏块或子宏块的内容。
- 运动补偿:基于运动估计的结果,编码器会计算出预测误差,即实际图像块与预测图像块的差异。这个差异(残差)相比于原始图像信息,通常具有更高的压缩效率。
- 编码残差:预测误差经过变换编码(如离散余弦变换DCT)、量化和熵编码(如CABAC或CAVLC)等步骤,被高效地编码并存储。这些步骤与I帧中的类似,但因为处理的是残差信息,所以通常需要的比特数更少。
- 参考帧:P帧的解码需要参考其前序帧,这意味着在解码流程中,必须先有参考帧的完整信息才能正确解码P帧。这种向前的依赖性使得P帧不能独立解码,但也是其高压缩效率的来源。
NAL单元类型标识通常标记为类型**2**,与某些情况下的I帧和B帧共用此类型,具体区分依赖其他编码信息
-
B帧(Bi-directional predicted picture,双向预测编码图像)是一种更为复杂的帧类型,它利用了前后两帧(未来帧和过去帧)的信息来进行预测编码,以此达到更高的压缩效率。与P帧相比,B帧能够更准确地预测运动物体的形态,从而编码更少的残差信息,节省更多的带宽。
- 双向预测:B帧最大的特点是它可以同时参考前一帧(P帧或I帧)和后一帧(P帧或I帧)来进行预测编码。编码器执行两次运动估计,一次向前(参考过去的帧),一次向后(参考未来的帧),然后结合这两个预测结果来生成最佳的预测图像。
- 最佳预测选择:基于双向预测得到的两个预测图像,编码器会计算出综合考虑两者的最佳预测结果,使得预测误差最小化。这个过程可能涉及到加权平均或其他优化策略。
- 编码残差:与P帧一样,B帧最终编码的也是预测误差信息。预测误差经过变换编码(如DCT)、量化和熵编码,以高效的形式存储。
- 解码依赖性:B帧的解码最为复杂,因为它依赖于两个方向上的参考帧,这意味着在解码顺序上,B帧往往位于其参考帧之后。这增加了编解码的复杂度,同时也要求解码器必须有较大的缓冲区来存储未解码的帧。
NAL单元类型标识大多数情况下标记为类型**2**,其与P帧的差异在于编码时采用的双向预测信息
-
-
作用: 通过引入时间上的冗余减少,实现高效的视频压缩。GOP的长度(即包含了多少帧)是编码策略的一部分,影响着视频质量和解码延迟。
-
-
NAL(Network Abstraction Layer)
- 定义: NAL是H.264编码中用来封装编码数据的一种方式,它将编码后的原始数据分割成携带不同类型信息的单元,便于网络传输和解码处理。
- NAL单元结构:
-
起始码(Start Code)或长度前缀(Length Prefix) :起始码是一个特定的字节序列(如0x000001或Annex B格式的0x00000001),用于标识NAL单元的开始。在某些传输情况下,可能会使用长度前缀来代替起始码,以适应特定的封装格式。
-
Annex B格式:
-
最常用的封装格式,特别是在基于IP的网络传输中。
-
每个NAL单元前都带有起始码(Start Code),通常是0x00000001或者对于较短版本的0x000001。
-
起始码用来标识一个新的NAL单元的开始,便于解码器分离和处理各个NAL单元。
-
不包含长度信息,解码器需要依赖起始码来区分NAL单元。
-
AVCC格式(Advanced Video Coding Configuration Record) :
- 常用于MP4等基于ISO Base Media File Format的容器中。
- NAL单元前没有起始码,而是使用长度字段来表示每个NAL单元的长度。
- 在容器文件头部会有一个AVCDecoderConfigurationRecord记录,包含SPS、PPS等参数信息。
- 这种格式更适用于文件存储和需要精确控制数据包长度的场景。
-
-
NAL头(NAL Header) :紧跟在起始码或长度前缀之后,通常占一个字节,包含以下信息:
- FORBIDDEN_ZERO_BIT:1位,总是为0,用于错误检测。
- NAL_UNIT_TYPE:5位,定义了NAL单元的类型,如I帧(IDR为1,非IDR为5)、P帧(通常为2)、B帧(通常也为2)、SEI(补充增强信息)等。
- NAL_PRIORITY_ID:3位,在某些应用中用于指示NAL单元的重要性,但在H.264中通常未使用。
-
负载数据(Payload Data) :包含实际的编码数据,如图像数据、序列参数集(SPS)、图像参数集(PPS)或SEI消息等,具体内容根据NAL单元类型而定。
-
- NAL单元类型
- 1: IDR图像(IDR Slice),表示即时解码刷新点,用于错误恢复和随机接入。
- 2: 非IDR图像的切片(Non-IDR Slice),包括P帧和B帧的切片。
- 5: I帧的切片(I Slice),不含IDR属性的帧内编码图像。
- 6、7、8、9、10、11: 定义了不同类型的补充增强信息(SEI)单元,用于传输时间戳、字幕信息等。
- 12: 序列参数集(SPS),定义了一段视频序列的编码参数。
- 13: 图像参数集(PPS),针对单个图像的编码参数。
- 14: 解码器自主运算数据(Access UnitDelimiter),用于分隔访问单元。
- 15: 空NAL单元(Filler Data),填充数据,用于字节对齐等目的。
-
VCL(Video Coding Layer)
2.2 所使用压缩技术
- 帧间预测(Inter-frame Prediction) :通过比较前后帧之间的差异来进行运动估计,预测每一帧中物体的运动方向和速度,仅对运动矢量和残差进行编码,大大减少了需要传输的数据量。
- 帧内预测(Intra-frame Prediction) :在单个帧内部利用周围像素的信息来预测当前块的内容,减少空间冗余。H.264引入了多种帧内预测模式,提高了预测精度。
- 变换编码(Transform Coding) :将预测后的残差信号进行离散余弦变换(DCT)或类似的正交变换,将空间域信号转换到频率域,使信号能量集中,便于进行量化和熵编码。
- 量化(Quantization) :在变换编码之后,对变换系数进行量化,将连续的数值映射为离散的值,这一过程会引入一定的失真,但也是压缩的关键步骤,通过调整量化参数可以在压缩效率和图像质量之间权衡。
- 熵编码(Entropy Coding) :对量化后的系数进行熵编码,通常是使用上下文自适应的二进制算术编码(CABAC)或上下文自适应的变长编码(CAVLC),这两种方法都能根据符号出现的概率动态调整编码长度,从而进一步提高压缩效率。
- 环路滤波(Deblocking and SAO Filter) :为了减少因压缩带来的块效应,H.264采用了去块滤波器(Deblocking Filter)和采样自适应偏移(Sample Adaptive Offset, SAO)等后处理技术,提升解码后图像的视觉质量。
- 多参考帧预测:H.264允许使用多个过去的帧作为参考帧进行运动补偿,增加了预测的灵活性和准确性,进一步提高压缩效率。
2.3 编码基础流程
graph TD;
A[输入视频帧] --> B(图像分割为宏块);
B --> C{帧类型};
C --> |I帧| D[帧内预测];
C --> |P帧| E[运动估计];
C --> |B帧| F[双向预测];
D & E & F --> G[预测误差];
G --> H[变换编码DCT];
H --> I[量化];
I --> J[熵编码CAVLC/CABAC];
J --> K[环路滤波Deblocking];
K --> L(NAL单元封装);
L --> M[输出码流];
style A fill:#f9f,stroke:#333,stroke-width:2px,rx:5,ry:5;
style B fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style C fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style D fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style E fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style F fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style G fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style H fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style I fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style J fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style K fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style L fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style M fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
基本流程
- 输入视频帧:视频序列的原始输入。
- 图像分割为宏块:视频帧被分割成多个固定大小的宏块(通常为16x16像素)作为基本编码单位。
- 帧类型:根据编码策略选择帧为I帧(帧内编码)、P帧(前向预测帧)或B帧(双向预测帧)。
- I帧:仅使用帧内预测,不参考其他帧。
- P帧:使用前一帧进行运动预测,产生预测误差。
- B帧:同时参考前后帧进行双向预测,提高压缩效率。
- 预测:根据帧类型执行帧内预测或帧间预测,产生预测误差信号。
- 预测误差:实际像素值与预测值之差,需要进一步编码。
- 变换编码(DCT) :使用离散余弦变换(DCT)将空间域的预测误差转换到频率域,便于压缩。
- 量化:将变换后的系数进行量化处理,去除不重要的信息,进一步压缩数据。
- 熵编码(CAVLC/CABAC) :对量化后的系数进行熵编码,CABAC(上下文自适应二进制算术编码)通常比CAVLC(基于内容的自适应变长编码)更高效。
- 环路滤波(Deblocking) :应用去块滤波器减少因量化引入的块效应,提升图像质量。
- NAL单元封装:将编码后的数据封装成网络抽象层(NAL)单元,便于传输和解码。
- 输出码流:最终编码后的视频数据,准备用于存储或传输。
3. H.265/HEVC(高效视频编码)
H.265,也称为High Efficiency Video Coding (HEVC),是继H.264之后的新一代视频编码标准,由ITU-T和ISO/IEC联合制定。H.265旨在以更高效的压缩算法,在保持视频质量不变的情况下,相比H.264减少约50% 的比特率,或者在相同比特率下提供更高质量的视频体验。这一进步对于高分辨率视频内容(如4K、8K超高清视频)的存储和传输尤为重要,广泛适用于流媒体服务、广播电视、视频监控及移动视频等领域。尽管H.265带来了显著的效率提升,但由于其较高的计算复杂度和潜在的专利授权费用,其普及和应用面临着一定挑战。
3.1 所使用压缩技术
- 编码树单元(CTU)和四叉树划分:H.265使用更大的编码树单元(最大可达64x64像素),并引入四叉树结构来灵活划分编码单元(CU)、预测单元(PU)和变换单元(TU),这使得编码器能更精细地适应图像内容的复杂度,实现更佳的压缩效率。
- 更丰富的运动预测模式:除了传统的帧间预测模式外,H.265新增了更多运动矢量预测方向、合并相邻块的运动信息、以及高级运动矢量预测等技术,提高了运动补偿的精度,减少了预测误差。
- 更高效的熵编码:延续了H.264中的CABAC(上下文自适应二进制算术编码),并进一步优化了上下文模型,提升了熵编码的性能,有效减小了编码后的数据量。
- 样本自适应偏移(SAO)和自适应环路滤波(ALF) :SAO通过分析像素值的分布对边缘和平滑区域进行优化,而ALF则动态调整滤波强度,两者共同作用于编码后阶段,显著改善了图像质量,减少压缩产生的视觉失真。
- 并行处理技术:引入了瓦片(Tiles)和波前并行处理(Wavefront Parallel Processing, WPP)等机制,支持视频编码过程中的并行计算,提高了编码速度和效率,特别适合现代多核处理器架构。
- 色度采样比例的灵活性:允许在不同区域使用不同的色度采样格式(4:2:0、4:2:2、4:4:4等),根据内容特点优化压缩,尤其是在高色彩精度需求的场景中。
- 自适应量化和去块滤波优化:根据图像内容动态调整量化参数,减少视觉失真;同时,增强的去块滤波算法能更有效地消除块效应,保持图像的自然平滑度。
3.2 编码基础流程
graph TD;
A[输入视频帧] --> B(图像分割为CTUs);
B --> C{预测类型};
C --> |I块| D[帧内预测];
C --> |P块| E[运动估计];
C --> |B块| F[双向预测];
D & E & F --> G[残差编码];
G --> H[变换编码];
H --> I[量化];
I --> J[熵编码];
J --> K[环路滤波];
K --> L(NAL单元封装);
L --> M[输出码流];
style A fill:#f9f,stroke:#333,stroke-width:2px,rx:5,ry:5;
style B fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style C fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style D fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style E fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style F fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style G fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style H fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style I fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style J fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style K fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style L fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
style M fill:#def,stroke:#333,stroke-width:2px,rx:5,ry:5;
基本步骤
- 输入视频帧后,图像被分割成编码树单元(CTUs)。
- 根据块的类型(I块、P块、B块),分别进行帧内预测、运动估计(帧间预测)或双向预测。
- 预测后的残差信号进行变换编码(如DCT)。
- 变换后的系数进行量化。
- 量化后的系数进行熵编码(如CABAC或CAVLC)。
- 熵编码后,应用环路滤波(例如去块效应滤波、采样自适应偏移等)来改善图像质量。
- 最后,处理过的数据被封装成网络抽象层(NAL)单元,输出为编码码流。
4. 多种编码格式的对比
维度 | H.264 (AVC) | H.265 (HEVC) | VP9 | AV1 |
---|---|---|---|---|
发布时间 | 2003年 | 2013年 | 2013年 | 2018年 |
开发机构 | ITU-T VCEG & ISO MPEG | ITU-T VCEG & ISO MPEG | Alliance for Open Media | |
主要应用 | 网络视频、蓝光光盘、IP监控等 | 高清电视、4K/8K超高清视频、流媒体服务、视频会议系统等 | YouTube、WebM项目、一些流媒体服务 | 逐步应用于流媒体服务、网页浏览器、视频编辑软件等 |
压缩效率 | 相比MPEG-4 Part 2,节省约50%比特率 | 相比H.264,平均节省约50%比特率,高分辨率视频效率更高 | 相比H.264有显著提升,尤其是在高分辨率下 | 当前最高效率,特别针对高分辨率和HDR内容优化 |
图像质量 | 支持高清至8K分辨率,提供高质量图像 | 在相同比特率下提供更高质量图像,优化细节处理,支持更高分辨率 | 提供与H.265相近的图像质量,优化色彩和动态范围 | 提供最佳图像质量,尤其在复杂场景和高动态范围内容上 |
硬件解码支持 | 广泛支持,包括较老设备 | 新设备普遍支持,但老设备支持度有限,可能需要软件解码 | 渐增,主要在较新设备和一些平台上有良好支持 | 支持正在增长,但在一些老旧设备上可能缺乏硬件加速 |
编码复杂度 | 相对较低 | 显著高于H.264,需要更强大计算资源 | 较高,需要较强计算力 | 最高,极度依赖高性能硬件以实现有效编码 |
解码复杂度 | 适中,兼容性好 | 增加,特别是高分辨率内容 | 高于H.264,但在现代硬件上表现良好 | 目前最高,要求较高性能的解码器 |
版权与专利 | 需要支付专利许可费 | 需要支付专利许可费,且费用可能更高 | 免专利费,但Google保留部分权利 | 完全免专利费,开放源代码 |
兼容性与普及度 | 非常高,几乎被所有现代播放器和设备支持 | 普及度正在上升,但在某些老设备上不兼容 | 在Web平台上广泛使用,但在一些传统设备上的支持有限 | 正在逐渐提高,特别是在支持开放标准的新设备上 |
网络适应性 | 良好,适合各种网络环境 | 更佳,特别适合高分辨率视频在有限带宽下的传输 | 良好,针对网络流媒体进行了优化 | 优化针对互联网流媒体,特别是在高分辨率内容传输上 |