如何使用 FFMPEG 从一系列 1000 个 PNG 图像创建未压缩的 AVI?
我使用以下命令将文件转换input.avi
为一系列 PNG 帧:
ffmpeg -y -i input.avi -an -vcodec png -s 1024x768 pic%d.png`
现在我需要知道如何从所有这些 PNG 帧制作未压缩的 AVI 视频。我尝试了以下方法:
ffmpeg -i pic%d.png -y -f avi -b 1150 -s 1024x768 -r 29.97 -g 12 -qmin 3 -qmax 13 -ab 224 -ar 44100 -ac 2 test.avi
但与原始 AVI 相比,生成的视频质量损失很大。
答案1
有几种方法可以从 中获得“未压缩”的 AVI ffmpeg
,但我怀疑你实际上指的是“无损”。正如你将看到的,这两个术语的定义都有相当大的回旋余地。
我将用 720p 高清版的大雄兔,因为这是一个免费提供的视频,我们都可以测试并获得可以比较的结果。 24 fps 的 1280×720p 视频的原始数据速率非常接近于您所述的 29.97 fps 的 1024×768 目标,所以我的结果应该可以很好地指导您在素材上可以预期的数据速率。
自动列出可用选项
以下 POSIX 命令¹为您提供了一个与我们下面讨论的内容基本²匹配的列表:
$ ffmpeg -codecs 2> /dev/null | grep '^..EV..S ' | grep -vE 'bitmap|image'
您可能希望在自己的机器上运行该命令,以查看您的 FFmpeg 版本将支持哪些功能。FFmpeg 很少在构建时启用所有可能的编码器。
现在让我们讨论一下这些选项。
完全未压缩
如果你对“未压缩”的定义是视频在被数字显示器转换为光子之前的形式,那么我在列表中看到的最接近的形式是、、、ffmpeg -codecs
和-c:v r210
。它们基本上都是同一件事,只是在r10k
v410
v308
ayuv
v408
颜色深度,色彩空间, 和阿尔法通道支持。
R210和R10K为 4:4:4 RGB,每分量 (bpc) 为 10 位,因此它们都需要大约708兆比特/秒在我的测试中,720p 的下载量为 100%。(这大约是每小时 ⅓ TB,朋友们!)
这些编解码器都将每像素 3×10 位颜色分量打包成 32 位值,以便于计算机操作,因为计算机喜欢 2 的幂大小。这些编解码器之间的唯一区别是两个未使用的位位于 32 位字的哪一端。这种微不足道的差异无疑是因为它们来自竞争公司,Blackmagic Design和AJA 视频系统, 分别。
虽然这些都是微不足道的编解码器,但您可能必须下载 Blackmagic 和/或 AJA 编解码器才能在计算机上使用它们播放文件。这两家公司都允许您在不先购买硬件的情况下下载其编解码器,因为他们知道您可能正在处理由以下客户制作的文件:做拥有一些他们的硬件。
V410本质上只是 R210/R10K 的 YUV 版本;它们的数据速率相同。不过,此编解码器的编码速度可能更快,因为
ffmpeg
它更有可能在输入帧的色彩空间和此色彩空间之间建立加速色彩空间转换路径。但是,我不推荐这个编解码器,因为我无法在任何我尝试过的软件中播放生成的文件,即使安装了 AJA 和 Blackmagic 编解码器。
V308是 V410 的 8 bpc 变体,因此518兆比特/秒在我的测试中。与 V410 一样,我无法在普通视频播放器软件中播放这些文件。
亚美尼亚青年志愿服务团和V408本质上与 V308 相同,只是它们包含一个 alpha 通道,无论是否需要!如果您的视频不使用透明度,这意味着您要付出上述 10 bpc R210/R10K 编解码器的大小代价,而无法获得更深的色彩空间的好处。
AYUV 确实有一个优点:它是 Windows Media 中的“原生”编解码器,因此不需要特殊软件即可播放。
V408 应该以同样的方式原生于 QuickTime,但 V408 文件无法在我的 Mac 上的 QuickTime 7 或 10 中播放。
因此,将所有这些放在一起,如果您的 PNG 已命名,frame0001.png
等等:
$ ffmpeg -i frame%04d.png -c:v r10k output.mov
...or... -c:v r210 output.mov
...or... -c:v v410 output.mov
...or... -c:v v408 output.mov
...or... -c:v v308 output.mov
...or... -c:v ayuv output.avi
请注意,在 AYUV 的情况下我指定了 AVI,因为它基本上是 Windows 独有的编解码器。其他编解码器可能在 QuickTime 或 AVI 中工作,具体取决于您的机器上安装了哪种编解码器。如果一种容器格式不起作用,请尝试另一种。
上述命令(以及下面的命令)都假设您的输入帧已经与输出视频所需的大小相同。如果不是,请-s 1280x720
在命令的输出文件名前添加类似以下内容。
压缩 RGB,但无损
如果,正如我所怀疑的,你实际上指的是“无损”而不是“未压缩”,那么比上述任何一个更好的选择是苹果 QuickTime 动画, 通过-c:v qtrle
我知道您说想要 AVI,但事实上,您可能需要在 Windows 机器上安装编解码器才能读取此处提到的任何基于 AVI 的文件格式,而使用 QuickTime,您选择的视频应用程序可能已经知道如何打开 QuickTime 动画文件。(上面的 AYUV 编解码器是我所知道的唯一例外,但它的数据速率非常高,只是为了获得 AVI 的好处。)
ffmpeg
会qtrle
为您填充 AVI 容器,但结果可能不太兼容。在我的测试中,QuickTime Player 会对这样的文件有点抱怨,但它确实会播放它。但奇怪的是,甚高频液晶无法播放,尽管它部分基于ffmpeg
。我会坚持使用 QT 容器来制作此编解码器。
QuickTime Animation 编解码器使用一个简单的放射线剂量率方案,因此对于简单的动画,它应该与下面的 Huffyuv 一样好。每帧中的颜色越多,它就越接近上面完全未压缩选项的比特率。在我用 Big Buck Bunny 进行测试时,我能够得到ffmpeg
一个165兆位/秒RGB 4:4:4 模式下的文件,通过-pix_fmt rgb24
。
虽然此格式是压缩的,但它将提供与 PNG 输入文件相同的输出像素值,原因相同PNG 的无损压缩不影响像素值。
QuickTime ffmpeg
Animation 实现还支持-pix_fmt argb
,可获得 4:4:4:4 RGB,这意味着它具有 alpha 通道。从粗略的角度看,它是-c:v ayuv
上述 的 QuickTime 等效版本。但由于无损压缩,因此它仅214兆位/秒,数据速率低于 AYUV 的 ⅓,且质量或功能没有任何损失。
QuickTime Animation 有以下变体:更少超过 24 位/像素,但它们最适合用于逐渐简化的动画样式。ffmpeg
似乎仅支持规范定义的其他格式之一,-pix_fmt rgb555be
即 15 bpp 大端 RGB。对于某些视频来说,这是可以容忍的,对于大多数截屏捕获和简单动画来说也很好。如果您可以接受色彩空间抽取,您可能会发现它的122兆位/秒数据速率很有吸引力。
综合起来:
$ ffmpeg -i frame%04d.png -c:v qtrle -pix_fmt rgb24 output.mov
...or... -pix_fmt argb output.mov
...or... -pix_fmt rgb555be output.mov
有效无损:YUV 技巧
现在,关于 RGB 和4:4:4 YUV是这些编码对于计算机来说非常容易处理,但它们忽略了人类视觉的一个事实,那就是我们的眼睛对黑白差异比对颜色差异更敏感。
因此,视频存储和传输系统几乎总是使用更少的比特来存储颜色信息而不是亮度信息。这被称为色度二次采样.最常见的方案是4:2:0和4:2:2。
4:2:0 YUV 的数据速率仅比黑白(仅 Y)未压缩视频高 50%,并且是 4:4:4 RGB 或 YUV 数据速率的一半。
4:2:2 是 4:2:0 和 4:4:4 之间的一种中间点。它的数据速率是 Y-only 视频的两倍,是 4:4:4 数据速率的 ⅔。
有时还会看到 4:1:1,如旧的DV摄像机标准。4:1:1具有与4:2:0相同的未压缩数据速率,但颜色信息的排列不同。
所有这些的重点是,如果您从 4:2:0 H.264 文件开始,将其重新编码为 4:4:4 未压缩 RGB 绝对不会比 4:2:0 无损压缩 YUV 带来任何好处。即使您知道您的工作流程是 4:4:4 RGB,情况也是如此,因为这是一个微不足道的转换;视频硬件和软件会定期动态进行此类转换。
实际上,只有在进行像素窥视或在视频上进行像素级颜色更改时才需要 4:4:4,并且您需要保留精确的像素值。视觉效果例如,使用 4:4:4 像素格式更容易完成 VFX 工作,因此高端 VFX 公司通常愿意容忍其所需的更高数据速率。
有效无损:编解码器选择
一旦你了解了 YUV 编解码器与色彩抽取,你的选择也会变多。ffmpeg
有很多有效无损编解码器。
哈菲尤夫
最广泛兼容的选项是哈菲尤夫. 您可以通过 获得-c:v huffyuv
。
原始的 Windows Huffyuv 编解码器仅支持两种像素格式:RGB24 和 YUV 4:2:2。(实际上,它支持两种 YUV 4:2:2,仅在磁盘上的字节顺序上有所不同。)
FFmpeg Huffyuv 编解码器的旧版本不包含 RGB24 支持,因此如果您尝试它并且 FFmpeg 告诉您它将使用yuv422p
像素格式,则需要升级。
FFmpeg 还有一个 Huffyuv 变体编解码器,称为 FFVHuff,支持 YUV 4:2:0。此变体与 Windows DirectShow Huffyuv 编解码器不兼容,但它应该可以在任何基于 的软件(libavcodec
例如 VLC)中打开。
RGB24— RGB 4:4:4 本质上与 QuickTime Animation 的 RGB24 色彩空间选项相同。对于给定文件,这两种编解码器的压缩率略有不同,但通常非常接近。
它也与上面的 V308 选项使用的 YUV 4:4:4 模式本质上是相同的。颜色空间差异没有实际区别,因为颜色空间转换很容易实时完成。
由于 Huffyuv 的无损压缩,我能够将测试视频压缩到大约251兆位/秒在 RGB24 模式下,视觉质量与 V308 或 AYUV 相同。如果 AVI 是绝对必须为您安装Huffyuv 编解码器可能比支付 AYUV 的 3 倍数据速率成本要轻松得多。
YUV 4:2:2— 这种模式对于视频来说比 RGB24 更实用,这无疑是
ffmpeg
开发人员选择首先实现它的原因。正如您从上面讨论的理论上的 ⅔ 减少所期望的那样,我的测试文件编码为173兆比特/秒。如果考虑到这两次测试之间音轨没有变化,那么这个比例几乎正好是 ⅔。YUV 4:2:0— 此选项比 4:2:2 抽取更多的颜色信息,从而将数据速率降低到133兆比特/秒在我的测试中。
综合起来:
$ ffmpeg -i frame%04d.png -c:v huffyuv -pix_fmt rgb24 output.avi
...or... -pix_fmt yuv422p output.avi
...or... -c:v ffvhuff -pix_fmt yuv420p output.avi
虽然ffvhuff
我写这篇文章的时候编解码器默认为 4:2:0,但确实仅有的我使用的发布版本支持该像素格式,这正在改变,因此您应该包含该标志,以防默认值发生变化。
Ut 视频
与 Huffyuv 和 FFVHuff 秉承相同理念的较新选择是Ut 视频. 像 Huffyuv 一样,还有Windows 视频编解码器这意味着任何可以播放电影的 Windows 程序都可以在安装了该编解码器的情况下使用此编解码器播放视频。与 Huffyuv 不同,还有一个 Mac 视频编解码器,因此您不必局限于基于 FFmpeg 的软件或libavcodec
在 Mac 上读取这些文件。
此编解码器非常在色彩空间方面很灵活,因此我仅给出几个常见色彩空间的例子:
4:4:4 RGB通过
-f avi -c:v utvideo -pix_fmt rgb24
给予178兆比特/秒输出4:4:4 YUV通过
-f avi -c:v utvideo -pix_fmt yuv444p
给予153兆比特/秒输出4:2:2 YUV通过
-f avi -c:v utvideo -pix_fmt yuv422p
给予123兆比特/秒输出4:2:0 YUV通过
-f avi -c:v utvideo -pix_fmt yuv420p
给予100 Mbit/秒输出
我怀疑 4:4:4 YUV 在此测试中的表现优于 4:4:4 RGB,尽管这两者在技术上是等效的,因为源视频是 4:2:0 YUV,因此以 YUV 格式排列数据可以通过在文件中将部分冗余的 U 和 V 通道组合在一起来实现更好的无损压缩。
最终幻想1
这个领域的另一个有趣的选择是 FFmpeg 自己的FFV1
编解码器。这主要用作存档编解码器,而不是播放或编辑编解码器,但由于许多软件要么基于FFmpeg 的基础库,要么可以通过以下工具libavcodec
绑定:libavcodec
ffdshow
,无论如何它可能对你有用。
默认情况下,ffmpeg
在使用像 FFV1 这样的灵活编解码器时,它将保留输入文件的色彩空间,因此,如果您向其输入一个使用 4:2:0 YUV 的官方 Big Buck Bunny MP4 文件,除非您给 加上标志,否则您将得到该颜色空间-pix_fmt
。ffmpeg
这会导致63兆位/秒输出文件。
如果你强制 FFV1 使用 4:4:4 YUV 色彩空间-pix_fmt yuv444p
,文件大小只会增加到86兆比特/秒,但在这种情况下,它对我们没有任何帮助,因为我们是从 4:2:0 原始文件进行编码的。但是,如果您输入一组 PNG,就像原始问题中那样,输出文件可能会使用bgra
或bgr0
颜色空间,它们只是上面提到的argb
和颜色空间的重新排列。rgb24
无损 H.264
另一个有趣的选择是无损 H.264.这几乎是一个仅限 x264在撰写本文时,这还不算什么,但那些在编码方面使用 FFmpeg 的人很可能正在使用其他包含以下内容的软件libx264
:解码也可以使用 VLC 等工具。
获取此类文件的最简单方法是:
$ ffmpeg -i frame%04d.png -c:v libx264 -qp 0 -f mp4 output.mp4
标志-qp 0
是关键:值越高,压缩越有损。(您也可以给出-crf 0
相同的效果。)
与 FFV1 一样,ffmpeg
将尝试根据输入色彩空间猜测最佳输出色彩空间,因此为了与上面的结果进行比较,我在具有不同色彩空间的 Big Buck Bunny 源文件上运行了多次编码:
yuv444p:这就是
ffmpeg
当你给它一个 RGB PNG 流时所做的选择,就像在原始问题中一样,结果是44兆比特/秒使用我们的测试文件进行归档yuv422p:这与 Huffyuv 的默认颜色空间类似,但我们得到了一个34兆比特/秒在这种情况下,相当节省!
yuv420p:这是我测试的 Big Buck Bunny 官方 MP4 的默认设置,结果是29兆比特/秒文件。
请注意,为了获得如此小的文件大小,您需要牺牲很多兼容性。这就是为什么我甚至懒得尝试将其塞入 AVI 或 MOV 容器中。它与 x264 紧密相关,因此您不妨改用其标准容器类型 (MP4)。您也可以使用类似马特罗斯卡为了这。
你可以通过添加 来牺牲一些比特率来加快编码时间-preset ultrafast
。这将我的测试文件的比特率提高到44兆比特/秒在 YUV 4:2:2 模式下,但编码速度更快,正如承诺的那样。文档声称这-preset veryslow
也是值得的,但它导致了很多编码时间更长,但仅节省一点点空间;我不推荐它。
其他的
ffmpeg
还支持仅解码模式拉加里斯和仅编码模式无损 JPEG。这两个编解码器实际上有些相似,并且应该能够生成比 Huffyuv 稍小的文件,但质量相同。如果ffmpeg
开发人员添加 Lagarith 编码,它将成为 Huffyuv 的强大替代品。但我不推荐 Lossless JPEG,因为它没有得到广泛的解码支持。
感知无损:或者,你也许可以承受一些损失
然后是编解码器感知上无损。除非你对像素进行仔细观察,否则你几乎肯定看不出这些图像与前两组图像的视觉效果有什么不同。通过放弃视频捕获传感器和显示设备之间绝对零变化的想法,你可以节省大量成本:
苹果 ProRes:
-c:v prores
或-c:v prores_ks
— ProRes 是一种基于配置文件的编解码器,这意味着它有几种变体,每种变体都有不同的质量与空间权衡:ProRes 4444仅使用114兆位/秒,但视觉特效质量。FFmpeg 中目前有三种不同的
prores*
编解码器,但prores_ks
在我撰写本文时,仅通过选项支持 ProRes 4444-profile:v 4444
。如果你想知道为什么要选择 ProRes 4444 而不是无损 H.264,那么这取决于兼容性、解码速度、可预测性和 alpha 通道。
ProRes 422节省更多空间,只需要84兆比特/秒仅通过像素窥视就能得到与 ProRes 4444 不同的结果。除非您需要 ProRes 4444 提供的 alpha 通道,否则可能没有理由坚持使用 ProRes 4444。
ProRes 422 是上述无损 H.264 选项的更接近竞争对手,因为它们都不支持 alpha 通道。如果您需要与 Apple 专业视频应用程序兼容、较低的编码和解码 CPU 开销或可预测的比特率,您将需要容忍 ProRes 的更高比特率。例如,后者对于硬件编码器很重要。另一方面,如果您可以应对无损 H.264 的兼容性问题,您可以选择使用 4:2:0 色彩空间,而这不是任何 ProRes 配置文件中的选项。
FFmpeg 中的所有三个 ProRes 编码器都支持 ProRes 422 配置文件,因此最简单的选择是使用
-c:v prores
,而不是-c:v prores_ks -profile hq
,或者依靠的自动配置文件功能prores_ks
来做正确的事情。
还有更简约的 ProRes 配置文件,但它们适用于标清视频或代理用于全分辨率文件。
ProRes 的主要问题是它在 Apple 和专业视频领域之外尚未得到广泛的支持。
Avid 的 DNxHD是一种与 ProRes 类似的编解码器,但与 Apple 专业视频世界无关。Avid 提供可免费下载的编解码器适用于 Windows 和 Macintosh,FFmpeg 现在通过 支持它
-c:v dnxhd
。由于 DNxHD 是一种基于配置文件的编解码器(如 ProRes),因此您可以从预定义集,并告诉编解码器要使用哪种帧大小、帧速率和比特率。对于 Big Buck Bunny 测试文件,该
-b:v 60M
配置文件最合适。不出所料,生成的文件约为59兆比特/秒。低损耗 MJPEG:
-vcodec mjpeg -qscale:v 1
— 这比无损 JPEG 更常见。事实上,这曾经是一种相当常见的视频编辑编解码器,并且仍然经常被联网流媒体摄像机等使用。所有这些历史意味着很容易找到支持它的软件。预计此编解码器的数据速率会有相当大的变化。我刚刚在这里进行的测试让我25兆比特/秒720p 视频。压缩程度足够高,让我担心有损,但我觉得效果还不错。仅从数据速率来看,我认为质量可能与12兆位/秒MPEG-2 或6兆比特/秒264。
综合起来:
$ ffmpeg -i frame%04d.png -c:v prores_ks -profile:v 4444 output.mov
...or... -c:v prores_ks -profile:v hq output.mov
...or... -c:v prores output.mov
...or... -c:v dnxhd -b:v 60M output.mov
...or... -c:v mjpeg -qscale:v 1 output.avi
这些方法的底线是,除非你正在做一些非常苛刻的事情,否则“足够好”确实足够好。
脚注和题外话
该命令应在 Linux、macOS、BSD 和 Unix 上正常工作。如果您使用的是 Windows,则可以通过以下方式获取 POSIX 命令行赛格威或者西弗吉尼亚海岸。
该命令生成的列表与我上面选择讨论的编解码器集不完全匹配的原因有几个:
第二种方法
grep
旨在过滤掉不合适的编码器,例如 ,bmp
尽管被标记在此列表中,但这些编码器并非“视频”编解码器V
。虽然从技术上讲,您可能可以将其中许多编码器塞入 AVI、MP4 或 MKV 等容器中以获取单个文件视频,但该文件很可能只能由基于ffmpeg
或 的程序读取libavcodec
。有一些例外,比如
-f avi -c:v ljpeg
可以称为“无损 MJPEG”,但一般来说,我们不想将许多静态图像文件塞进 A/V 容器来制作电影。我们希望使用广为认可的视频编解码器,而不是语义欺骗。该命令目前无法过滤掉一些不适当的编码器,例如 GIF,因为它们目前没有在输出中描述
ffmpeg -codecs
为bitmap
或image
文件格式。GIF 是一个有趣的案例:它支持单个 GIF 文件中的多个图像帧,并带有用于运动播放的定时信息,但由于多种原因,它完全不适合我们在此讨论。
所显示的几个选项已经过时或从未真正获得太多关注,例如
flashsv
、dirac
和snow
,因此不值得在上面讨论它们。该列表中的某些选项仅适用于
ffmpeg
实例之间或和ffmpeg
另一个程序之间的管道,例如rawvideo
和wrapped_avframe
,因此不适合我们这里的目的。在上述讨论即将结束时,我明智地稍微扩大了问题的范围,包括了一些精心选择的有损选项,因此它们不会通过
grep
上述命令中的第一个过滤器。
答案2
所以我最终把我的答案写得太长了。TL
;DR 总结:要无损存储一系列图像,请使用libx264
或libx264rgb
与-preset ultrafast -qp 0
。它几乎和 ffvhuff 一样快,但比特率要低得多,而且解码速度更快。 huffyuv
在 ffmpeg 之外得到更广泛的支持,但支持的像素格式不如 那么多ffvhuff
。所以这是使用 h.264 的另一个原因,假设你的其他工具可以处理 x264High 4:4:4 Predictive
在无损模式下使用的 h.264 配置文件。如果需要快速随机访问任意帧,x264 可以仅进行帧内处理。
当心ffmpeg 错误从图像目录读取时会影响 libx264rgb。(谁知道还有什么其他情况。)使用前在您的设置中测试无损。(使用ffmpeg -i in -pix_fmt rgb24 -f framemd5
源和无损压缩很容易)
编辑:utvideo
编码和解码速度相当快,并且比 h.264 更简单。它基本上是一种现代的huffyuv
,支持更多有用的色彩空间。如果您在使用 h.264 时遇到问题,请尝试使用 utvideo 来处理临时文件。
编辑2:PNG 作为 RGB 编解码器似乎表现良好,至少在 Sintel 预告片上是如此。
另请参阅我对类似问题的类似回答: https://superuser.com/a/860335/20798
Warren Young 的回答中有很多关于各种原始格式和编解码器的信息。我认为如果答案更短一些会更有用,所以我做了一个新的答案。如果您使用的软件不支持无损 x264 或 ffvhuff,那么其中一些信息可能仍然有用。
在此上下文中,“无损”最有用的定义是您可以逐位恢复输入。无论您做什么,都无需担心视频编码的质量下降。
http://en.wikipedia.org/wiki/Chroma_subsampling
理想情况下,应避免多次进行色彩空间转换。舍入误差可能会累积。如果您要使用在 RGB 色彩空间中工作的滤镜对视频进行操作,那么只要更高的比特率不是问题,保留 RGB 是有意义的。您最终可能会制作视频yuv 4:2:0
,但保留额外的色度分辨率可能会很有用,具体取决于您要应用的滤镜。
无论如何,无损 x264 和 ffvhuff 都支持 RGB 和 yuv 4:4:4
、4:2:2
和4:2:0
。我建议使用 x264,因为它解码速度很快。如果您尝试实时播放 RGB 高清视频,请尝试使用 opengl 而不是 xv,因为我的系统上的 xv 仅接受 yuv 输入。mplayer 需要额外的 CPU 时间来进行色彩空间转换。
以下编码器测试的来源:https://media.xiph.org/。 https://media.xiph.org/sintel/sintel_trailer-1080-png.tar.gz 他们忘记对 sintel 预告片的 y4m 文件进行 gzip 压缩,因此 png tarball 实际上要小得多。
ffmpeg -i 1080/sintel_trailer_2k_%4d.png -i sintel_trailer-audio.flac \
-c:a copy -c:v libx264rgb -preset ultrafast -qp 0 \
frompng.sintel.264rgb.mkv
例如
peter@tesla:/mnt/GP1TB/p/encoder-sample/sintel$ time ffmpeg -i 1080/sintel_trailer_2k_%4d.png -i sintel_trailer-audio.flac -c:a copy -c:v libx264rgb -preset ultrafast -qp 0 frompng.sintel.264rgb.mkv
ffmpeg version N-67983-g2b358b4 Copyright (c) 2000-2015 the FFmpeg developers
built on Jan 10 2015 05:32:37 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
configuration: --enable-gpl --enable-version3 --enable-nonfree --disable-doc --disable-ffserver --enable-libx264 --enable-libx265 --enable-libmp3lame --enable-libopus --enable-libwebp --enable-libvpx --disable-outdev=oss --disable-indev=oss --disable-encoder=vorbis --enable-libvorbis --enable-libfdk-aac --disable-encoder=aac --disable-decoder=jpeg2000
libavutil 54. 16.100 / 54. 16.100
libavcodec 56. 20.100 / 56. 20.100
libavformat 56. 18.100 / 56. 18.100
libavdevice 56. 3.100 / 56. 3.100
libavfilter 5. 7.100 / 5. 7.100
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
Input #0, image2, from '1080/sintel_trailer_2k_%4d.png':
Duration: 00:00:50.12, start: 0.000000, bitrate: N/A
Stream #0:0: Video: png, rgb24, 1920x1080 [SAR 72:72 DAR 16:9], 25 fps, 25 tbr, 25 tbn, 25 tbc
Input #1, flac, from 'sintel_trailer-audio.flac':
Duration: 00:00:52.00, start: 0.000000, bitrate: 721 kb/s
Stream #1:0: Audio: flac, 48000 Hz, stereo, s16
File 'frompng.sintel.264rgb.mkv' already exists. Overwrite ? [y/N] y
No pixel format specified, rgb24 for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.
[libx264rgb @ 0x2770760] using SAR=1/1
[libx264rgb @ 0x2770760] using cpu capabilities: MMX2 SSE2Fast SSSE3 Cache64 SlowShuffle
[libx264rgb @ 0x2770760] profile High 4:4:4 Predictive, level 4.0, 4:4:4 8-bit
[libx264rgb @ 0x2770760] 264 - core 144 r2525+2 6a4fca8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=0 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, matroska, to 'frompng.sintel.264rgb.mkv':
Metadata:
encoder : Lavf56.18.100
Stream #0:0: Video: h264 (libx264rgb) (H264 / 0x34363248), rgb24, 1920x1080 [SAR 72:72 DAR 16:9], q=-1--1, 25 fps, 1k tbn, 25 tbc
Metadata:
encoder : Lavc56.20.100 libx264rgb
Stream #0:1: Audio: flac ([172][241][0][0] / 0xF1AC), 48000 Hz, stereo (16 bit)
Stream mapping:
Stream #0:0 -> #0:0 (png (native) -> h264 (libx264rgb))
Stream #1:0 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 1253 fps= 18 q=-1.0 Lsize= 834790kB time=00:00:51.96 bitrate=131592.5kbits/s
video:830198kB audio:4575kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.002025%
[libx264rgb @ 0x2770760] frame I:6 Avg QP: 0.00 size:612470
[libx264rgb @ 0x2770760] frame P:1247 Avg QP: 0.00 size:678787
[libx264rgb @ 0x2770760] mb I I16..4: 100.0% 0.0% 0.0%
[libx264rgb @ 0x2770760] mb P I16..4: 50.3% 0.0% 0.0% P16..4: 12.0% 0.0% 0.0% 0.0% 0.0% skip:37.6%
[libx264rgb @ 0x2770760] coded y,u,v intra: 71.1% 68.2% 70.0% inter: 22.8% 22.8% 23.2%
[libx264rgb @ 0x2770760] i16 v,h,dc,p: 50% 48% 1% 1%
[libx264rgb @ 0x2770760] kb/s:135693.94
请注意,我忘记指定-r 24
fps,因此它不会使 av 与音频保持同步。(并且比特率(但不是文件大小)数字也会偏离。ffmpeg 默认为 25fps)。这台机器的 CPU 是第一代 (conroe) core2duo 2.4GHz (E6600)。
结果:
4.5M sintel_trailer-audio.flac # this is muxed in to every mkv
948M 1080 # the directory of PNGs
940M /var/tmp/dl/sintel_trailer-1080-png.tar.gz
7434M sintel.y4m # yuv444, uncompressed. mplayer gets the colors wrong?
2342M qtrle.mkv # encode went at 16fps, so qtrle is slower and worse filesize
2105M sintel.huff.mkv # ffvhuff with default options, rgb pix fmt
1228M sintel.utvideo.mkv # muxed without audio, I should update the others this way
946M png-copy.mkv # -codec copy makes a MPNG stream. Use -codec png for non-png sources, but it won't make PNGs as small. Decodes very fast
824M lossy.prores_ks.mov # yuv444p10le extremely slow to encode (2.3fps), and worse bitrate.
816M frompng.sintel.264rgb.mkv
735M sintel.x264rgb.medium.nocabac.mkv # encode went at 3.3 fps instead of 18. Better gain than for live-action, though
626M sintel_trailer.rgb.lossless.veryslow.mkv # 1.1fps. With CABAC, 16 ref frames, etc. etc.
512M lossy.prores.mov # yuv422p10le, 12fps
341M sintel.yuv420.x264.lossless.mkv
21M lossy.rgb.crf26.preset=medium.mkv
13M lossy.yuv420.crf26.preset=medium.mkv # remember this is WITH 4.5MB audio
请注意,虽然mediainfo
不了解 RGB h.264,但它仍然说文件是 YUV。
检查它是否确实是无损的:
ffmpeg -i 1080/sintel_trailer_2k_%4d.png -f framemd5 png.framemd5
ffmpeg -i fromhuff.sintel.264rgb.mkv -an -sn -pix_fmt rgb24 -f framemd5 x264rgb.framemd5
diff -s *.framemd5
Files png.framemd5 and x264rgb.framemd5 are identical
因此,您可以通过这种方式恢复原始 PNG 输入,即,您可以制作包含相同图像数据的 PNG。
注意-pix_fmt rgb24
x264 测试。ffmpeg 的 h.264 解码器输出 gbrp(平面的,非打包的)输出,因此位是相同的,但顺序不同。framemd5“容器”不施加任何格式限制,但只有当位以相同的方式排列时,您才会获得相同的 md5。当我向 ffmpeg 提供 PNG 时,我刚刚查看了它所说的 pix fmt 的使用情况,然后将其用作-pix_fmt
解码的参数。顺便说一句,这就是 vlc 无法播放 RGB h.264 文件的原因(直到下一个版本或当前的夜间版本):它不支持 gbrp 像素格式。
对于 yuv 使用libx264
,而不是libx264rgb
。您不需要安装 RGB 版本的 x264,实际库支持两者。只是 ffmpeg 将其实现为两个不同名称的编码器。我认为如果他们没有这样做,默认行为将是将 rgb 输入保留为 rgb,并且运行非常缓慢,同时为相同质量产生更高的比特率输出。(-pix_fmt yuv420p
如果您愿意,您有时仍然必须使用420
而不是444
h.264 输出。
除非您要制作用于长期存储的文件,否则请始终使用-preset ultrafast
无损 x264。对于无损、非动画材料(带有任何噪音),更多的参考帧和运动搜索几乎不会产生任何影响。在无损比特率下,CABAC 会占用大量 CPU,甚至解码也是如此。仅用于存档目的,而不是临时文件。(超快会禁用 CABAC)。CABAC 可节省 10% 到 15% 的比特率。
如果需要将每一帧都设为关键帧,请设置-keyint 1
。这样,只想在关键帧或其他帧上剪切的视频编辑软件就不会限制您。
回答最初的问题:这是您在分阶段尝试操作时应该做的事情(例如,缓慢的去隔行,在尝试其他操作之前保存无损输出):
ffmpeg -i dv-video-source.ts -vf yadif=2:1,mcdeint=3:1:10 -c:a copy -c:v libx264 -preset ultrafast -qp 0 deinterlaced.mkv
如果您确实需要以图像文件的形式输出,并且可以使用静态图像工具进行修改,那么当然可以解码为 png。您不会丢失任何内容,除了每个像素的 Y、Cb 和 Cr 值的 8 位中最低有效位。
x264 在这方面表现得非常好,因为有很多黑色帧,带有一些文本,淡入淡出,并且许多帧的大区域之间具有完美的相似性,它甚至能够利用这一点-preset ultrafast
。在实景拍摄中,我仍然看到 x264 的文件大小只有 ffvhuff (yuv420) 的一半。
对于那些好奇的人来说:高 CPU 时间无损 rgb 编码具有(x264 核心 144 r2525):
[libx264rgb @ 0x35b97a0] frame I:27 Avg QP: 0.00 size:604367
[libx264rgb @ 0x35b97a0] frame P:1226 Avg QP: 0.00 size:517512
[libx264rgb @ 0x35b97a0] mb I I16..4..PCM: 46.3% 38.1% 15.7% 0.0%
[libx264rgb @ 0x35b97a0] mb P I16..4..PCM: 24.3% 5.4% 4.5% 0.0% P16..4: 10.5% 3.3% 5.7% 0.0% 0.0% skip:46.3%
[libx264rgb @ 0x35b97a0] 8x8 transform intra:17.3% inter:46.1%
[libx264rgb @ 0x35b97a0] coded y,u,v intra: 81.6% 77.5% 80.0% inter: 28.0% 27.7% 28.1%
[libx264rgb @ 0x35b97a0] i16 v,h,dc,p: 35% 64% 1% 0%
[libx264rgb @ 0x35b97a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 49% 13% 2% 1% 1% 1% 1% 1%
[libx264rgb @ 0x35b97a0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 37% 5% 5% 6% 5% 5% 4% 3%
[libx264rgb @ 0x35b97a0] Weighted P-Frames: Y:41.1% UV:40.7%
[libx264rgb @ 0x35b97a0] ref P L0: 74.5% 4.2% 9.1% 4.1% 2.1% 1.7% 1.2% 0.8% 0.6% 0.5% 0.3% 0.2% 0.2% 0.2% 0.2% 0.1%
[libx264rgb @ 0x35b97a0] kb/s:99721.66
请注意,加权 p 帧的比例非常高,跳过宏块的比例也非常高。每个场景转换都是淡入淡出,而不是切换,如果您给 x264 一些 CPU 时间来弄清楚如何操作,它就会利用这一点。
进一步说明(用于编辑的有损编解码器):
对于在剪辑中向前/向后拖拽,通常首选仅支持内部的编解码器(utvideo、ffvhuff、mjpeg、jpeg2000、pro-res、AVC-Intra)。我认为常规 AVC 的短 GOP(1/2 到 1 秒)也能很好地拖拽,只要软件知道它在做什么(快速拖拽时解码最近的 I 帧,如果时间轴放大到需要,则在 GOP 内解码以到达中间帧)。
我发过一些关于这个的负面帖子,https://video.stackexchange.com/关于 pro-res,例如“如果它比无损编解码器更慢、压缩率更差,那还有什么意义”,但它确实有一些有趣的功能。 苹果说它可以以半分辨率进行解码,仅需使用解码全分辨率的 CPU 时间的 1/3。
ffmpeg 的 prores 实现可能也没有 Apple 的那么优化速度,这就是为什么我对 ffmpeg 的测试让它看起来很慢的原因。如果您有基于 ffmpeg 的工具的免费软件工作流程,它可能不值得使用,但如果您使用的是商业软件,它可能值得一试。
我很少进行视频编辑,主要是编码,所以我不太清楚哪些测试适合 prores 之类的编解码器。我猜,如果短 GOP x264 效果不好,mjpeg 可能是一个很好的快速替代方案。Linux 发行版中有 jpeg 的 asm 加速实现,这是一个非常简单的编解码器。您可以根据需要提高或降低质量,以在质量与文件大小 + 编码/解码速度之间进行权衡。它很古老,但如果您想要一个速度非常快的仅限内部的编解码器,它可能会胜过 x264。
对于 x264,我会尝试类似x264 --crf 10 --keyint=1 --preset superfast --tune fastdecode
(仅限内部,不--avcintra-class
设置任何其他内容)的方法。注意superfast
(没有 CABAC)或faster
,不是ultrafast
可能是有损操作的最佳选择。我认为超快会损失很多质量,但速度不会更快。您使用的质量越低(crf 越高),花费更多 CPU 时间寻找更好的编码就越值得。不过,这其中很多可能与 GOP 大小 = 1 无关。
当 GOP 大小 > 1 时,如果您在编码时投入了太多比特,以至于更好的帧间预测在编码残差时不会节省很多比特(因为帧之间的噪声/颗粒/细微变化被非常准确地保留),那么超快可能就足够了。否则,使用--keyint=30
或其他方法可能--preset veryfast --crf 12
会很有趣。
理论上,给定 CRF 设置下的质量应在预设中保持不变。如果您正在寻找更小的文件(更快的解码),那么牺牲一些质量和一些编码时间是合理的。
答案3
我认为 ffmpeg 实际上支持转换为未压缩的视频。
我使用了 ffmpeg -i input.mp4 -vcodec rawvideo out.avi,生成的 .avi 大致是正确的文件大小。Windows media player 似乎无法正确播放它,但 VirtualDub 可以读取它,而且我没有看到任何图像质量损失。