One of the reasons I bought a used Z440 workstation with a 6 core Xeon CPU and an Nvidia graphics card back in December was to offload and speedup occasional video transcoding tasks. As I wrote at the time, I could get a speed-up of up to 8x over my X250 notebook. Since then I have found further parameter improvements for ffmpeg and in some scenarios, my speed-up is now over 30x compared to running the same task on my notebook.
Two Practical Examples
The speed-up that can be reached mainly depends on the input data and the desired output codec and quality. Compressing a 49 minute 2.9 GB video file encoded with HEVC (H.265) and made on a mobile phone to a low bit-rate H.264 encoded video with a size of 380 MB is done at around 0,6 of the original video frame rate on my notebook. In other words, transcoding the video takes around 1.5 hours. Running the same task on my workstation and letting the graphics card do the H.265/HEVC decoding + re-encoding in H.264 format is done at 13 times the original video frame rate, i.e. in just under 4 minutes. And as a bonus, the workstation fans remain almost inaudible while the little fan in my notebook runs rampant for one and a half hours.
Re-encoding this particular video into H.265/HEVC results in a 330 MB file. However, the codec is much more complicated and even the hardware unit on the graphics card requires 8 minutes for the task. As there is little movement in this video, the slightly better compression rate does not compensate for the significantly longer encoding time for my purposes. Perhaps other videos have a better ratio, so this is not a general statement.
Some ffmpeg Commands
So here are a couple of ffmpeg command parameters I found useful, which work with an Nvidia graphics card and an out-of-the-box pre-compiled ffmpeg that came as part of Ubuntu 20.04:
# With DE- and ENCODER on NVIDIA, decode AUTO codec detection, # encoding to h264 ffmpeg -hwaccel cuda -i input.mp4 -c:v h264_nvenc -cq:v 37 test.mp4 # With DE- and ENCODER on NVIDIA, decode AUTO codec detection, # encoding to HEVC/H.265 ffmpeg -hwaccel cuda -i input.mp4 -c:v hevc_nvenc -cq:v 37 test.mp4
Specifying the quality of the output stream is a bit strange, however. There is always a difference of 8 between the setting used on the command line and the resulting quality of the output stream as shown on the console. A value of 37, for example, results in an output quality ‘q’ on the console of 29.
In many cases, the output video should only be a part of the input. There are various ways to cut the beginning and ending of a video, and some have nasty side effects like a black screen for a few seconds. The following parameters create a proper start and end in the output file:
# specifiy start and end time AFTER -i filename.mp4 -ss 00:02:00 -to 01:37:30
Another option I use frequently is to amplify the audio signal if it is too low in the input file:
# Transcode audio to aac and amplify volume by 3x -c:a aac -filter:a "volume=3.0"
And if you ever need to downscale a 4k video to 1080p and compress the result, here’s the ffmpeg command for that:
# -hwaccel cuda before the input file might # does NOT ALWAYS speed up things as single core use # for parts of the decoding could become the bottleneck! ffmpeg -i input.mp4 -c:v h264_nvenc -cq:v 37 -c:a aac -s hd1080 output-1080p.mp4
An amazing tool with so many options. For more details have a look here and here.