How to minimize usage of CPU/memory by ffmpeg when recording video

55,170

Solution 1

1. Make a lossless RGB output first

ffmpeg -y -framerate 25 -video_size 1280x1024 -f x11grab -i :0.0 -c:v libx264rgb \
-crf 0 -preset ultrafast temp.mp4
  • The input is RGB, so using the encoder libx264rgb will avoid the potentially slow RGB to YUV conversion that would occur if you use plain libx264.

  • This uses the quickest x264 encoding preset: ultrafast.

  • The output will be lossless because -crf 0 is used.

2. Then re-encode it

The output from the first command will be huge, and most dumb players can't handle RGB H.264 so you can re-encode it:

ffmpeg -i temp.mp4 -c:v libx264 -crf 23 -preset medium -vf format=yuv420p out.mp4
  • You can experiment with the -crf value to control output quality. A subjectively sane range is 18-28, where 18 is visually lossless or nearly so. Default is 23.

  • Use the slowest preset you have patience for: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow. Default is medium.

  • I added -vf format=yuv420p to ensure the output works with dumb players like QuickTime and Windows Media Player. You can omit this if you're uploading it to YouTube or only playing it on VLC, mpv, MPlayer, or any other FFmpeg based player.

Also see

Solution 2

It is better to concentrate on using different ffmpeg options that will achieve the same result in a way that uses less resources. That said, there are ways to use less resources if you really need to accomplish a specific thing with ffmpeg and it is using too many resources.

You can decrease the priority of ffmpeg's CPU process:

  • Terminal method: Use the nice command to change the process's priority: nice -n 8 ffmpeg -y -r 15 -g 600 -s 1280x1024x24 -f x11grab -i :100 -vcodec libx264 /tmp/video.mov. In Linux, the priority number (the nice command format is nice -n <priority> <command>) ranges from -20 to 20. The greater the integer, the lower the priority is; neutral is 0. If you use the command I gave you and set it to 8, the CPU will give the process less time, which seems like less "power". If this number is too high or two low, of course, you can change it.
  • GUI method: This isn't recommended because it gives you less control over the exact number and it doesn't take effect as soon as the process begins. However, it is more comprehensible. With ffmpeg running, open the System Monitor. Scroll down to the process named ffmpeg, left click it to select, right click it, and set the priority to "Low" or "Very Low".

If you're worried about memory usage, too, know that it is not possible to tell a process to only take so much memory and still run. The kernel automatically controls memory allocation for processes. There is a way to cage processes, with the timeout script, so that when a process and any child processes take up too much memory (a limit set by you) they are terminated safely and a notification is displayed. However, if a process is only given so much memory (say by the kernel) and it requests more memory that it cannot have, it will crash.

Some helpful things to know about:

Using knowledge of Cgroups, you can do lots of fun things like controlling the swappiness of a process.

Share:
55,170

Related videos on Youtube

Panji
Author by

Panji

Repo collaborator of Capybara

Updated on September 18, 2022

Comments

  • Panji
    Panji over 1 year

    I use FFmpeg for making video screen capture from Xvfb display.

    Currently I invoke it with:

    ffmpeg -y -r 15 -g 600 -s 1280x1024x24 -f x11grab -i :100 -vcodec libx264 /tmp/video.mov
    

    As I record video from about 5 Xvfb sessions my CPU usage is very high and there are lags because of it. Also memory usage is about 300 MB for each of ffmpeg processes.

    Which parameters for ffmpeg should I use to minimize computer resources usage (particularly CPU and memory) when making video screen capture?

  • Panji
    Panji over 10 years
    If I understand correctly putting ffmpeg to lower priority queue will make it produce videos with lags which is undesired.
  • Panji
    Panji over 10 years
    I capture video from non-default display (it's Xvfb) so it can be any number
  • Richard
    Richard over 10 years
    Hmm... I see nothing online saying that... Do you have a source that indicates that? (If not, it should be a bug).
  • Richard
    Richard over 10 years
    This is designed to limit the process's CPU usage, so if your CPU is running at 100%, it will have an easier time handling it.
  • Richard
    Richard over 10 years
    I tested this with a video and there seems to be no problem with the result.
  • llogan
    llogan over 10 years
    @AndreyBotalov Did you try the lossless method? Did it perform better for you?
  • Panji
    Panji over 10 years
    Currently I invoke ffmpeg with -preset superfast parameter (I haven't tried -crf). It takes less resources in such case and produces videos of good enough size.
  • llogan
    llogan over 10 years
    @AndreyBotalov -crf 23 is used by default if you do not declare a value, but anyway if superfast is sufficient for you then maybe the issue is solved.
  • gertvdijk
    gertvdijk over 10 years
    I've -1 this, because no matter how you change the priority, it will only make it worse. Setting a lower priority will lower the CPU time for ffmpeg resulting in more dropped frames, or, by raising the priority, it will slow down other processes on the system even more. Both results are undesired.
  • Panji
    Panji over 10 years
    Will low value of crf (such as 0) result in smaller usage of CPU/memory? To quote from Bonster's response in "HOWTO: Proper Screencasting on Linux": "The lower you set the CRF value, ... encoding time will increase, and vice-versa."
  • llogan
    llogan over 10 years
    @AndreyBotalov 0 uses lossless encoding which should be "faster" to capture than a lossy encoding. CPU usage may not be much different but you'll probably be able to capture using a higher frame rate, but of course it depends on other factors too (such as input complexity) and your best action is to perform some tests.
  • Kenn
    Kenn about 7 years
    You can also try hardware encoding via h264_nvenc (nvidia) or h264_qsv (modern intel cpu). This will shift the burden of encoding from your CPU to dedicated h264 hardware.
  • llogan
    llogan almost 7 years
    "Should not be used with actual grab devices" such as x11grab.