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 (很快,但文件很大 几乎没怎么压缩)
  • superfast
  • veryfast
  • faster
  • fast
  • medium – 默认预设值
  • slow
  • slower
  • veryslow (很慢,但压缩率很高 文件很小)
  • placebo – 忽略这个,这个没啥用 (参考 FAQ)

你可以通过参数:-preset help看到当前的所有预设值。如你安装了x264的库,你也可以用x264 --fullhelp 查看完整的预设设置;

Tune

译者:--tune的参数主要配合视频类型和视觉优化的参数。

你可以用-tune参数去改变你指定的输入的设置,当前的turn有如下值:

  • film – 适用于高质量的电影,降低去块效应。use for high quality movie content; lowers deblocking
  • animation – 适用于动画,使用更高级的去块处理和更多的参考帧。 good for cartoons; uses higher deblocking and more reference frames
  • grain – 保留旧的、颗粒状的影片材料中的颗粒结构。 preserves the grain structure in old, grainy film material
  • stillimage – 适用于幻灯片式的内容。good for slideshow-like content
  • fastdecode – 通过关掉某些路径,实现更快的编码。allows faster decoding by disabling certain filters
  • zerolatency – 适用于快的编码和低延迟的流。 good for fast encoding and low-latency streaming
  • psnr – 忽略此项,编码器开发用的。ignore this as it is only used for codec development
  • ssim – 忽略此项,编码器开发用的。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 BaselineMain profiles。你可以设置这些选项值为 -profile:v baseline or -profile:v main. 新设备一般都支持更高级的 High配置文件。

另外要用这个参数的原因是,要去匹配其他用 concat demuxer连接的视频文件。

注意:-profile:v参数不兼容无损的编码,setting -profile:v high444 也是无效的。

x264支持的配置文件如下:

  • baseline
  • main
  • high
  • high10 (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)。 ultrafastveryslow 这两个预设值是非常常用的,因为更快的编码速度和更好的压缩一般来说都是挺重要的考虑因素。

更快的编码示例:

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编码器指南[译]的更多相关文章

  1. x264 - 高品质 H.264 编码器

    转自:http://www.5i01.cn/topicdetail.php?f=510&t=3735840&r=18&last=48592660 H.264 / MPEG-4 ...

  2. FFmpeg X264 H264编码指南[译]

    本文目标:如何创建一个高质量的H.264视频 x264 是一个 H.264 编码器. 通常有2种码率控制(rate control)模式:Constant Rate Factor (CRF) or T ...

  3. 主流H.264编码器对比测试 (MSU出品)

    俄罗斯的MSU Graphics & Media Lab (Video Group)出品的H.264编码器性能测试报告.测试了主流的H.264编码器的性能.从测试的结果来看,开源产品x264性 ...

  4. [ffmpeg] h.264解码所用的主要缓冲区介绍

    在进行h264解码过程中,有两个最重要的结构体,分别为H264Picture.H264SliceContext. H264Picture H264Picture用于维护一帧图像以及与该图像相关的语法元 ...

  5. FFmpeg的H.264解码器源代码简单分析:环路滤波(Loop Filter)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  6. FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  7. FFmpeg的H.264解码器源代码简单分析:熵解码(Entropy Decoding)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  8. FFmpeg的H.264解码器源代码简单分析:解码器主干部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  9. 6. H.264/AVC编码器原理

    1. H.264/AVC的应用 H.264 不仅具有优异的压缩性能,而且具有良好的网络亲和性,这对实时的视频通信是十分重要的.和 MPEG-4 中的重点是灵活性不同,H.264 着重在压缩的高效率和传 ...

  10. H.264的一些资料整理

    本文转载自 http://blog.csdn.net/ljzcom/article/details/7258978, 如有需要,请移步查看. Technorati 标签: H.264 资料整理 --- ...

随机推荐

  1. 大数据实战手册-开发篇之RDD:计算 transform->action

    2.2 RDD:计算 transform->action 2.2.1 aggregate x = sc.parallelize([2,3,4], 2)[Task不能跨分片,task数为2] ne ...

  2. 一次与 ChatGPT 的 .NET 面试问答

    以常用问题来面试机器人,机器人是否能够合格 1. 您能描述一下您曾经在.NET项目中集成硬件设备的经历吗?这个过程是怎样的,您面临了哪些挑战? GPT 回答:当我在.NET项目中集成硬件设备时,我首先 ...

  3. 使用C#编写.NET分析器(三)

    译者注 这是在Datadog公司任职的Kevin Gosse大佬使用C#编写.NET分析器的系列文章之一,在国内只有很少很少的人了解和研究.NET分析器,它常被用于APM(应用性能诊断).IDE.诊断 ...

  4. 利用java来实现计算器的加减乘除

    package bag; import java.util.Scanner; public class Demo06 { public static void main(String[] args) ...

  5. 基于ChatGPT上线《你说我猜》小游戏

    摘要 AIGC.GPT.休闲小游戏三者可以怎么结合? AIGC.GPT与小游戏的结合为游戏体验带来了新的可能性.AIGC(Artificial Intelligence Game Content)作为 ...

  6. 【NestJS系列】核心概念:Controller控制器

    前言 控制器主要是用来处理客户端传入的请求并向客户端返回响应. 它一般是用来做路由导航的,内部路由机制控制哪个控制器接收哪些请求. 路由 为了创建基本控制器,我们需要使用@Controller装饰器, ...

  7. MariaDB start 报错:mysql-bin.index' not found (Errcode: 2) (Errcode: 13)

    问题是修改配置log-bin=/data/mysql/binlog/mysql-bin后出现的. 报错:Errcode: 2 mkdir -p /data/mysql/binlog ## 和正常的DB ...

  8. 2021-7-30 MySql进阶2

    创建临时表只需在table前面加temporary CREATE TEMPORARY TABLE mytable#创建临时表,在断开数据库连接时销毁 ( ID INT NOT NULL, userna ...

  9. 传输层之UDP与TCP的首部

    从通信信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能的最底层. 传输层位于应用层和数据链路层之间,主要有两个协议,用户数据报协议UDP(User D ...

  10. 无linux基础也能熟练掌握git的基本操作

    git是一个用来管理项目的工具,它的远程仓库有github.gitee.gitlab代码托管中心,既可以用于个人共享代码,又可以用于团队进行项目的协作与发布,那么我们一起来了解一下git该如何使用~ ...