ffmpeg:编码 h264 时限制为单 CPU 核心

kon*_*ify 20 video cpu-usage ffmpeg video-encoding

我需要在后台降低一些 H.264 视频的帧速率,而不用尽我的 CPU(在 Linux 上)。不知何故-threads 1根本没有效果:

ffmpeg -threads 1 -i 50fps.mp4 -filter:v fps=30 30fps.mp4
Run Code Online (Sandbox Code Playgroud)

流信息:

Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p(tv, bt470bg, progressive)
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D)
Run Code Online (Sandbox Code Playgroud)

所有核心仍处于最大状态。我怎样才能将其限制为只有一个核心?H.265 有一个特定于编码器的选项(pools=none),我可以在这里使用类似的选项吗?

Gor*_*bić 30

您可以通过以下方式执行此操作taskset

taskset -c 0 ffmpeg ...
Run Code Online (Sandbox Code Playgroud)

运行仅限于第一个 CPU 核心(从 0 开始计数)的 ffmpeg 进程。或者例如,在第一个和第三个核心上运行它:

taskset -c 0,2 ffmpeg ...
Run Code Online (Sandbox Code Playgroud)

  • 对于最终在这里搜索类似问题的任何人来说,这个特定的答案是有效的,但它仍然可能对系统其余部分的性能产生意想不到的影响(默认情况下,CPU 调度不会将任务固定到内核,这非常好)原因)。 (9认同)
  • 这样可行!在Linux上开发了10多年,我不知道这个命令。为了完整起见,我将等待“纯粹”的 ffmpeg 答案,然后再接受这一点。 (5认同)

Gya*_*yan 15

视频编码线程由输出设置-threads

所以,

ffmpeg -i 50fps.mp4 -filter:v fps=30 -threads:v 1 30fps.mp4
Run Code Online (Sandbox Code Playgroud)

  • @kontextify 这很正常而且还不错。与让操作系统决定在给定时刻什么是最佳的相比,保持“特定”核心“可用”没有任何好处。如果你 (11认同)
  • @TLW Linux 已经意识到这一点,并将尝试在最近运行的同一核心上重新安排任务,但它会打破该规则*有充分的理由*。cpuset pinning 确实有其用途(特别是对于网络应用程序),但这并不是真正的用途之一。特别是,除非您为系统上的每个“其他”进程提供 cpumask,否则它不会像您想象的那样保护缓存。当 ffmpeg 在没有“任务集”的情况下跳跃核心的时候,几乎就是“无论如何都没有帮助”将其放回同一核心的时候。 (9认同)
  • 是的,ffmpeg 不会限制特定的内核。此外,输出线程仅限制编码线程。有解码和过滤以及主程序线程。 (4认同)
  • @hobbs - 如果您想尽量减少对其他进程的干扰,那么固定到单个核心_can_是一个好主意。其一,核心之间的跳跃可能会破坏 L1 缓存。这不是免费的午餐——它还有其他缺点——但这并不等于说没有优点。 (4认同)
  • 这具有减少负载的效果,但仍将其分配给多个核心。没有一个核心达到最大,但总体而言,我的 4 核 CPU 运行速度约为 50%。也许“taskset”是执行此操作的唯一可靠方法。 (2认同)

小智 9

目的是为了防止ffmpeg在后台占用CPU而导致其他软件运行不良吗?

在这种情况下,我建议以更高的性能运行它:

nice -n 19 ffmpeg -i 50fps.mp4 -filter:v fps=30 30fps.mp4
Run Code Online (Sandbox Code Playgroud)

这将允许调度程序最小化 ffmpeg 的优先级,并在任何其他进程需要 CPU 的情况下立即抢占它,并且仍然允许您利用所有核心尽可能快地进行编码。