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. 前端树形结构图treeShapeStruct,可拖拽移动,点击展开收缩,无限添加子集

    快速实现树形结构图,可拖拽移动,点击展开收缩,无限添加子集; 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12650 效果图如 ...

  2. 驱动开发:摘除InlineHook内核钩子

    在笔者上一篇文章<驱动开发:内核层InlineHook挂钩函数>中介绍了通过替换函数头部代码的方式实现Hook挂钩,对于ARK工具来说实现扫描与摘除InlineHook钩子也是最基本的功能 ...

  3. 在命令行按下tab键之后, 发生了生么?

    1. 引言 2. complete命令 3. 自定义补全列表 4. 动态补全列表 5. compgen命令 6. 别名的自动补全 7. 补全规则永久生效 8. 自动加载 9. 参考 1. 引言 当我们 ...

  4. Java 递归的小练习,累加、累乘、斐波那契兔子、文件递归

    递归的小练习, public static void main(String[] args) { System.out.println(sum(10)); System.out.println(mul ...

  5. 即构SDK7月迭代:新增支持按通道设置延迟模式,让卡顿大大减少

    即构SDK 7月迭代如期而至,本月SDK更新主要增加了按推流通道设置延迟模式,大大减少了直播卡顿:媒体本地录制新增AAC 格式,可生成更小的录制文件,更易于上传.此外还有多项功能的优化,让用户获得更好 ...

  6. JNI c++ 与 java 通信过程

    JNI(Java Native Interface)是Java提供的一种机制,用于在Java和本地C/C++代码之间进行通信.下面是JNI C++与Java通信的一般过程: 1. 编写Java代码:首 ...

  7. windows CMD命令的一些使用方法及注意事项

    windows CMD命令的一些使用方法及注意事项 转载请著名出处:https://www.cnblogs.com/funnyzpc/p/17572397.html 一.执行路径或参数带中文.空格.特 ...

  8. git报错:error: Your local changes to the following files would be overwritten by checkout:

    原因 原本想切换到dev分支,拉取远程dev分支,但我将分支上的数据修改了,此时切换分支报错 解决方案 方法一: 存到暂存区 # 暂存 git add . git stash 之后切换分支到dev,执 ...

  9. OpenLayers文档

    https://openlayers.org/en/latest/apidoc/module-ol_interaction_DragZoom-DragZoom.html#changed

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

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