0

I'm using the following ffmpeg command to take a 4K (3840x2160) video (between 5 and 10 minutes), trim it down to 21 seconds, flip it horizontally (across the vertical axis) and switch the red and blue channel:

ffmpeg -i "input.webm" -ss {trim_start} -t 21 -y -vf "hflip,format=yuv420p,colorchannelmixer=0:0:1:0:0:1:0:0:1:0:0" -metadata:s:v rotate=0 -codec:v libx264 "output.mp4"

However, I noticed that it is extremely slow, even on an Intel i7 5960x 8-core 16-thread CPU @ 3.9 GHz. I noticed that most of the time, ffmpeg's CPU utilization is sitting around 25%, and only a little of the time is the CPU is at 100% as reported by Windows Task Manager.

Is there anything I can do to speed this up? Is there something about the way the command is structured that is making it so slow? Or is this operation (trimming, flipping, and swapping channels) just too intense? Why is the cpu sitting at 25% most of the time?

I'm on Windows 10 1607. This is the ffmpeg output while encoding a video:

ffmpeg version N-94150-g231d0c819f Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9.1.1 (GCC) 20190621
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
  libavutil      56. 30.100 / 56. 30.100
  libavcodec     58. 53.101 / 58. 53.101
  libavformat    58. 28.101 / 58. 28.101
  libavdevice    58.  7.100 / 58.  7.100
  libavfilter     7. 55.100 /  7. 55.100
  libswscale      5.  4.101 /  5.  4.101
  libswresample   3.  4.100 /  3.  4.100
  libpostproc    55.  4.100 / 55.  4.100
Input #0, matroska,webm, from 'C:\Users\John\Downloads\raw_videos\input.webm':
  Metadata:
    encoder         : google/video-file
  Duration: 00:04:10.30, start: 0.000000, bitrate: 16596 kb/s
    Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv, bt709), 3840x2160, SAR 1:1 DAR 16:9, 60 fps, 60 tbr, 1k tbn, 1k tbc (default)
Stream mapping:
  Stream #0:0 -> #0:0 (vp9 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 000001a42792fcc0] using SAR=1/1
[libx264 @ 000001a42792fcc0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 000001a42792fcc0] profile High 4:4:4 Predictive, level 5.2, 4:4:4, 8-bit
[libx264 @ 000001a42792fcc0] 264 - core 157 r2970 5493be8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2019 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=4 threads=24 lookahead_threads=4 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'encoded/GB~BTj2lBc-84M.mp4':
  Metadata:
    encoder         : Lavf58.28.101
    Stream #0:0(eng): Video: h264 (libx264) (avc1 / 0x31637661), yuv444p, 3840x2160 [SAR 1:1 DAR 16:9], q=-1--1, 60 fps, 15360 tbn, 60 tbc (default)
    Metadata:
      encoder         : Lavc58.53.101 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
frame=  954 fps=1.9 q=31.0 size=   48896kB time=00:00:14.71 bitrate=27217.8kbits/s speed=0.0297x
2
  • 1) Add -preset veryfast 2) Swap the order of ccm and format filters.
    – Gyan
    Commented Dec 29, 2020 at 4:20
  • @Gyan, this helps, but I still don't understand why there's a large portion of the time where the frame sits at "0" and the CPU is only at 25%. What is it doing during that time? Commented Dec 29, 2020 at 15:59

1 Answer 1

1

Placing the -ss parameter after the input will cause FFmpeg to seek the input file by decoding file all the way from the beginning until it reaches the specified point. This is quite slow and the further the seek point is from the beginning of the file, the longer the seek will take. This is most likely why you're sitting at 0 frames encoded for a while.

When the -ss parameter is placed before the input, FFmpeg will use keyframes to seek, which is very fast. See https://trac.ffmpeg.org/wiki/Seeking for why.

If your CPU usage is still low after FFmpeg has managed to seek to the defined point in the video, it's likely due to one or more of the filters you're using. Some filters may not be able to use all the available CPU threads, and some filters aren't even multi-threaded. If you're curious and want to know which filter is the bottleneck, try removing filters one at a time and seeing how your CPU usage looks.

As a user, there isn't much you can do about a filter bottleneck. If you have multiple files waiting to be processed, you can launch multiple instances of FFmpeg to process the files in parallel and thus avoid "wasting" your CPU cores. Launching multiple instances does come with the caveat of increased memory use though, so keep an eye on your RAM use if you decide to do that.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .