当前位置: 首页 > news >正文

FFMPEG将H264转HEVC时,码率缩小多少好,以及如何通过SSIM(Structural Similarity Index结构相似性指数)衡量转码损失

最近整理一些视频,我发现太多了,就想把一些本来就需要转码的视频缩小一下。因为转码的时候为了弥补损失,我将码率增大了 10-20%,但是如果将 H264 转 HEVC(当然也可以是其他格式),那么或许不用增大码率甚至可以减少码率。

但是码率缩小多少好呢?

HEVC 的体积一般是 H264 的 50-80%,但是这个跨度也不小。

肉眼观察太难评了,而且每次都这样很麻烦,我就找了一些技术评判方法,来找到合理的缩小值。

FFMPEG 支持 SSIM(Structural Similarity Index,结构相似性指数),可以评估两个视频之间的差别。我们就使用这个指标。

在转码的时候,我们首先要考虑原视频的码率。因为码率极大的情况下,码率哪怕只有原来的 5%,效果也不会下降太多。而在低码率的情况下,下降 50% 就会带来很大的影响。

其次我们需要考虑我们能接受的损失程度是多少。要做到这点,需要通过实验,建立 SSIM 和人肉眼看到的情况之间的关系。

SSIM 测试

这里需要说明一下,SSIM 只是一个参考,它只是从某种角度上表示转码前后的损失度,重点还是我们肉眼看到的情况。

首先这个测试分两类:第一次我用 Blackmagic Camera 这个 App 拍摄 220Mbps 码率的 4K H264 视频,文件大小 80MB;第二次我截取一个 5700Kbps 1080P 流媒体电影片段,文件大小 100 MB,分别代表两种可能的情况。

本节转码时,编码均使用显卡加速。

对比测试命令如下:

ffmpeg -i 第一个文件路径 -i 第二个文件路径 -lavfi "[0:v]settb=AVTB,setpts=PTS-STARTPTS[main];[1:v]settb=AVTB,setpts=PTS-STARTPTS[ref];[main][ref]ssim" -f null -

这里我使用的是-lavfi "[0:v]settb=AVTB,setpts=PTS-STARTPTS[main];[1:v]settb=AVTB,setpts=PTS-STARTPTS[ref];[main][ref]ssim",而不是网上常见的-filter_complex ssim,是因为我的两个视频如果用这个会识别错误。你可以根据你自己的情况修改一下。

你会看到一个类似编码的过程,然后看到最终的结果:

SSIM Y:0.986175 (18.593297) U:0.995715 (23.680221) V:0.995205 (23.192565) All:0.989270 (19.693974)

它分别显示了 YUV 和总共的 SSIM。

可以看到在高码率的情况下,视频压到 10% 码率的时候曲线才出现了波动,当然在肉眼观察的时候也发现此处开始,画质有明显的下降,比如没有那么锐利了(由于素材不咋地,就不放截图了)。

请添加图片描述

我们把图表纵轴上下限修改一下,可以更精确的看到变化情况:

请添加图片描述

当在常见的流媒体码率下,只要压到 50% 左右,SSIM 就开始有较大损失,虽然肉眼可以发现画质损失了,但是不明显,依旧属于能看。但是当压到 10% 的时候,那就很无语了。

注意下图的上下限和上图不一样。

请添加图片描述

下面第一张是原文件,第二张是 45% 码率的,第三张是 10% 码率的。可以看到第三张的画质损失严重:

请添加图片描述
请添加图片描述
请添加图片描述

根据数据可以发现,如果码率相比 100% 码率的情况下, SSIM 差距达到 0.01,那么画质会有肉眼可见的损失。如果达到 0.05 -0.1,那么会有很严重的画质损失。

SSIM 仅供参考

这里再次强调一下,SSIM 只是一个参考,它只是从某种角度上表示转码前后的损失度,重点还是我们肉眼看到的情况。不要本末倒置。

比如在一些特殊情况下,两个完全不同的视频的 SSIM 可能能达到 0.9 的级别。只不过我们在测试原视频和转码文件的时候这个指标可以当做参考。

同码率下转码一定有损失

首先这种换编码的转化一定有损失,那怕不降低码率甚至提高 20% 的码率也会有损失,上面的测试中你也可以看到 100% 的时候 SSIM 也不为 1(5700K 测试 为 0.992643,而 220m 的结果为 0.896002)。如果你使用--lossless可以保证无损,但是码率会高很多,不划算。

关于无损转码的详细说明可以看 x265 - readthedocs。

选择 75% 码率

根据上面的测试,我们可以看到 50% 左右一定会损失画质,只是不明显罢了,但是 50% 到 100% 这区间,可以看到变化不大,我们可以取中间值。

此外,在 Blackmagic Camera App 中, H264 的编码为 220Mbps,而 HEVC 的编码为 160Mbps,约为73%。

所以选择 75% 码率是一个比较合理的选项。

在完整转码一个约 680 MB 的文件视频后,得到 SSIM 为 0.989270,肉眼可见没啥区别。证明这个比例是比较合适的,节约了四分之一的体积,虽然小文件没什么区别,但是 1TB 变成 0.75 TB,还是差距巨大的

H264 转 HEVC

在使用 FFMPEG 将 H264 转为 HEVC,请使用以下命令:

ffmpeg -c:v h264_cuvid -i 输入文件路径 -c:v hevc_nvenc -b:v 码率 -tag:v hvc1 输出文件路径

解释一下:

  • -c:v libx265:表示使用 libx265 软件编码器。
  • -b:v 码率:这里设置码率,需要注意如果是大码率,比如上面的 220Mbps 这种级别,不要使用220m,而是应该使用220000k,因为前者可能会导致转码后的码率非常低,比如我在测试过程中发现,使用220m转码后只有7562 kb/s,这差距太大了。
  • -tag:v hvc1:这部分是为了支持 Apple 的 HEVC,不然你转码完的视频会发现无法使用 Mac 等苹果设备的播放器播放。

如果你需要使用 Nvidia 硬件加速,那么使用以下命令:

ffmpeg -c:v h264_cuvid -i 输入文件路径 -c:v hevc_nvenc -b:v 码率 -tag:v hvc1 输出文件路径

解释一下:

  • -c:v h264_cuvid表示使用硬件解码器。如果你的格式出现问题,那么不要用这个,使用软件解码兼容性更高,而且速度没啥区别,就是 CPU 利用率高。
  • -c:v hevc_nvenc:表示使用 NVENC 的 HEVC 硬件编码器。

希望能帮到有需要的人~

参考资料/扩展阅读

Structural similarity index measure - Wikipedia:SSIM 的维基百科,里面解释了 SSIM 是如何计算的。

H.265/HEVC Video Encoding Guide - FFMPEG:FFMPEG 官方关于 HEVC 的编码指南。如果你需要使用 HEVC 编码,那么建议看看这个指南。

11.237 ssim - FFmpeg Filters Documentation:FFMPEG 关于 SSIM 的文档。

此外感谢豆包帮我把输出转换成表格,方便我制图。

http://www.dtcms.com/a/322572.html

相关文章:

  • 大语言模型概述
  • day15 - CSS3新增属性
  • Java Callback 实现线程切换以及与Kotlin原理关系
  • MySQL(188)如何使用MySQL的慢查询工具?
  • 驾驶场景玩手机识别准确率↑32%:陌讯动态特征融合算法实战解析
  • 用生活日常的案例来介绍“程序运行时,对函数的调用一般有两种形式:传值调用和引用调用 和 这两种调用有什么区别?
  • 使用Navicat备份数据库MySQL、PostGreSQL等
  • SqlSugar vs EF Core 对比 2025年 .NET ORM
  • ES6中箭头函数的作用
  • C++-红黑树
  • 电子电气架构 --- 48伏电气系统架构
  • 串扰-信号完整性与电源完整性分析
  • C++安全异常设计
  • 浅尝AI辅助C转Verilog方法
  • 阿里云 ECS 怎么用 nginx 部署80端口多个网站
  • 无印良品:回归本质的管理哲学
  • 海康威视摄像头实时推流到阿里云公网服务器(Windows + FFmpeg + nginx-rtmp)
  • webrtc弱网-BandwidthQualityScaler 源码分析与算法原理
  • Ruoyi-Vue-Plus 修改包名、模块名、项目名
  • MySQL 临时表详细说明
  • 20.万物皆可变身术:状态模式架构全景解析
  • 【Git】Visual Studio 实现合并分支
  • 在 Ubuntu 中测试串口通信:详细指南与实践
  • 【面试场景题】微博热点新闻系统设计方案
  • 容器docker场景下新增接口测试及工具使用方法介绍
  • 人工智能技术发展历史演变
  • Java基础-TCP通信(多发多收和一发一收)
  • 八、Linux Shell 脚本:变量与字符串
  • Dotenv 入门教程
  • 政府数字化大屏系统 - Flask实现方案