跳转到正文
知识笔记
通用📖 学习中

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 ...
└───────────┬───────────┘
            GOP

GOP 越大,压缩率越高,但随机访问和恢复越慢。


H.264 编码流程 ​

原始帧 → 帧内/帧间预测 → 残差 → DCT变换 → 量化 → 熵编码 → 码流
                    ↓
                运动估计/补偿
  1. 预测:利用空间或时间相关性预测像素值
  2. 残差:原始值 - 预测值 = 残差
  3. DCT 变换:将空域残差转换到频域
  4. 量化:丢弃高频细节(人眼不敏感)
  5. 熵编码:对量化后的数据做无损压缩(CAVLC / CABAC)

NALU(网络抽象层单元) ​

H.264 码流由一系列 NALU 组成。每个 NALU 是一个独立的数据单元。

NALU 类型 ​

类型值说明
NAL_IDR_SLICE5IDR 帧(即时解码刷新,一种特殊 I 帧)
NAL_SLICE1非 IDR 的普通帧
NAL_SPS7序列参数集(Sequence Parameter Set)
NAL_PPS8图像参数集(Picture Parameter Set)
NAL_AUD9访问单元分隔符
NAL_SEI6补充增强信息

💡 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、隔行流媒体、广播
High8x8 变换、自定义量化矩阵等高清存储(蓝光)

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 太长

相关知识 ​

相关实验 ​