Sweet ffmpeg Script to Speed Up Convert Times with AMDGPU

Sweet ffmpeg Script to Speed Up Convert Times with AMDGPU

After pulling all the photos and videos from my wife’s iPhone I soon ran into an issue where I found all of her videos were a MOV format. Normally this is not an issue due the fact I can use VLC which can play anything I give it but other software, in this case Synology Photos, would not play this at all on the computer. On a mobile device it had no issues but if my computer has issues with it then I’m sure other devices would be afflicted as well.

This took me down a rabbit-hole where I soon found myself looking for some nice for loops and running ffmpeg on those MOV files to convert them to mp4. I came upon a script that does just that on a person’s blog that can be seen here: https://mrcoles.com/convert-mov-mp4-ffmpeg/. It was the last comment by Br. Bill that led me to a script that I will show here:

# Script done on CPU only
for f in *.mov *.MOV; do
   ffmpeg -i "$f" -vcodec h264 -acodec mp2 "${f%".[Mm][Oo][Vv]"}.mp4"
done;

After looking at this script I saw the next comment down suggest to use -acodec mp3 instead of -acodec mp2 which I added to my script soon afterwards.

I have a 12 core AMD CPU totaling 24 threads (AMD Ryzen 9 5900X) and running this script would max out every single one of them but even then it would only convert the video 1:1 per second of the video. Some of the videos were short but there were too many large ones, so I needed to speed things up.

I found some optimization tweaks online but each one brought me back to trying to run it in the most efficient way possible which was always going to be via the GPU. And since I recently got on the AMD GPU bandwagon with a 6700XT 12GB GPU, I decided to give it a try.

After finding the correct syntax to run ffmpeg on an AMD GPU which can be found on the Arch wiki site, (gotta love the Arch wiki), using this link: https://wiki.archlinux.org/title/FFmpeg, the script now runs the conversion twice as fast as before. Granted I was looking for something even faster, but double the speed is a nice jump just from making some tweaks and calls to a script. One thing you may need to take into account is my videos that are being converted are on my Synology NAS and is being run over NFS to my computer. So your mileage may vary be better than mine if you ran it all on the same machine and fast storage (SSD or NVMe).

Here is the final script:

# Script done on AMD GPU
for f in *.mov *.MOV; do
   ffmpeg -n -i "$f" -vaapi_device /dev/dri/renderD128 -vcodec h264_vaapi -vf format='nv12|vaapi,hwupload' -acodec mp3 "${f%".[Mm][Oo][Vv]"}.mp4"
done;

If you take a close look I also added a -n flag right after ffmpeg which means to n(ot) clobber or in other words to not overwrite the ones that have already been converted.

One caveat is you must install the libva-mesa-driver which is the open-source drivers for the GPU. Since I was running the proprietary AMD blob version, this caused the script to not work at all.

I also installed a program called radeontop which is a cli monitor for AMDGPUs. Run it with the -c flag: radeontop -c and it gives you a live view of the GPU.

/images/radeontop.png

This pic was taken right after the ffmpeg script just finished. Whoops. ¯\_(ツ)_/¯

The Graphics pipe was hitting around 5-10% while the script was running.

I’m sure with more tweaks and fine tuning I could get faster conversion speeds but for right now 2:1 was good enough.

Latest update over one year later…

After running this script in a variant to convert .mkv rather than .mov, the GPU’s Graphics Pipe ran around 12.50% to 20% and the script from above seemed like it was doing all the videos at the same time rather than one at a time.