FFmpeg H.264编码器指南[译]
H264 视频编码器指南
本指引着眼于x264编码器,这里假设你的FFmpeg 编译了--enable-libx264支持。如果你需要编译支持的帮助请看这篇文档:https://trac.ffmpeg.org/wiki/CompilationGuide,看 HWAccelIntro关于支持H264编码器在逻辑上的支持;
有两种适用于大部分场景的码率控制模式:
Constant Rate Factor (CRF) : 恒定码率因子模式
Two-Pass ABR: 两遍式控制模式
码率控制是指每帧需要处理多少bits的数据。码率控制会决定视频文件的大小和质量的优劣。需要更多关于码率控制模式的区别,请看这篇文章
CRF-- 恒定码率因子模式
推荐在你需要保证视频的质量最佳,而完全不关心视频文件的大小的时候使用这种模式;
这种模式运行编码器当在不关心输出文件的大小时,得到一个一定质量的视频;这种方式可以让一次处理达到一个最大的压缩效果。也可以通过调整每帧所谓的量化因子,可以得到所需的比特率去保证要求的视频质量等级;不过缺点就是你不能指定输出文件的大小或者限制视频不能超过某个大小阈值,也就是说这种方式不推荐用到流式的视频编码。
1、设置CRF的值
CRF的取值范围是0-51,0是画面质量最高的无损(只是针对8bit,10bit的话要用 -qp 0),默认值是23,51的话是画质最差的。值越低,质量越高(可以理解为画面质量的损失值),主管的认为合理的值范围是17-28。
17或者18是肉眼区别不出来的无损或者几乎区分不出来的无损;这时看起来跟输入一样或者非常接近,但技术来说并不是无损的。
CRF的取值范围对画质的影响是指数级别的,所以,参数值+6的结果差不多只有原数值比特率/文件大小的一半。同样,参数值-6会导致大概比特率/文件大小是原来的两倍。
在视频质量可以接受的范围选择一个CRF最大的值。 如果输出画质依旧非常好,再选大一点,如果画质不行,再调小;
注意:0-51 的CRF取值范围仅适用于8-bit 的x264. 如果你编译了10bit的x264,CRF的取值范围是 0-63,(在x264的源码上,它是-12到51,只不过是 FFmpeg的 libx264给包装了一层,做了偏移处理。所以0依旧是无损的,但只在受支持的配置文件中,High 10 不支持无损)。
你可以通过FFmpeg编码处理的控制台输出判断你究竟在用哪种(yuv420p就是8-bit的,yuv420p10le就是10-bit的)。8-bit更常用;
2、选择一个预设值和Tune;
preset--预设值
译者:--preset的参数主要调节编码速度和质量的平衡
预设值是一系列保证确定的编码速度和压缩率的选项值的集合。慢的预设值能提供更好的压缩效率(也就是文件能压缩得更小)。例如,如果你设定了确定的文件大小或者固定的比特率,你能用更慢的预设值得到更好的质量。同样的,对于固定的质量编码,你能通过选择较慢的预设值到简单保存比特率;
选在你耐心范围内最慢的预设值。所有的预设值由慢到快的速度排序如下:
ultrafast(很快,但文件很大 几乎没怎么压缩)superfastveryfastfasterfastmedium– 默认预设值slowslowerveryslow(很慢,但压缩率很高 文件很小)placebo– 忽略这个,这个没啥用 (参考 FAQ)
你可以通过参数:-preset help看到当前的所有预设值。如你安装了x264的库,你也可以用x264 --fullhelp 查看完整的预设设置;
Tune
译者:--tune的参数主要配合视频类型和视觉优化的参数。
你可以用-tune参数去改变你指定的输入的设置,当前的turn有如下值:
film– 适用于高质量的电影,降低去块效应。use for high quality movie content; lowers deblockinganimation– 适用于动画,使用更高级的去块处理和更多的参考帧。 good for cartoons; uses higher deblocking and more reference framesgrain– 保留旧的、颗粒状的影片材料中的颗粒结构。 preserves the grain structure in old, grainy film materialstillimage– 适用于幻灯片式的内容。good for slideshow-like contentfastdecode– 通过关掉某些路径,实现更快的编码。allows faster decoding by disabling certain filterszerolatency– 适用于快的编码和低延迟的流。 good for fast encoding and low-latency streamingpsnr– 忽略此项,编码器开发用的。ignore this as it is only used for codec developmentssim– 忽略此项,编码器开发用的。ignore this as it is only used for codec development
例如,如果你的输入是一个动画你可以用animation,或者你你保留颗粒状在影片里你可以用grain选项。如果你不确定你要用那个选项或者不知道你的输入适用何选项你可以忽略 -tune 选项。你可以用 -tune help查看所用的tune选项列表,或者用 x264 --fullhelp看这些选项设置的含义。
Profile(配置文件)
译者:限制输出文件的profile。这个参数将覆盖其它所有值,此选项能保证输出profile兼容的视频流。如果使用了这个选项,将不能进行无损压缩(qp 0 or crf 0)。
一般不建议设置;
-profile:v 参数将输出限定为特定的H264配置。一般来说你不想理用这个选项,建议忽略这个设置h264会自动选择合适的配置文件;
某些设备(一般是老掉牙的)只支持更多限制的Constrained Baseline 和 Main profiles。你可以设置这些选项值为 -profile:v baseline or -profile:v main. 新设备一般都支持更高级的 High配置文件。
另外要用这个参数的原因是,要去匹配其他用 concat demuxer连接的视频文件。
注意:-profile:v参数不兼容无损的编码,setting -profile:v high444 也是无效的。
x264支持的配置文件如下:
baselinemainhighhigh10(first 10 bit compatible profile)high422(支持yuv420p, yuv422p, yuv420p10le and yuv422p10le)high444(supports as above as well as yuv444p and yuv444p10le)
列出预算和tunes
用以下命令列出当前的预算和tunes:
ffmpeg -hide_banner -f lavfi -i nullsrc -c:v libx264 -preset help -f mp4 -
注意: windows环境要改为:
ffmpeg -hide_banner -f lavfi -i nullsrc -c:v libx264 -preset help -f mp4 NUL
CRF 示例
下面命令用更慢的预设值与更好的压缩,将视频重新编码为质量好的视频。
ffmpeg -i input -c:v libx264 -preset slow -crf 22 -c:a copy output.mkv
注意,这条示例直接用简单拷贝的方式将输入的音频流拷贝到输出而没有重新编码;
如果你要处理一批相似的视频,用统一的设置,能保证这样这批视频的输出质量都接近;
译者:这里的-preset控制的是压缩率和编码速度的,-crf控制输出质量的。
Two-Pass--两遍式
如果你要输出指定大小的文件,并且输出质量和每帧的质量要求没那么高的时候, 那就用这种码率控制模式。这是用示例最好的解释。你的视频时长600秒并且需要输出大小是200MB。根据:bitrate = file size / duration:
(200 MB * 8388.608 [转换MB到KBit(1024*8/1000); 注意不是8192,因为1KBit是1000bit。]) / 600 seconds = ~2796 kBit/s 总比特率
2796 - 128 kBit/s (减去音频比特率) = 2668 kBit/s 是视频的比特率
你也可以忽略什么的计算公式如果你已经知道最终的模板比特率的话。
译者:通过上面的公式,你就能得到一个最终输出文件大小确定的视频;
两遍式示例
对应两遍式,你要用差不多一样参数跑两次,参数不同点如下:
- 在第一遍和第二遍,用
-pass 1和-pass 2选项区别; - 在第一遍,输出是一个空描述,没有一个显式的输出(但会生成一个日志文件ffmpeg在第二遍需要用);
- 在第一遍,你可以用
-an参数剥离音频文件;
注意:第一遍,当用-an参数可能最终得到报段内存错误或者顺坏的文件。这样的话,去掉-an参数改为-vsync cfr就行;
例如:
ffmpeg -y -i input -c:v libx264 -b:v 2600k -pass 1 -an -f null /dev/null && \
ffmpeg -i input -c:v libx264 -b:v 2600k -pass 2 -c:a aac -b:a 128k output.mp4
windows下空输出“/dev/null”要改成“NUL”,‘\’ 要改成'`';
跟CRF一样,可用可以接受的-preset 和 -tune、 -profile:v参数以得到不同的目标视频;
无损的H.264
如果设置了-profile:v high444参数你可以用 -crf 0 生成无损的视频,否则用 -pb 0(High 10 profile 配置不支持无损视频, 详看 https://code.videolan.org/videolan/x264/-/blob/master/x264.c#L579)。 ultrafast 和veryslow 这两个预设值是非常常用的,因为更快的编码速度和更好的压缩一般来说都是挺重要的考虑因素。
更快的编码示例:
ffmpeg -i input -c:v libx264 -preset ultrafast -qp 0 output.mkv
更好的压缩效果示例:
ffmpeg -i input -c:v libx264 -preset veryslow -qp 0 output.mkv
提示:无损的视频文件一般来说都非常大,不是基于ffmpeg的播放器可能不能解码播放。所以,如果兼容性和文件大小问题不可忽略,就别用无损了。
提示:如果你要的视频是“视觉上无损”而不是技术上的无损的话,用-crf 17或者18就行(你自己试哪个数值可以接受)。这样不会像真正的无损模式一样搞出一个非常大和兼容性有问题的视频文件;
覆盖默认预设设置
虽然 -preset 已经预设好了可能是最优默认设置给你,但你还是可以用 x264-params 参数去覆盖默认设置,也可以用libx264 的私有参数(ffmpeg -h encoder=libx264)。当然这些参数不推荐初学者使用。预设值是ffmpeg开发人人给出的最优解你去调这些参数一般都是浪费时间。
示例:
ffmpeg -i input -c:v libx264 -preset slow -crf 22 -x264-params keyint=123:min-keyint=20 -c:a copy output.mkv
注意: 不要用‘x264opts’这个参数, 这个参数后续版本会被删的。用’x264-params‘就行;
【原文】
https://trac.ffmpeg.org/wiki/Encode/H.264
测试示例命令
crf输出示例
#修改编码速度与压缩率
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast ultrafast.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset veryslow veryslow.mp4
#加入crf,速度快
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 18 ultrafast_18.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 23 ultrafast_23.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 51 ultrafast_51.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 39 ultrafast_39.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 45 ultrafast_45.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset ultrafast -crf 0 ultrafast_0.mp4
#加入crf,压缩率高
ffmpeg -i input.mp4 -vcodec libx264 -preset veryslow -crf 18 veryslow_18.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset veryslow -crf 23 veryslow_23.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset veryslow -crf 51 veryslow_51.mp4
ffmpeg -i input.mp4 -vcodec libx264 -preset veryslow -crf 0 veryslow_0.mp4
两遍式示例
ffmpeg -y -i input.mp4 -c:v libx264 -b:v 2097k -pass 1 -an -f null NUL && ffmpeg -i input.mp4 -c:v libx264 -b:v 2097k -pass 2 -c:a aac -b:a 128k tow_pass_3MB_2097k.mp4
[参考]
https://ffmpeg.0voice.com/forum.php?mod=viewthread&tid=282
FFmpeg H.264编码器指南[译]的更多相关文章
- x264 - 高品质 H.264 编码器
转自:http://www.5i01.cn/topicdetail.php?f=510&t=3735840&r=18&last=48592660 H.264 / MPEG-4 ...
- FFmpeg X264 H264编码指南[译]
本文目标:如何创建一个高质量的H.264视频 x264 是一个 H.264 编码器. 通常有2种码率控制(rate control)模式:Constant Rate Factor (CRF) or T ...
- 主流H.264编码器对比测试 (MSU出品)
俄罗斯的MSU Graphics & Media Lab (Video Group)出品的H.264编码器性能测试报告.测试了主流的H.264编码器的性能.从测试的结果来看,开源产品x264性 ...
- [ffmpeg] h.264解码所用的主要缓冲区介绍
在进行h264解码过程中,有两个最重要的结构体,分别为H264Picture.H264SliceContext. H264Picture H264Picture用于维护一帧图像以及与该图像相关的语法元 ...
- FFmpeg的H.264解码器源代码简单分析:环路滤波(Loop Filter)部分
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- FFmpeg的H.264解码器源代码简单分析:熵解码(Entropy Decoding)部分
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- FFmpeg的H.264解码器源代码简单分析:解码器主干部分
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- 6. H.264/AVC编码器原理
1. H.264/AVC的应用 H.264 不仅具有优异的压缩性能,而且具有良好的网络亲和性,这对实时的视频通信是十分重要的.和 MPEG-4 中的重点是灵活性不同,H.264 着重在压缩的高效率和传 ...
- H.264的一些资料整理
本文转载自 http://blog.csdn.net/ljzcom/article/details/7258978, 如有需要,请移步查看. Technorati 标签: H.264 资料整理 --- ...
随机推荐
- 一文了解Go语言的函数
1. 引言 函数是编程中不可或缺的组成部分,无论是在Go语言还是其他编程语言中,函数都扮演着重要的角色.函数能够将一系列的操作封装在一起,使得代码更加模块化.可重用和易于维护. 在本文中,我们将详细介 ...
- 特性介绍 | MySQL测试框架 MTR 系列教程(四):语法篇
作者:卢文双 资深数据库内核研发 序言: 以前对 MySQL 测试框架 MTR 的使用,主要集中于 SQL 正确性验证.近期由于工作需要,深入了解了 MTR 的方方面面,发现 MTR 的能力不仅限于此 ...
- 手写call&apply&bind
在这里对call,apply,bind函数进行简单的封装 封装主要思想:给对象一个临时函数来调用,调用完毕后删除该临时函数对应的属性 call函数封装 function pliCall(fn, obj ...
- NOIP模拟测试A3
A. 谜之阶乘 题目是让我们把 \(n\) 分解成两个阶乘的商,本来想推个式子什么的,结果发现推不出来. 我们知道,阶乘的增长速率非常的快啊!那么这个 \(b - a\) 的值肯定不会太大,我们可以暴 ...
- 【译】如何在 Visual Studio 中调试异步代码
虽然异步代码可以提高程序的整体吞吐量,但异步代码仍然无法免除错误!当潜在的死锁.模糊的错误消息以及查找导致 Bug 的 Task 时,编写异步代码会使调试更加困难.幸运的是,Visual Studio ...
- web系统字典统一中文翻译问题
几乎每个web系统都离不开各种状态码.订单新建,待支付,未支付,已支付,待发货. 消息已读未读,任务待标记待审批已审批待流转已完成未完成.等等. 复杂一点的,会有多级状态码. 状态码超出3个的,一般都 ...
- python-多继承构造函数声明问题
背景 有场景分别定义两组逻辑,随后有统一入口做基类属性的整合 其中两组逻辑的积累构造函数定义入参不同 设计类继承图如: 实际的使用方式抽象为[使用] 小节 实际开发过程中遇到问题 先说结论 pytho ...
- ABC295 D题 题解
题意简述 给定一个长度不超过\(\;5\times 10^5\;\)的,仅有数字构成的字符串,问存在多少段子串,使得子串内字符重新排序后,前半段与后半段相同? 做法分析 重组后前后两部分相同,其实也就 ...
- Promise的理解和使用(二)
一.Promise的常用APIpromise的这些方法执行完成都会返回一个新的promise,promise的状态由执行的结果决定. (1) new Promise()中的excutor函数 new ...
- [nginx]lua控制请求头
前言 nginx原生提供expires.add_header两个指令控制请求头,在Lua API中也有类似的指令. 添加请求头 指令:ngx.req.set_header 语法:ngx.req.set ...