跳至正文
老丹的足迹 —— 代码写给机器,游记写给自己,感悟写给时间
老丹的足迹 老丹的足迹
老丹的足迹 老丹的足迹
  • 首页
  • 示例页面
  • 首页
  • 示例页面
老丹的足迹 老丹的足迹
老丹的足迹 老丹的足迹
  • 首页
  • 示例页面
  • 首页
  • 示例页面

深入解析x265:HEVC/H.265编码的核心引擎

一、x265是什么——一个独立的编码库

x265是一个开源的H.265/HEVC(高效视频编码标准)视频编码器库。它是一个完全独立的开源项目,与FFmpeg没有从属关系,两者是各自独立的项目,在生态上形成协作关系。x265由MulticoreWare公司主导开发,项目始于2013年3月,同年7月公开源代码。截至2024年11月,最新版本为4.1。

x265采用GNU GPL 2许可证,同时提供商业授权选项——这意味着如果你想把x265集成到自己的闭源商业软件里,需要向MulticoreWare购买商业许可。这个双许可模式与x264完全一致。

技术上,x265用C++和汇编语言编写,支持HEVC的Main、Main 10及Main Still Picture配置,覆盖8位和10位色深,以及4:2:0、4:2:2、4:4:4色度抽样格式。它充分利用了现代CPU的SIMD指令集(SSE2/AVX2/AVX-512/ARM NEON)进行加速,编码性能得到显著提升。

二、项目起源——x265为何诞生

要理解x265,得先回顾x264的历史。x264是一个开源的H.264/AVC编码器,项目始于2003年,由视频编码领域的传奇开发者Loren Merritt主导。在很长一段时间里,x264被认为是软件H.264编码的黄金标准——速度快、压缩率高、参数可调性极强,被广泛应用于FFmpeg、VLC、OBS等知名开源项目。

然而,2013年H.265/HEVC标准正式发布后,业界迫切需要一款与之对应的开源编码器。x264的开发团队和社区并没有直接”升级”x264,而是开启了一个全新的项目:x265。这是因为H.265相比H.264在算法层面有本质性的变化,无法在原有代码基础上修修补补来实现。

三、x265如何工作——编码流程与核心API

要在你的C++程序里用x265编码视频,核心流程是这样的:

第一步:创建编码器

通过x265_param_alloc()分配参数结构体,调用x265_param_default()填充默认值,然后根据需求修改关键参数(分辨率、帧率、编码预设、CRF值等)。最后调用x265_encoder_open()创建编码器实例。

第二步:获取流头信息

调用x265_encoder_headers()获取SPS(序列参数集)、PPS(图像参数集)、VPS(视频参数集)——这些是解码器必须首先拿到的东西,被称为”extradata”。

第三步:主编码循环

把原始图像帧(x265_picture结构体)一帧一帧喂给编码器。调用的核心函数是:

int x265_encoder_encode(x265_encoder *encoder, 
                        x265_nal **pp_nal, 
                        uint32_t *pi_nal, 
                        x265_picture *pic_in, 
                        x265_picture *pic_out);

它的工作方式是:你输入一帧原始画面(pic_in),它输出一个或多个NAL单元(pp_nal)——也就是H.265码流的基本数据包。需要注意的是,输入帧是按显示顺序(PTS)给的,但编码器内部会重新排队,等你把管道填满之后,每次调用才吐出一帧已编码的输出。

第四步:刷新编码器

所有原始帧送完后,还要继续调用x265_encoder_encode(),pic_in传NULL,让编码器把内部缓冲的帧全部吐出来。这个过程被称为”draining”。

第五步:关闭与清理

调用x265_encoder_close()释放编码器资源,最后调用x265_cleanup()释放全局资源。

四、x265与FFmpeg的关系——各自独立,协作共生

x265和FFmpeg是两个完全独立的项目,各有各的代码仓库、维护团队和发布周期。

FFmpeg是一个庞大而全面的多媒体处理框架,它提供了解封装、解码、滤镜处理、编码、封装等一整套工具链。它自己实现了大量编码器(如libx264、libvpx),但对于H.265编码,它选择通过外部库调用的方式集成x265。在FFmpeg的代码中,H.265编码器被命名为”libx265″。

当你在FFmpeg命令行输入ffmpeg -i input.mp4 -c:v libx265 output.mp4时,实际发生的是:

  • FFmpeg负责读取input.mp4、解封装、解码出原始YUV帧
  • 将这些YUV帧传递给x265编码库
  • x265执行HEVC编码,输出H.265码流
  • FFmpeg接收码流,加上音频轨道,打包成MP4容器

这种协作模式在开源界非常常见:FFmpeg提供框架,x265提供专业算法。你可以把FFmpeg看作”工厂的流水线”,x265则是流水线上负责”H.265压缩”这道工序的专家。

五、编码参数深度解析——从preset到crf

x265的参数体系在视频编码领域堪称丰富。最核心的几个参数如下:

Preset(编码预设)

控制编码速度与压缩效率的权衡。可选值从快到慢依次为:ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、placebo。

编码速度与压缩效率的关系大致如下表:

预设相对medium的速度相对medium的文件体积变化
ultrafast快约50倍大80%-100%
veryfast快约10倍大20%-30%
fast快约2倍大5%-10%
medium基准基准
slow慢约50%小10%-15%
slower慢约4倍小20%-25%
veryslow慢约10倍小25%-30%

placebo是”调试专用”级别,实际生产环境几乎没有使用价值——它比veryslow慢很多,压缩效率提升极其有限。

CRF(恒定质量因子)

CRF是x265最推荐的质量控制模式。它的取值范围是0到51,数值越小画质越好,文件越大。典型取值范围是18到28:

  • CRF 18-20:接近视觉无损,适合存档
  • CRF 20-22:高画质,适合电影级素材
  • CRF 22-24:平衡点,日常使用最广泛
  • CRF 24-28:网络分发,文件小,画质可接受

码率控制模式

除了CRF,x265还支持:

  • 固定QP(量化参数):每个块使用固定的量化步长,简单直接但效率低
  • 平均比特率(ABR):指定目标码率,编码器尽量接近,但可能波动
  • 二次编码(2-pass):第一遍分析视频复杂度,第二遍精确分配码率,文件大小最可预测
  • VBV缓冲区控制:用于流媒体场景,防止码率突发导致播放缓冲

视觉优化算法

x265集成了多种人眼视觉优化算法:

  • CU-tree(编码树单元级别的码率分配):根据帧间预测情况,在I帧和P帧之间重新分配码率
  • 自适应量化(AQ):根据画面纹理复杂度动态调整QP值,平坦区域少给码率,复杂区域多给
  • B-pyramid:B帧可以被其他B帧用作参考,提高压缩效率
  • 加权预测:针对淡入淡出等亮度变化场景的优化
  • 心理视觉优化(psy-rd和psy-rdoq):牺牲一点点客观PSNR指标,换取更好的主观视觉感受

六、实际使用方式

x265有三种主流的使用方式:

方式一:命令行独立使用

直接使用x265可执行文件编码原始YUV文件:

x265 --input input.yuv --fps 25 --input-res 1920x1080 --crf 22 -o output.hevc

适合测试和实验,但在实际工作流中较少单独使用。

方式二:通过FFmpeg调用(最常用)

这是绝大多数人的使用方式:

ffmpeg -i input.mp4 -c:v libx265 -preset medium -crf 22 -c:a aac -b:a 128k output.mp4

如果需要传递x265专属参数,可以用-x265-params:

ffmpeg -i input.mp4 -c:v libx265 -x265-params "crf=22:psy-rd=2.0:aq-mode=3" output.mp4

方式三:在你的C++程序中直接调用API

这就是你之前想尝试的方式——在自己的程序里直接调用x265的C++ API,配合FFmpeg的libavformat完成解封装和封装,实现一个完整的转码器。

七、与FFmpeg内部编码器的对比

这里需要澄清一个重要的区别:x265不是FFmpeg的一部分,它是独立的编码器库。

FFmpeg也有自己的H.265编码器实现(叫做”hevc_vaapi”或”hevc_nvenc”等),但这些通常是硬件加速编码器,依赖特定的GPU硬件。而x265是纯软件编码器,不依赖特定硬件,可以在任何CPU上运行。

在FFmpeg的命令行中,区分它们的方式是编码器名称:

  • libx265:调用外部的x265库(软件编码)
  • hevc_nvenc:调用NVIDIA GPU的硬件编码器
  • hevc_qsv:调用Intel QuickSync硬件编码器
  • hevc_amf:调用AMD硬件编码器

八、x265与新一代编码器

值得提及的是,H.265的后继者H.266/VVC(Versatile Video Coding)已经于2020年正式发布,目标是再省50%的码率。对应的开源编码器叫vvenc,由Fraunhofer HHI开发,FFmpeg从7.1版本开始已经支持集成vvenc。

不过目前H.266的软硬件生态远不如H.265成熟,x265在未来很长一段时间内仍是实际应用中的主力编码器。

总结

x265的本质:一个用C++实现HEVC标准的开源视频编码库。它独立于FFmpeg,两者是协作关系而非从属关系。它把极其复杂的HEVC编码算法封装成了一个可调用的API,让开发者能够在自己的程序中嵌入H.265编码能力。

理解x265的核心就是这三件事:

  1. 它能做什么:把原始视频画面(YUV)压缩成H.265码流
  2. 它怎么用:通过API调用(编码器生命周期、喂帧、取码流)
  3. 它调什么:preset(速度)、crf(质量)、各种视觉优化参数

掌握了这三个维度,你就真正理解了x265。

作者

老丹

关注我
其他文章
上一个

YUV色彩空间完全指南:从概念原理到工程实战

下一个

HandBrake完全指南:从入门到精通的开源视频转码工具

关于博主

    老丹是一名C/C++后台开发工程师,信奉“无抽象不设计,无性能不生产”。

  • 技术栈:Modern C++、Linux环境编程、多线程/并发、网络编程等。
  • 信条:能用constexpr解决的问题绝不拖到运行时,能靠RAII避免的泄漏绝不写析构。
  • 正在填坑:从解封装到渲染的C++全链路实现,正在驯服FFmpeg与H.264/H.265。
  • 输出原则:这里的每一段代码都经过-Wall -Wextra -Werror -O2的洗礼。

近期文章

  • Ubuntu 防火墙迁移指南:从 UFW 到 firewalld 的完整实践 2026年9月12日
  • Nano 编辑器完全操作指南:从入门到熟练 2026年9月12日
  • SSCG:让自签名证书不再“危险”的生成工具 2026年9月12日
  • Ubuntu Samba 服务安装与配置完全指南 2026年9月12日
  • 从零开始:用 Docker 部署 Jellyfin 并启用英特尔核显硬件加速 2026年9月11日

文章分类

  • C/C++开发 (22)
  • Docker容器 (5)
  • Linux工具包 (17)
  • Linux服务配置 (50)
  • Linux系统 (16)
  • OpenWrt路由 (3)
  • Shell脚本 (3)
  • 代码管理 (1)
  • 安防技术 (4)
  • 数据安全 (36)
  • 未分类 (1)
  • 网络协议 (25)
  • 计算机理论 (23)
  • 音视频技术 (5)
联系我们:📍 地址:中国·广东省深圳市   |   ✉️ 邮箱:support@tanglinux.com   |   💬 QQ:870866607
版权所有:老丹的足迹粤ICP备2026061170号-1       公安备案图标 粤公网安备44030002013274号