H264编码结构和解析

H.264(又称 MPEG-4 AVC)是目前应用最广泛的视频编码标准之一,其高效的压缩性能和良好的网络适配性使其成为流媒体、安防监控、视频会议等场景的核心技术。理解 H.264 的编码结构和解析过程,需要从其分层设计、核心数据单元及解码流程逐步展开。

一、H.264 的编码结构

H.264 的编码结构采用分层设计,核心分为视频编码层(VCL)网络抽象层(NAL),两者协同实现视频压缩与网络传输的适配。

1.1. 网络抽象层(NAL,Network Abstraction Layer)

NAL 的核心作用是将 VCL 生成的压缩数据封装为适合网络传输的格式,解决不同网络(如 IP、广播、存储)的适配问题。其基本单元是NAL 单元(NALU,NAL Unit)。
(1)NALU 的结构
每个 NALU 由1 字节的头部(NAL Header) 和负载(RBSP) 组成,结构如下:

[NAL Header (1字节)] + [RBSP (可变长度)]

NAL Header(头部):共 8 位,包含 3 个关键字段,决定 NALU 的类型和传输优先级:

  • forbidden_zero_bit(1 位):禁止位,通常为 0;若为 1,表示该 NALU 存在严重错误,需丢弃。
  • nal_ref_idc(2 位):参考重要性指示,值越大表示该 NALU 对解码的重要性越高(如 I 帧的 NALU 通常为 3,B 帧可能为 0)。
  • nal_unit_type(5 位):NALU 类型标识,决定负载的内容,常见类型如下:
    0-23:VCL 相关(如 Slice 数据);
    24-31:非 VCL 相关(如参数集、补充增强信息)。
    例如:nal_unit_type=7表示序列参数集(SPS),=8表示图像参数集(PPS),=5表示 I 帧的 Slice 数据。

负载(RBSP,Raw Byte Sequence Payload):VCL 层输出的压缩数据经处理后的形式。VCL 输出的原始数据称为SODB(String of Data Bits),为了避免字节对齐问题,会在 SODB 末尾添加停止位(1 个或多个 0),形成 RBSP。

1.2. 视频编码层(VCL,Video Coding Layer)

VCL 负责核心的视频压缩逻辑(如预测、变换、量化、熵编码),生成压缩后的视频数据。其数据结构按层次分为:序列(Sequence)→ 图像(Picture)→ Slice(片)→ 宏块(Macroblock)→ 子块(Subblock)

  • ① 序列(Sequence)
    一个 “序列” 是由一系列连续的图像组成的视频片段,其全局参数由序列参数集(SPS,Sequence Parameter Set) 定义。SPS 是解码的 “全局配置”,包含影响整个序列的关键参数:
    profile_idc和 level_idc:定义编码的 “能力等级”,限制最大码率、分辨率、帧率等,确保不同设备的兼容性。
    图像尺寸:pic_width_in_mbs_minus1(宽度,以宏块为单位)、pic_height_in_mbs_minus1(高度,以宏块为单位),需结合宏块大小(16x16)计算实际像素尺寸。
    帧 / 场编码模式:指示视频是按 “帧”(Frame)还是 “场”(Field)编码(场编码用于隔行扫描视频)。
    参考帧数量:max_num_ref_frames 定义最大参考帧数目,影响帧间预测的复杂度。

  • ② 图像(Picture)
    一个 “图像” 对应一帧(Frame)或一场(Field)视频,其参数由图像参数集(PPS,Picture Parameter Set) 定义。PPS 依赖于 SPS,包含单幅图像的局部参数:
    熵编码方式:entropy_coding_mode_flag 指示使用 CAVLC(0)还是 CABAC(1)(CAVLC 简单但压缩率低,CABAC 复杂但压缩率高)。
    宏块划分:pic_init_qp_minus26 定义量化参数基准,影响画质与码率的平衡。
    加权预测参数:用于 B 帧或 P 帧的参考帧加权,提升预测精度。
    一个 SPS 可对应多个 PPS,一个 PPS 可对应多个图像(即同一参数配置可复用)。

  • ③ Slice(片)
    每个图像由 1 个或多个 Slice 组成,Slice 是独立解码的最小单元(目的是限制误码扩散:若一个 Slice 出错,仅影响该 Slice,不扩散到其他 Slice)。
    Slice 的组成:每个 Slice 包含Slice 头部和一系列连续的宏块(按光栅扫描顺序排列)。
    Slice 头部:包含解码关键信息,如:
    · slice_type:指示 Slice 类型(I、P、B 等,决定预测方式)。
    · pic_order_cnt_lsb:图像顺序计数(POC),用于确定解码顺序与显示顺序的映射(尤其是 B 帧,解码顺序与显示顺序不同)。
    ref_pic_list_reordering_flag_l0/l1:指示是否重排序参考帧列表(优化预测精度)。

  • ④ 宏块(Macroblock)
    宏块是编码的基本单元,对应原始图像中的一块区域。对于 4:2:0 色度采样(最常用),一个宏块包含:
    1 个 16x16 的亮度块(Y);
    2 个 8x8 的色度块(Cb、Cr)。
    宏块的类型由其所属的 Slice 类型决定,核心分类如下:
    I 宏块:仅依赖自身像素进行帧内预测(无需参考其他帧),适用于关键帧(I 帧)。
    P 宏块:依赖前向参考帧(已解码的 I/P 帧)进行帧间预测,适用于预测帧(P 帧)。
    B 宏块:依赖双向参考帧(前向和后向的 I/P 帧)进行帧间预测,压缩率最高,适用于双向预测帧(B 帧)。
    每个宏块还包含残差数据(原始像素与预测值的差值,经变换和量化后的数据)和运动矢量(对 P/B 宏块,指示参考帧中匹配块的位置偏移)。

  • ⑤ 子块(Subblock)
    为提升预测精度,宏块可进一步划分为更小的子块(如 8x8、4x4),尤其是运动补偿时:
    P/B 宏块的运动补偿单元(PU)可分为 16x16、16x8、8x16、8x8(8x8 还可细分为 4x4),灵活适配不同运动强度的区域(如快速移动的物体用小尺寸子块,静止区域用大尺寸)。

1.3. 熵编码

VCL 层的最后一步是熵编码,将量化后的残差、运动矢量等数据转换为二进制比特流(进一步压缩)。H.264 支持两种熵编码方式:
CAVLC(基于上下文的自适应可变长编码):用变长码表(VLC)编码,根据上下文动态选择码表,实现简单(适合低算力设备)。
CABAC(基于上下文的自适应二进制算术编码):将数据转换为二进制后,用算术编码压缩,结合上下文概率模型动态更新编码参数,压缩率比 CAVLC 高 5-10%,但复杂度更高(适合高性能设备)。

1.4.“帧”(Frame)、 “场”(Field)编码简介

在视频编码中,“按帧(Frame)编码” 和 “按场(Field)编码” 是两种不同的处理视频画面的方式,主要区别源于传统隔行扫描电视技术与逐行扫描技术的差异:

  • 帧(Frame)编码
    定义:将一整个画面(帧)作为基本编码单位,完整记录一帧内的所有像素信息。
    适用场景:适用于逐行扫描的视频,如电影(24fps)、电脑动画、现代数字摄像机录制的视频等。
    特点
    每一帧都是完整独立的画面
    编码处理相对直接,压缩算法作用于完整画面
    适合静态或慢动作场景,细节保留更完整
  • 场(Field)编码
    定义:将一帧画面分成两个 “场”(奇场和偶场)分别编码。奇场包含画面中所有奇数行像素,偶场包含所有偶数行像素。
    适用场景:源于传统 CRT 电视的隔行扫描技术,适用于广播电视信号(如 PAL 制、NTSC 制)。
    特点
    每个场单独传输,播放时两场快速交替形成完整画面
    能有效减少运动画面的闪烁感
    编码时需考虑两场之间的相关性,处理运动场景更高效
    对于快速运动的画面,场编码可能比帧编码产生更少的模糊
    核心区别:
    数据结构:帧编码处理完整画面,场编码将画面拆分为两行交错的场
    时间特性:场的时间间隔是帧的一半(例如 60 场 / 秒相当于 30 帧 / 秒)
    压缩效率:运动场景中场编码通常更高效,静态场景中帧编码表现更好
    兼容性:场编码主要用于传统广播电视,帧编码是现代数字视频的主流方式随着数字技术的发展,逐行扫描和帧编码已成为主流,但场编码仍在广播电视领域有一定应用,许多编码器也支持根据内容自动选择最优模式。

二、H.264 的解析过程(解码流程)

H.264 的解析(解码)是编码的逆过程,核心是从 NALU 流中恢复原始视频帧,步骤如下:

2.1. 码流读取与 NALU 提取

H.264 码流是连续的 NALU 序列,NALU 之间通过起始码(Start Code) 分隔:
短起始码:0x000001(3 字节);
长起始码:0x00000001(4 字节,通常用于码流开头或关键参数集前)。
解析时需先检测起始码,分割出单个 NALU,同时处理防竞争字节(Emulation Prevention Bytes):若 NALU 内部出现0x000000、0x000001(可能被误判为起始码),编码时会插入0x03(如0x000000→0x00000300),解析时需移除0x03以恢复原始数据。

2.2. NALU 类型判断与参数集解析

提取 NALU 后,先解析NAL Header,通过nal_unit_type判断 NALU 类型:
若为 SPS(nal_unit_type=7)或 PPS(nal_unit_type=8),则解析并存储参数集(SPS/PPS 需优先解析,后续 Slice 解码依赖这些参数)。
若为 Slice 数据(nal_unit_type=1-5等),则进入 Slice 解析流程。

2.3. Slice 解析

Slice 解析是核心步骤,依赖已解析的 SPS 和 PPS,流程如下:
解析 Slice 头部:获取slice_type(确定宏块类型)、POC(确定显示顺序)、参考帧列表等信息。
宏块解析:按顺序解析 Slice 内的每个宏块:
若为 I 宏块:执行帧内预测(根据 SPS 中的帧内预测模式,如 16x16、8x8 或 4x4 模式,用相邻已重构像素预测当前块)。
若为 P/B 宏块:执行帧间预测(根据运动矢量从参考帧中找到匹配块,计算预测值)。
残差恢复:对量化后的残差数据执行反量化和反变换(H.264 用 4x4 或 8x8 整数 DCT 变换,避免浮点运算),得到原始残差。
像素重构:将预测值与残差相加,得到重构像素。

2.4. 去块滤波(Deblocking Filter)

重构后的图像可能因宏块边界的量化误差产生 “方块效应”(块边缘明显),需通过去块滤波平滑边界:对宏块边缘的像素进行加权平均,在不模糊细节的前提下减少块效应,提升视觉质量。

2.5. 图像合成与输出

所有 Slice 解析完成后,合成完整的图像,根据 POC 调整显示顺序(尤其是 B 帧,解码顺序可能晚于显示顺序),最终输出解码后的视频帧。

总结

编码结构:H.264 通过 VCL(负责压缩)和 NAL(负责网络适配)分层设计,核心数据单元包括 NALU、参数集(SPS/PPS)、Slice、宏块,形成从序列到像素的多级结构。
解析过程:从码流中提取 NALU,解析 SPS/PPS 获取全局参数,再按 Slice→宏块的顺序解析,通过预测、残差恢复、去块滤波等步骤重构原始视频帧,最终输出连续的解码图像。
这种结构既保证了高效的压缩性能(通过帧内 / 帧间预测、变换量化),又具备良好的网络适应性(通过 NAL 的封装和 Slice 的独立解码),使其成为视频编码领域的经典标准。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SY.ZHOU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值