当前位置: 首页 > 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.xdnf.cn/news/1270369.html

相关文章:

  • 使用Navicat备份数据库MySQL、PostGreSQL等
  • Meta AI水印计划的致命缺陷——IEEE Spectrum深度文献精读
  • (nice!!!)(LeetCode 面试经典 150 题) 146. LRU 缓存 (哈希表+双向链表)
  • 力扣热题100------70.爬楼梯
  • 如何解决 Vue 项目启动时出现的 “No such module: http_parser” 错误问题
  • Cherryusb UAC例程对接STM32内置ADC和DAC播放音乐和录音(中)=>UAC+STM32 ADC+DAC实现录音和播放
  • traceroute命令调试网络
  • C++高频知识点(十七)
  • 《Resolving tissue complexity by multimodal spatial omics modeling with MISO》
  • 9. 堆和栈有什么区别
  • Vitalik谈以太坊:ETH财库储备策略“有益且有价值”
  • Kotlin 协程线程切换机制详解
  • AG32cpld实现一个UartTx“外设”
  • 智慧能源设备巡检缺陷漏检率↓76%:陌讯多模态融合算法实战解析
  • Android适配最新SplashScreen方案:让启动页不再“翻车“
  • webrtc弱网-BandwidthQualityScaler 源码分析与算法原理
  • 视图是什么?有什么用?什么时候用?MySQL中的视图
  • Android MediaCodec 音视频编解码技术详解
  • linux php版本降级,dnf版本控制
  • Amazon Linux 训练lora模型的方式
  • Web自动化技术选择
  • 回答“http协议 ,js组件化,工程化, seo优化策略 ,针对不同平台终端适配 web标注和兼容性”
  • 基于遗传优化的智能灌溉系统控制策略matlab仿真
  • Beelzebub靶机通关教程
  • 【工具】Python多环境管理
  • 【Java基础】字符串不可变性、string的intern原理
  • 【李宏毅-2024】第六讲 大语言模型的训练过程1——预训练(Pre-training)
  • 搭建若依前后端分离版本的开发环境
  • 鸿蒙分布式任务调度深度剖析:跨设备并行计算的最佳实践
  • 在nodejs中使用Java方法