视频编解码器(Video Codec)是把原始视频帧压缩成码流、再把码流还原成可显示帧的规则或实现;常见标准包括 H.264(AVC)、H.265(HEVC)、VP9 和 AV1。
“codec” 可以指编码标准,也可以指具体软件库或硬件模块。讨论兼容性时要区分:文件里是什么编码格式、播放器用什么解码实现、设备是否支持硬件加速。
核心问题
原始视频数据量非常大。以 1920x1080、30 fps、8-bit YUV 4:2:0 为例,一个像素平均约 12 bit:
raw_bitrate = width * height * fps * bits_per_pixel
= 1920 * 1080 * 30 * 12
~= 746 Mbpswidth和height是画面分辨率。fps是每秒帧数。bits_per_pixel是平均每个像素需要的位数;8-bit YUV 4:2:0 因色度降采样,平均约 12 bit。raw_bitrate是未压缩数据吞吐,不包含容器、音频或协议开销。
这个量级不适合普通网络传输和长时间存储,所以视频编码器需要去掉空间冗余、时间冗余和视觉上不敏感的信息。
核心对象
| 对象 | 作用 |
|---|---|
| raw frame | 未压缩或接近未压缩的视频帧 |
| encoder | 把 raw frame 压缩成码流 |
| decoder | 把压缩码流重建成可显示帧 |
| bitstream | 编码后的二进制语法和数据 |
| I/P/B frame | 不同引用关系的帧类型 |
| GOP | 一组按引用关系组织的图片序列 |
| profile / level | 标准中定义的工具集合和能力边界 |
| container | 承载视频、音频、字幕和时间戳的文件或流格式 |
核心机制
多数现代有损视频编解码器遵循类似管线:
- 预测:用同一帧邻近像素做帧内预测,或用参考帧做帧间预测。
- 求残差:计算真实块和预测块之间的差值。
- 变换:把残差从像素域变换到更利于压缩的系数域。
- 量化:把系数按精度压缩,丢掉部分不敏感细节。
- 熵编码:用熵编码把符号进一步压成较短比特表示。
- 解码重建:解码端按相反方向重建近似帧,并维护参考帧。
关键公式可以写成:
bitstream = entropy_encode(quantize(transform(frame - prediction)))frame是待编码的原始图像块。prediction是编码器从邻近像素或参考帧生成的预测块。frame - prediction是残差;如果预测准确,残差更小、更容易压缩。transform(...)让残差信息集中到少量系数上。quantize(...)是主要有损步骤,决定码率和画质。entropy_encode(...)是无损压缩步骤,用概率模型减少符号表示长度。
解码端没有原始 frame,只能从码流恢复预测方式和量化后的残差,所以编码器和解码器必须严格遵守同一个标准语法。
工程用途
边界与常见坑
- codec 不是 container:H.264/H.265 是编码格式;MP4/MKV/FLV 是容器。
- encoder 不是 decoder:编码端负责搜索和取舍,通常比解码端重得多。
- 标准不是实现:同是 H.264,x264、OpenH264、硬件编码器和浏览器解码器的质量、延迟和兼容性可能不同。
- 低码率不是免费午餐:低码率可能带来块效应、拖影、细节丢失或更高解码复杂度。
- 能播放不代表适合实时:播放器缓冲、B 帧、GOP 长度和硬件队列都会影响端到端延迟。