H.264 编码基础
H.264 也叫 AVC(Advanced Video Coding),是目前应用最广泛的视频编码标准。
H.264 是什么
H.264 是由 ITU-T 和 ISO/IEC 联合制定的视频压缩标准,通过帧内预测、帧间预测、变换编码、熵编码等技术大幅压缩视频数据。
原始视频 (YUV 原始帧)
↓ [H.264 编码]
H.264 码流 (NALU 序列)
压缩比通常 50:1 ~ 200:1核心概念
I 帧 / P 帧 / B 帧
| 帧类型 | 全称 | 特点 |
|---|---|---|
| I 帧 | Intra Frame(帧内) | 独立编码,不参考其他帧,体积最大,随机访问点 |
| P 帧 | Predicted Frame(预测) | 参考前面的 I/P 帧,用运动补偿压缩,体积较小 |
| B 帧 | Bi-predicted Frame(双向预测) | 参考前后帧,压缩率最高,延迟高 |
GOP (Group of Pictures)
一组连续的帧,从 I 帧开始,到下一个 I 帧前结束。
I P P P B B P P | I P P ...
└───────────┬───────────┘
GOPGOP 越大,压缩率越高,但随机访问和恢复越慢。
H.264 编码流程
原始帧 → 帧内/帧间预测 → 残差 → DCT变换 → 量化 → 熵编码 → 码流
↓
运动估计/补偿- 预测:利用空间或时间相关性预测像素值
- 残差:原始值 - 预测值 = 残差
- DCT 变换:将空域残差转换到频域
- 量化:丢弃高频细节(人眼不敏感)
- 熵编码:对量化后的数据做无损压缩(CAVLC / CABAC)
NALU(网络抽象层单元)
H.264 码流由一系列 NALU 组成。每个 NALU 是一个独立的数据单元。
NALU 类型
| 类型 | 值 | 说明 |
|---|---|---|
| NAL_IDR_SLICE | 5 | IDR 帧(即时解码刷新,一种特殊 I 帧) |
| NAL_SLICE | 1 | 非 IDR 的普通帧 |
| NAL_SPS | 7 | 序列参数集(Sequence Parameter Set) |
| NAL_PPS | 8 | 图像参数集(Picture Parameter Set) |
| NAL_AUD | 9 | 访问单元分隔符 |
| NAL_SEI | 6 | 补充增强信息 |
💡 SPS/PPS 非常重要,包含了解码所需的参数(分辨率、Profile、Level 等)。播放器必须先拿到 SPS/PPS 才能解码。
NALU 起始码
Annex-B 格式的 NALU 以起始码开头:
00 00 00 01 (4字节起始码)
或
00 00 01 (3字节起始码)后面紧跟 NALU header(1字节)和 NALU 数据。
Profile 和 Level
Profile(档次)
| Profile | 说明 | 应用场景 |
|---|---|---|
| Baseline | 最基础,只有 I/P 帧,CAVLC | 视频会议、低延迟 |
| Main | 增加 B 帧、CABAC、隔行 | 流媒体、广播 |
| High | 8x8 变换、自定义量化矩阵等 | 高清存储(蓝光) |
Level(级别)
规定了最大分辨率、帧率、码率等参数限制。
常见 Level:
- 3.1 — 最高 1280×720 @ 30fps
- 4.0 — 最高 1920×1080 @ 30fps
- 4.1 — 最高 1920×1080 @ 60fps
- 5.1 — 最高 4096×2048 @ 30fps
码率控制模式
| 模式 | 说明 | 适用场景 |
|---|---|---|
| CBR (Constant Bitrate) | 固定码率,输出码率稳定 | 直播、流媒体 |
| VBR (Variable Bitrate) | 可变码率,简单画面码率低,复杂画面码率高 | 存储、点播 |
| CQP (Constant QP) | 固定量化参数,画质稳定 | 质量对比测试 |
| AVBR (Average VBR) | 平均可变码率,在设定平均码率附近波动 | 一般场景 |
Rockchip MPP 编码
瑞芯微平台使用 MPP(Media Process Platform)进行硬件编码。
MPP 编码基本流程c
// 1. 创建编码上下文
MppCtx ctx;
mpp_create(&ctx, NULL);
mpp_init(ctx, MPP_CTX_ENC, MPP_VIDEO_CodingAVC);
// 2. 配置编码参数
MppEncCfg cfg;
mpp_enc_cfg_init(&cfg);
cfg.width = 1920;
cfg.height = 1080;
cfg.fps = 30;
cfg.bitrate = 4000; // kbps
cfg.gop = 30; // I帧间隔
mpp_control(ctx, MPP_ENC_SET_CFG, cfg);
// 3. 输入帧,获取码流
// mpp_encode_put_frame(ctx, frame);
// mpp_encode_get_packet(ctx, &packet);
// 4. 释放
mpp_destroy(ctx);常见问题
花屏/马赛克
- 缺少 SPS/PPS
- 丢帧导致参考帧缺失
- 分辨率或格式不匹配
码率不准
- 码率控制模式选择不当
- GOP 设置不合理
- 画质设置过高/过低
延迟大
- B 帧过多
- 缓冲太大
- GOP 太长
相关知识
- YUV 像素格式
- MPP 编码
- FFmpeg
- RTSP 协议
