x264 — H.264/AVC 编码器
待复核x264 是一个把原始视频压成 H.264/AVC 码流的开源编码器。日常类比:它像一个特别会打包行李的人,同样一箱衣服,普通人塞不下,它能按重要程度折叠、压缩、分层,让箱子更小但打开后仍然像原来那样可用。
最小例子来自它自己的命令行帮助:
x264 --crf 24 -o output.264 input.y4m这行命令的意思是:读入 input.y4m 这样的原始或接近原始的视频,用质量优先的 CRF 24 压成 H.264 裸码流,写到 output.264。
如果 ffmpeg 是一个多媒体瑞士军刀,x264 就是其中最有名的 H.264 刀片之一;如果 handbrake 是带按钮的转码软件,x264 就是它背后真正做 H.264 压缩的发动机之一。
不理解 x264,下面这些事就不好解释:
- 为什么同一个 1080p 视频,H.264 能从几十 GB 原始数据压到几百 MB,还能正常播放。
- 为什么视频工具里总有
CRF、bitrate、preset、profile这些词,它们其实是在控制编码器怎么花比特。 - 为什么”压得快”和”压得小、画质好”经常冲突,x264 的 preset 就是在替你选择这个取舍。
- 为什么直播、点播、归档、测试 PSNR 会用不同参数,因为它们追求的不是同一个目标。
-
率控是会计:x264 的 ratecontrol 决定每一帧、每个宏块该花多少比特。类比:家庭预算不是每一天平均花钱,而是把钱留给更重要的日子;复杂运动、关键参考帧通常更值得花比特。
-
preset 是速度档位:
ultrafast到placebo不是画质档,而是”愿意花多少 CPU 时间找更好压缩方案”的档位。类比:收拾行李可以随手塞,也可以花两小时卷衣服、抽真空,后者更省空间但更慢。 -
profile/tune 是约束和偏好:
profile让码流符合某类播放器能力,tune按素材或目标微调,例如film、grain、fastdecode、zerolatency。类比:同一份菜谱,给老人、运动员、赶时间的人吃,调味和切法会不同。
案例 1:日常转码用 CRF 固定主观质量
Section titled “案例 1:日常转码用 CRF 固定主观质量”x264 --preset slow --crf 22 -o movie.264 movie.y4m逐部分解释:
--crf 22:告诉 x264 “我更关心稳定观感,不指定最终文件大小”。--preset slow:让编码器多花一些时间搜索运动、参考帧和模式,通常能在同等观感下省空间。-o movie.264 movie.y4m:前者是输出 H.264 码流,后者是输入视频。
这个案例适合个人压片、离线归档和上传前预处理。ratecontrol 文档里说,恒定质量不等于恒定 QP,也不等于恒定 PSNR;人眼对复杂运动和静止画面的敏感度不同,所以编码器要动态分配比特。
案例 2:交付固定大小时用二遍编码
Section titled “案例 2:交付固定大小时用二遍编码”x264 --pass 1 --bitrate 1000 -o /dev/null trailer.y4mx264 --pass 2 --bitrate 1000 -o trailer.264 trailer.y4m逐部分解释:
- 第一遍不追求最终画质,主要收集每帧复杂度、运动和场景信息。
- 第二遍用第一遍的统计文件,把总码率压到接近
1000 kbit/s,同时尽量把比特分给更需要的片段。 --bitrate 1000是平均目标,不是每一秒都刚好 1000 kbit。
这个案例适合”必须塞进某个大小”的场景,例如老式下载站、固定带宽分发、课程平台批量转码。x264 的 ratecontrol 文档把二遍编码拆成三步:先估相对分配,再缩放到目标大小,最后边编码边修正预测误差。
案例 3:直播/低延迟用 VBV 和 zerolatency
Section titled “案例 3:直播/低延迟用 VBV 和 zerolatency”x264 --preset veryfast --tune zerolatency \ --bitrate 1000 --vbv-bufsize 2000 \ -o live.264 live.y4m逐部分解释:
--bitrate 1000:给直播链路一个平均码率目标,方便估算带宽。--vbv-bufsize 2000:限制短时间内的码率波动,类似给播放器一个 2 秒缓冲水箱。--tune zerolatency:关闭或缩短会增加延迟的结构,例如 B 帧、lookahead、MB-tree 等。--preset veryfast:直播更怕来不及编码,所以宁愿牺牲一点压缩效率。
这个案例适合实时推流、互动课堂和视频会议中的服务端转码。threads 文档也提醒:低延迟切片线程会降低压缩效率,因为 slice header、CABAC 上下文重置和边界预测都会额外花比特。
-
把 CRF 当成码率:
--crf 22不保证文件大小,它保证的是质量目标;内容越复杂,文件越大。 -
迷信 placebo:x264 头文件提醒 preset 速度差异非常夸张,
placebo往往慢很多但收益很小,不适合日常生产。 -
只看 PSNR 忘了人眼:
--tune psnr是测试指标用的,不一定让人看起来更舒服;视觉优化有时会故意牺牲 PSNR。 -
随便开 sliced threads:切片线程能降延迟,但会破坏跨切片预测、重置 CABAC,常见结果是同码率画质下降。
适用 vs 不适用场景
Section titled “适用 vs 不适用场景”适用:
- 把原始或中间格式视频编码成 H.264,用于网页、移动端、机顶盒和老设备播放。
- 做离线压片、归档、批量转码,需要在画质、体积和速度之间精细取舍。
- 研究视频编码算法,尤其是 motion estimation、rate control、macroblock decision 这些工程细节。
- 作为底层库被 ffmpeg、handbrake、转码服务或自研媒体管线调用。
不适用:
- 只想剪辑、加字幕、混音或改容器;这些应该用 ffmpeg、shotcut 或 mlt。
- 追求 HEVC/H.265、AV1、VP9 等新编码格式;x264 只做 H.264/AVC。
- 需要完全无专利风险的分发策略;H.264 标准本身有复杂的专利背景,项目开源不等于标准无约束。
- 零基础用户想点按钮完成转码;直接用 handbrake 更友好。
历史小故事(可跳过)
Section titled “历史小故事(可跳过)”- 2003 年前后:H.264/AVC 标准逐渐成形,行业需要一个高质量、可研究、可集成的软件编码器。
- VideoLAN 生态:x264 长期在 VideoLAN 相关基础设施中演进,GitHub 上的
mirror/x264是镜像,不是唯一主阵地。 - 算法贡献者:AUTHORS 里能看到维护者长期围绕 motion estimation、rate control、RDO、多线程和 x86 汇编优化打磨。
- 工程路线:项目坚持 C + 手写 SIMD 的高性能路线,很多优化不是”换个参数”,而是深入 CPU 指令、缓存和预测结构。
- 社区影响:它的 GitHub star 不能完全代表影响力;更大的影响藏在 FFmpeg、HandBrake、VLC 和无数视频平台的转码链路里。
- 编码器是在做预算分配:视频压缩不是平均删信息,而是判断哪些像素、哪些帧、哪些运动线索更值得保存。
- 参数背后是取舍:
CRF、bitrate、preset、tune、profile都是在回答”我要质量、大小、速度、兼容性里的哪一个”。 - 事实标准来自长期打磨:x264 的价值不是接口多漂亮,而是多年算法、汇编、多线程和边界案例沉淀出来的可靠性。
- 媒体工程很少有万能参数:离线电影、直播、移动端兼容、指标测试,各自都有不同的好参数。
- mirror/x264 GitHub 仓库 —— 代码、GPL 许可证、
doc/目录和example.c。 - x264 ratecontrol 文档 —— 理解 CRF、ABR、CBR、二遍编码的核心来源。
- x264 threads 文档 —— 理解 frame threads 与 sliced threads 的速度/质量取舍。
- x264 VUI 文档 —— 解释 SAR、range、color primaries、chroma location 等播放提示。
- ffmpeg —— 最常见的上层命令行入口,常通过
libx264调用 x264。 - handbrake —— 把 x264 等编码器包装成普通用户能操作的 GUI。
- ffmpeg —— x264 常作为 FFmpeg 的
libx264编码器使用,负责 H.264 压缩。 - handbrake —— HandBrake 的 H.264 软件编码能力依赖 x264 这类底层编码器。
- gstreamer —— 媒体管线框架,能把采集、滤镜、编码、封装串成流水线。
- mlt —— 视频编辑引擎更关注时间线和效果,最终导出时仍会遇到编码器选择。
- shotcut —— 面向用户的剪辑工具,和 x264 的关系类似”操作台”和”发动机”。
- salsify-2018 —— 研究网络传输与编码器协同,能帮助理解为什么码率控制不只是编码器内部问题。
- gcc-webrtc-2016 —— 实时视频拥塞控制,与 x264 的 VBV/低延迟取舍形成上下游关系。