Building ffmpeg 6 on Windows 10
Introduction
ffmpeg is a cross-platform solution to record, convert, and stream audio and video. It can be used from Unreal Engine to change image formats, to record gameplay, and to convert content to and from various video formats. Here I am using it just to show how an Unreal Engine plugin can be developed.
ffmpeg can be downloaded from the https://ffmpeg.org/ or from https://git.ffmpeg.org/ffmpeg.git.
We download the source as a step in the build process. This is important because we use a Unix-like environment to configure and build the software, and dowloading using git from Windows can result in line-endings which are incompatible with Unix line-endings.
ffmpeg is cross-platform meaning it can be compiled for Windows, Linux, Macs and other operating systems and architectures. It has a Unix-based build system which uses Unix tools for configuring the build and finding and building dependent libraries. ffmpeg supports many different video encoders and decoders, some of which are downloaded separately from different websites if they are needed for the version you are building.
Approaches to building ffmpeg
We will be using a Unix-like terminal emulation approach to build ffmpeg. There are many alternative approaches to building ffmpeg from different sites including:
- building in docker
- parsing the Linux configure files to generate a Visual Studio .sln file
- downloading one big script that configures the build, downloads all the build tools, and builds in one go
None of the above tools worked for me, whether because they were out of date or my development system was not compatible I don't know. I didn't have time to dig into them in any depth.
Using MSYS2
MSYS2 is a command line terminal which looks and behaves like a Unix terminal and supports a collection of development tools. It is not a virtual machine (VM) like VMWare, in that VMWare typically has its own disk space, whereas MSYS2 shares its file system with Windows, so you can compile using the MSYS2 terminal and create executables and libraries are visible in the Windows file system.
Another difference from a VM is that while you are inside the MSYS2 terminal you can use both Unix-style commands and Windows commands. We will be using:
- a Unix-style "configure" command to create a makefile
- followed by a Unix-style "make" command which
- executes the Visual Studio C++ compiler
All this makes package management and diagnosing problems much more confusing then just using one operating system.
Using the right compiler
MSYS2 uses the Microsoft C/C++ compiler which is configured in the current environment. To create a 64 bit version
of ffmpeg we need to open the 64 bit command line; specifically the "x86_x64 Cross Tools Command Prompt"
which is an option under Visual Studio 2022 on the start menu:
If you open the 32 bit "x64_x86 Cross Tools Command Prompt" everything below will work but you will end up with a 32 bit version of ffmpeg which will not work with Unreal.
Preparation
Download and install MSYS2 from https://www.msys2.org/. I installed it to the d:\tools\msys64 directory so that is the path used in the examples below.
Install nasm from https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/win64/ to d:\tools\nasm.
Edit the msys2_shell.cmd command where MSYS2 is installed and uncomment one line, changing this line:
rem set MSYS2_PATH_TYPE=inherit
to:
set MSYS2_PATH_TYPE=inherit
Run MSYS2 with this command
d:\tools\msys64\msys2_shell.cmd -msys -use-full-path
Change the d:\tools\msys64
part to wherever you installed MSYS2
MSYS2 Prerequisites
Running msys2_shell.cmd will open a command shell. Run these commands one at a time to download and install development tools (you can't run them all at once, some of them may want you to restart the MSYS2 terminal):
pacman -Syu
pacman -S make
pacman -S diffutils
pacman -S yasm
pacman -S nasm
pacman -S mingw64/mingw-w64-x86_64-aom
pacman -S git
pacman -S pkg-config
mv /usr/bin/link.exe /usr/bin/link.exe.bak
Setup directories
Execute these commands:
cd /d/tools
mkdir ffmpeg6
cd ffmpeg6
mkdir build sources
Building x264
Many encoders or decoders which can be included in an ffmpeg build come from different projects and vendors. If you want them to be part of your ffmpeg they might need to be downloaded and built separately.
The x264 encoder is an example of one such module. To build it execute the commands below. The "CC=cl" part of the configure command on line 9 sets the CC environment variable to tell the build process to use the Microsoft "cl" compiler command
cd /d/tools/ffmpeg6/sources
git clone --depth 1 https://code.videolan.org/videolan/x264.git
cd x264
curl "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD" > config.guess
sed -i 's/host_os = mingw/host_os = msys/' configure
cd ../../build
mkdir x264
cd x264
CC=cl ../../sources/x264/configure --prefix=./../../installed --enable-shared
make -j 16
make install
mv ../../installed/lib/libx264.dll.lib ../../installed/lib/libx264.lib
Checking the build is 64 bits
Execute this command:
file ../../installed/bin/libx264-164.dll
you should see something like:
../../installed/bin/libx264-164.dll: PE32+ executable (DLL) (GUI) x86-64, for MS Windows,
which indicates it is a 64 bit build.
If you see this:
../../installed/bin/libx264-164.dll: PE32 executable (DLL) (GUI) Intel 80386, for MS Windows
You have accidently build a 32 bit version, probably because you have the wrong command prompt open.
Building ffmpeg
While still in the MSYS2 terminal do these steps to build ffpmeg command tools (ffmpeg, ffplay, ffprobe) and shared libraries which can be loaded into Unreal Engine.
Get the source:
cd /d/tools/ffmpeg6/sources
git clone --depth 1 git://source.ffmpeg.org/ffmpeg.git
Make a build directory:
cd ../build
mkdir ffmpeg
cd ffmpeg
Configure the build
Running a separate configuration pre-pass is a common approach in cross-platform software. This step uses all the MSYS2 packages we installed using the pacman command earlier.
The command line below also:
- sets the CC environment variable to tell the build process to use the Microsoft cl compiler command
- adds a directory (../../installed/lib/pkgconfig) to the PKG_CONFIG_PATH environment variable so that the configure command can find the
x264.pc
package configuration file which was created when we built the x264 project.
CC=cl PKG_CONFIG_PATH=$PKG_CONFIG_PATH:../../installed/lib/pkgconfig \
../../sources/ffmpeg/configure --prefix=../../installed \
--toolchain=msvc --target-os=win64 --arch=x86_64 \
--enable-x86asm --enable-asm --enable-shared \
--enable-gpl --enable-libx264 --enable-nonfree --enable-debug --disable-optimizations \
--extra-ldflags="-LIBPATH:../../installed/lib" \
--extra-cxxflags="-I../../installed/include/ -MTd -Od -Zi" \
--extra-cflags="-I../../installed/include/ -MTd -Od -Zi"
This configure command can take quite a while to run, sometime longer than the build itself.
Build
Execute these make commands to do the build and install the libraries and commands.
make -j 14
make install
The libraries which we built will be in /d/tools/ffmpeg6/installed/bin directory.
References
Feedback
Please leave any feedback about this article here