How to compile ffmpeg 5 with x86_64 and ARM64 support - ffmpeg

I'm building ffmpeg version 5.0.1 from source, but for some reason I don't get it to cross-compile against aarch64 as I want to run ffmpeg on a Khadas VIM4 which is a ARMv8 CPU, to be specific the CPU is an Amlogic A311D2 with non-free codecs..
To build ffmpeg from source, I have setup a build-suite put together from various sources which currently works fine with x86_64 and can be obtained here: https://github.com/venomone/ffmpeg_build_suite
Simply run trigger.sh from the terminal, make sure docker is installed on your host if you are interested. The script will output ffprobe and ffmpeg in a folder called /build
From my understanding, the ffmpeg configuration part must get extended by the following lines:
--enable-cross-compile \
--target-os=linux \
--arch=arm64 \
--cross-prefix=aarch64-linux-gnu- \
--enable-shared \
But even with these settings, I'm running into the following error:
#11 938.3 aarch64-linux-gnu-gcc is unable to create an executable file.
#11 938.3 C compiler test failed.
Is somebody able to provide me a hint, what might be the problem here?

Related

How to --enable-protocol=SRT of ffmpeg?

all I am trying to --enable-protocol=SRT of ffmpeg. What I do as the following:
1.Check current configuration of ffmpeg which shows it doesn't suppport protocol of SRT.
2.So I trying to use msys64 to compile ffmpeg with --enable-protocol=SRT,and the command
$ ./configure --toolchain=msvc --arch=x64 --enable-yasm --enable-asm --enable-shared --enable-protocol=SRT
but the result as the following:
it's showing that the config is no use.Can you help me,thanks!
SRT is provided via an external library, so you'll need that library available for linking via pkg-config.
configure flags are --enable-protocol=libsrt --enable-libsrt. The former flag is only needed if you have disabled all components or protocols. Won't hurt to keep it, though.

ffmpeg ERROR: libnpp not found in windows

I`m trying to compile ffmpeg in windows with nvidia libraries for hardware acceleration using MinGW/msys. tried to follow the instruction on nvidias website (section: Getting Started with FFmpeg/libav using NVIDIA GPUs). configured with --enable-nonfree --disable-shared --enable-nvenc --enable-cuda --enable-cuvid --enable-libnpp --extra-cflags=-Ilocal/include --extra-cflags=-I../common/inc --extra-ldflags=-L../common/lib/x64 --prefix=ffmpeg but stopped at "ERROR: libnpp not found." where common folder is downloaded from NVIDIA Video Codec SDK but there is no npp libs or header files. is there any solution for that? thanks for edvice.
I managed to successfuly cross compile ffmpeg under linux targeting Windows 64 bit with --enable-libnpp included.
My environment is Ubuntu Server 16.10 64bit.
After a fresh installation I installed MinGW using the command:
sudo apt-get install mingw-w64
First I successfully compiled the Linux version with the --enable-libnpp option activated following the instructions on the NVIDIA dev site Compile Ffmpeg with NVIDIA Video Codec SDK.
In order to do that you need to install the CUDA Toolkit. Just follow the instructions and the package installer will create the symbolic links (I have the CUDA Toolkit 8.0):
/usr/local/cuda/include/ -> /usr/local/cuda-8.0/targets/x86_64-linux/include
/usr/local/cuda/lib64/ -> /usr/local/cuda-8.0/targets/x86_64-linux/lib
This should provide Configure the right path to find the correct libraries and headers.
The command line I have used to compile the linux version of ffmpeg is:
./configure --enable-nonfree --disable-shared --enable-nvenc --enable-cuda --enable-cuvid --enable-libnpp --extra-cflags=-I/usr/local/cuda/include/ --extra-ldflags=-L/usr/local/cuda/lib64/
The problem you got is that when using cross-compilation you need to provide Configure the right path where to find headers and library for the Windows version of the libnpp library.
From the CUDA Toolkit Download page mentioned above I simply downloaded the exe(local) version of the Windows package.
Under the root of my working folder I created a folder called tmp where I copied the subfolders I found under npp_dev inside the package cuda_8.0.61_win10.exe:
cuda_8.0.61_win10.exe\npp_dev\lib -> tmp/lib
cuda_8.0.61_win10.exe\npp_dev\include -> tmp/include
As final step I launched Configure once again using the following parameters:
./configure --arch=x86_64 --target-os=mingw32 --cross-prefix=x86_64-w64-mingw32- --pkg-config=pkg-config --enable-nonfree --disable-shared --enable-nvenc --enable-cuda --enable-cuvid --enable-libnpp --extra-cflags=-I/usr/local/include --extra-cflags=-I/usr/local/cuda/include/ --extra-ldflags=-L/usr/local/cuda/lib64/ --extra-cflags=-I../tmp/include/ --extra-ldflags=-L../tmp/lib/x64/
The compilation completed successully. When I copied the ffmpeg.exe file to Windows and tried to execute it I got an errore message saying the executable was missing some npp_*.dll.
From the package cuda_8.0.61_win10.exe I copied all the dlls included into the folder npp\bin to the same directory I put ffmpeg.exe.
After that the application run normally and a simple conversion from a 4K file completed as expected.
Actually I went nuts about ffmpeg is not building with the same problem. I fianally managed to get it worked under Windows 10 x64:
Download msys2 from https://www.msys2.org/ and install all packages with Pacman
pacman -Su
pacman -S make
pacman -S diffutils
pacman -S yasm
pacman -S mingw-w64-x86_64-gcc
pacman -S mingw-w64-x86_64-toolchain
add pkgconfig to environment variable PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
Add additional installed toolchain to path: PATH=$PATH:/opt/bin
Start mingw64 version: C:\msys64\msys2_shell.cmd -mingw64
Download and install Cuda from nVidia https://developer.nvidia.com/cuda-downloads?target_os=Windows&target_arch=x86_64&target_version=10&target_type=exenetwork
Extract the downloaded file e.g. cuda_11.2.2_461.33_win10.exe with 7zip locally
Copy cuda_nvcc\nvcc\include to your msys2 e.g. C:\msys64\tmp\nvidia_include
Copy libnpp\npp_dev\lib\x64 to your C:\msys64\tmp\nvidia_lib\x64
Copy libnpp\npp_dev\include to C:\msys64\tmp\nvidia_npp_include
git clone https://github.com/FFmpeg/FFmpeg.git to C:\msys64\home\<user>
git clone https://github.com/libav/libav to C:\msys64\home\<user>
Maybe optional step: git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git to C:\msys64\home\<user>
make
make install
Optional because make install should have done this for you: Copy ffnvcodec.pc to C:\msys64\usr\local\lib\pkgconfig
Build libav avconv.exe and avprobe.exe are needed for ffmpeg later:
cd C:\msys64\home\<user>\libav
./configure
make
make install
Finally build ffmpeg:
cd C:\msys64\home\<user>\ffmpeg
./configure --enable-nonfree --disable-shared --enable-nvenc --enable-cuda --enable-cuvid --enable-libnpp --extra-cflags=-I/tmp/nvidia_npp_include --extra-cflags=-I/tmp/nvidia_include --extra-ldflags=-L/tmp/nvidia_lib/x64
make
make install
Copy avconv.exe and avprobe.exe to ffmpeg directory
Done.
Bugfixing:
Missing DLLs: find x64 missing DLLs on your harddisk or in internet.
Use dependency walker for analyzing errors
Download the newest nVidia drivers and use nSight making sure CUVID is supported for your graphic card.
This would seem to be caused by a broken configuration script in the FFmpeg code base. There is no library called npp in recent CUDA distributions, instead on Windows platforms you will have
nppc.lib
nppi.lib
npps.lib
and on linux
libnppc.so
libnppi.so
libnpps.so
You will either need to modify the configuration system yourself or file a bug request with the project developers to do it for you.
There might still be additional problems building the project with MinGW, but that is way beyond the scope of a Stack Overflow question.
If you check config.log, there may have a lot link warnings:
LINK : warning LNK4044: unrecognized option '/L...'; ignored
cause
ERROR: libnpp not found.
Since /L is not a correct argument for msvc linker, in order to include library path, the argument should as follow:
./configure .... --extra-cflags=-I/usr/local/cuda/... --extra-ldflags=-LIBPATH:/usr/local/cuda/...
This should able to solve the libnpp not found issue.
FYI, linker options are listed in the following link (included LIBPATH):
Linker Options
2022 Update
On this weekend I also managed to build latest ffmpeg with working scale_npp filter. Without any npp missing library error during compilation and building. But with some caveats (see below).
I followed this guide by NVIDIA with installed NVIDIA GPU Computing Toolkit v11.7 and latest driver display 473.47 for my video card GeForce GT 710 on Windows 10 21H2 x64
Changes (adaptations) for steps in the guide
I copied all headers including folders from directory path_to_CUDA_toolkit/include
I excluded pkg-config from pacman packages, because after recommended installation steps (step 7 in particular) of MSYS2 it conflicts with installed pkgconf package, i.e. use this command instead:
pacman -S diffutils make yasm
I added directories to Visual Studio C compiler to PATH environment variable in advance (using Windows GUI), in addition to declaring them in the MinGW64 terminal as specified in the guide:
export PATH="/c/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64/":$PATH
export PATH="/d/NVIDIA GPU Computing Toolkit/CUDA/v11.7/bin/":$PATH
After making (building) ffnvcodec headers, define PKG_CONFIG_PATH (where compiled file ffnvcodec.pc is located) before configure command.
Use absolute paths for --extra-cflags and --extra-ldflags options of configure command. It's probably the main thing in solving "not found" errors. But don't forget that these paths will be printed in ffmpeg banner with other explicit build options.
PKG_CONFIG_PATH="/d/_makeit/nv-codec-headers/" ./configure --enable-nonfree --disable-shared --enable-cuda-nvcc --enable-libnpp --toolchain=msvc --extra-cflags="-I/d/_makeit/ffmpeg/nv_sdk/" --extra-ldflags="-LIBPATH:/d/_makeit/ffmpeg/nv_sdk/"
And that's it. At least -vf scale_npp should work.
In my case still DO NOT WORK the following things from the guide:
cuda built-in resizer and cropper, i.e. -hwaccel_output_format cuda –resize 1280x720 and -hwaccel_output_format cuda –crop 16x16x32x32. I bet that this is due to my old video card is not in GPU Support Matrix. But NVENC and NVDEC works fine for me almost without crutches. And it seems I'm note alone.
UPD: resizer and cropper work! BUT in the mentioned guide commands are incorrect. I found correct way in another NVIDIA FFmpeg Transcoding Guide. Decoder h264_cuvid was missed, must be so:
ffmpeg.exe -y -vsync passthrough -hwaccel cuda -hwaccel_output_format cuda -c:v h264_cuvid -resize 1280x720 -i input.mp4 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4
ffmpeg.exe -y -vsync passthrough -hwaccel cuda -hwaccel_output_format cuda -c:v h264_cuvid -crop 16x16x32x32 -i input.mp4 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4
-vf scale_cuda fails with error. Maybe I used wrong C compiler version or didn't install DirectX SDK from here or installed wrong packages after installing MSYS2 and ignoring pkg-config
[Parsed_scale_cuda_0 # 000001A461479DC0] cu->cuModuleLoadData(cu_module, data) failed -> CUDA_ERROR_UNSUPPORTED_PTX_VERSION: the provided PTX was compiled with an unsupported toolchain.
there is no possibility to use -preset option for h264_nvenc with latest ffmpeg version where presets (enum) were updated. I noticed from ffmpeg report file, this is because using any preset causes "auto" enabling lookahead mode with log raw:
[h264_nvenc # 00000158EFC6E500] Lookahead enabled: depth 28, scenecut enabled, B-adapt enabled.
Even though the options -rc-lookahead and -temporal-aq are not supported by my device (video card). I have to use only one preset p4 (medium) which is by default. And I don't know how to workaround this issue. Value 0 for -rc-lookahead also does not help.
specifying -bf 2 only works with option -extra_hw_frames 6 (six in my case - number of extra frames can differ for your card). Or using only -bf 0. But this is due to constraints of my old video card.
ffmpeg.exe -v verbose -y -vsync passthrough -hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 6 -i input-1080p.mkv -map 0:v -map 0:a -c:a copy -c:v h264_nvenc -b:v 1M -bf 2 -bufsize 1M -maxrate 2M -qmin 0 -g 250 -b_ref_mode middle -i_qfactor 0.75 -b_qfactor 1.1 output.mp4
I hope my notes will help future Google and SO users.

Building Qt 5.6 on macOS for the Raspberry Pi 3

I am trying to set up a cross compiling environment for the Raspberry Pi 3 on my Mac because compiling on the Pi just became to slow.
Following this guide I successfully created a cross compiler using crosstool-ng that is able to compile a simple "Hello World" program that runs on the Pi.
I try to follow the RaspberryPi2EGLFS-Guide on the Qt wiki.
It is written for Ubuntu but that should not make a difference when you have a compiler for your host system, does it?
I created the sysroot and fixed symbolic links as described in the guide, but the configure command for Qt fails.
./configure \
-release \
-opensource -confirm-license \
-make libs \
-opengl es2 \
-device linux-rpi3-g++ \
-sysroot $SYSROOT \
-opensource -confirm-license -make libs \
-prefix /usr/local/qt5pi -extprefix ~/dev/raspi/qt5pi \
-hostprefix ~/dev/raspi/qt5 \
-device-option CROSS_COMPILE=$TOOLCHAIN \
-v
There, $TOOLCHAIN points to the toolchain I compiled and $SYSROOT is the sysroot I set up according to the guide.
But the command fails with a bunch of errors because header files could not be found:
fatal error: sys/cdefs.h: No such file or directory
fatal error: zconf.h: No such file or directory
fatal error: sys/types.h: No such file or directory
Edit 12-14-2016
Apparently the compiler can't determine the cpu architecture:
/Volumes/xtools/armv8-rpi3-linux-gnueabihf/lib/gcc/armv8-rpi3-linux-gnueabihf/5.2.0/../../../../armv8-rpi3-linux-gnueabihf/bin/ld.gold: error: /Volumes/xtools/armv8-rpi3-linux-gnueabihf/armv8-rpi3-linux-gnueabihf/sysroot/usr/lib/crti.o: unknown CPU architecture
From my (limited) understanding, these headers should apear somewhere in $SYSROOT.
I have checked my sysroot, the missing headers a located in $SYSROOT/usr/include/arm-arm-linux-gnueabihf/.
I created a symlink from there to $SYSROOT/sys but that did not work either.
Am I missing something?
Other threads suggest installing g++-multilib on the host system, but there is no multlib-equivalent on macOS.

How can I get FFmpeg to locate installed libraries when --sysroot is pointing to another directory?

I've been going at this, literally for days. I'm trying to build FFmpeg with libmp3lame for use in an Android application. The build script sets a --sysroot flag that points to the Android NDK directory necessary to build these libraries in a way that Android can use them.
The problem comes when I add the flag to --enable-libmp3lame; I get ERROR: libmp3lame >= 3.98.3 not found during the build start up. I know that LAME, and it's libraries are installed, because I can just run ./configure --enable-libmp3lame manually and the configuration launches without a hitch, and shows that libmp3lame is enabled for this build. However, building like this will simply not work for what I need it for, since I need the Android NDK to do some work.
I've tracked the problem down to the fact that this build script is declaring the sysroot, and through some research, I've tried adding -Luser/include, -L/user/includeto the extra cflags, and ldflags (which I've read is the default search location for gcc). I've tried several other things as well, but I'm confident that someone out here can help with this specific problem. This entire build script is as follows:
Extra info:
Build OS: Ubuntu 11.10
FFmpeg Ver: Latest from git
LAME Ver: 3.9.x
Android NDK: r7
build.sh
#!/bin/bash
if [ "$NDK" = "" ]; then
echo NDK variable not set, assuming ${HOME}/android-ndk
export NDK=${HOME}/android-ndk
fi
SYSROOT=$NDK/platforms/android-3/arch-arm
# Expand the prebuilt/* path into the correct one
TOOLCHAIN=`echo $NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/*-x86`
export PATH=$TOOLCHAIN/bin:$PATH
rm -rf build/ffmpeg
mkdir -p build/ffmpeg
cd ffmpeg
# Don't build any neon version for now
for version in armv5te armv7a; do
DEST=../build/ffmpeg
FLAGS="--target-os=linux --cross-prefix=arm-linux-androideabi- --arch=arm"
FLAGS="$FLAGS --sysroot=$SYSROOT"
FLAGS="$FLAGS --soname-prefix=/data/data/net.smartnotes/lib/"
FLAGS="$FLAGS --enable-shared --disable-symver"
FLAGS="$FLAGS --enable-small --optimization-flags=-O2"
FLAGS="$FLAGS --disable-everything --enable-protocol=file"
FLAGS="$FLAGS --enable-libmp3lame --enable-encoder=nellymoser"
case "$version" in
neon)
EXTRA_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon"
EXTRA_LDFLAGS="-Wl,--fix-cortex-a8"
# Runtime choosing neon vs non-neon requires
# renamed files
ABI="armeabi-v7a"
;;
armv7a)
# I have tried many things here.
EXTRA_CFLAGS="-march=armv7-a -mfloat-abi=softfp"
EXTRA_LDFLAGS=""
ABI="armeabi-v7a"
;;
*)
# I have tried many things here.
EXTRA_CFLAGS="-Luser/include"
EXTRA_LDFLAGS=""
ABI="armeabi"
;;
esac
DEST="$DEST/$ABI"
FLAGS="$FLAGS --prefix=$DEST"
mkdir -p $DEST
echo $FLAGS --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" > $DEST/info.txt
./configure $FLAGS --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" | tee $DEST/configuration.txt
[ $PIPESTATUS == 0 ] || exit 1
make clean
make -j4 || exit 1
make install || exit 1
done
Instead of changing the include paths, why don't you try copying all the libmp3lame files that were created by 'make install' to the relevant directory where the script will look for them. Insert ECHO statements to find out what exactly the PATH/CFLAGS/LDFLAGS are at the point where you get the error, and copy the files there so it does find them.
I saw you were using the project located at
http://bambuser.com/opensource
I had the same problem and resolved like this:
compile lame for android using https://github.com/intervigilium/liblame
this is a small diff between the original build.sh from "bambuser.com" and the one I used:
3c3,6
< export NDK=${HOME}/downloads/android-ndk # r8d
---
> if [ "$NDK" = "" ]; then
> echo NDK variable not set, assuming ${HOME}/android-ndk
> export NDK=${HOME}/android-ndk
> fi
15,16c18
< #for version in armv5te armv7a; do
< for version in armv7a; do
---
> for version in armv5te armv7a; do
24c26
< FLAGS="$FLAGS --disable-everything --enable-libmp3lame"
---
> FLAGS="$FLAGS --disable-everything"
from "intervigilium" project copy the folder liblame/jni/lame to PATH_TO_NDK/platforms/android-3/arch-arm/usr/include
from "intervigilium" project copy liblame/libs/armeabi-v7a/liblame.so to PATH_TO_NDK/platforms/android-3/arch-arm/usr/libs and RENAME it in libmp3lame.so.
finally run build.sh.
you should be fine:
install prefix ../build/ffmpeg/armeabi-v7a
source path /home/samuele/downloads/ffmpeg/ffmpeg-android/ffmpeg
C compiler arm-linux-androideabi-gcc
ARCH arm (generic)
big-endian no
runtime cpu detection no
ARMv5TE enabled yes
ARMv6 enabled yes
ARMv6T2 enabled yes
ARM VFP enabled yes
IWMMXT enabled no
NEON enabled no
debug symbols yes
strip symbols yes
optimizations small
static yes
shared yes
postprocessing support no
new filter support yes
network support yes
threading support pthreads
SDL support no
Sun medialib support no
AVISynth enabled no
frei0r enabled no
libdc1394 support no
libdirac enabled no
libfaac enabled no
libgsm enabled no
**libmp3lame enabled yes**
libnut enabled no
libopencore-amrnb support no
libopencore-amrwb support no
libopencv support no
libopenjpeg enabled no
librtmp enabled no
libschroedinger enabled no
libspeex enabled no
libtheora enabled no
libvorbis enabled no
libvpx enabled no
libx264 enabled no
libxavs enabled no
libxvid enabled no
zlib enabled no
bzlib enabled no
Enabled decoders:
Enabled encoders:
mpeg2video nellymoser
Enabled hwaccels:
Enabled parsers:
Enabled demuxers:
Enabled muxers:
Enabled protocols:
Enabled filters:
buffer
Enabled bsfs:
Enabled indevs:
Enabled outdevs:
License: LGPL version 2.1 or later
Creating config.mak and config.h...
libavutil/avconfig.h is unchanged
Be aware, I still need to test the resulting FFmpeg build.
To say the truth, now I have to learn how to use it in my App... ;)
EDIT: I tried removing --disable-everything and it builds OK the same, with a lot of encoders, decoders etc, but increasing to ~40MB for the build dir.

ffmpeg crashes on cygwin on launch with exit code 0xc0000022

I am trying to build ffmpeg with libx264 support. Configure and compilation is successful but when I am running the ffmpeg the application is crashing.
ffmpeg configure option : ./configure --enable-static --enable-libx264 --enable-pthreads --enable-gpl --disable-doc --enable-memalign-hack --extra-ldflags="-L/usr/local/lib"
gcc --version 4.3.4
Here is gdb dump,
$gdb ffmpeg_g.exe
GNU gdb(GDB) 7.2
Copyright(c) 2010 Free Software Foundation
This GDB has configured as mingw32
Reading symbols from C:\work\ffmpeg25jan2011\ffmpeg\ffmpeg_g.exe.....done
(gdb) break main
BreakPoint 1 at 0x40a120 : file ffmpeg.c, line 4317
(gdb) run -V
Starting program: C:\work\ffmpeg25jan2011\ffmpeg\ffmpeg_g.exe
[New Thread]
gdb: Unknown Target exception 0xc0000022 at 0x7c96671e
**During startup program exited with code 0xc0000022**
Anybody has any clue, How this can be resolved?
Windows error code 0xc0000022 means "The Application Failed to initialize." It usually indicates that your build is broken. There are lots of things that could have gone wrong, but here are some things to check:
You should build all libraries you link to with the same toolchain. It may be possible to link a Cygwin-built ffmpeg to a VC++-built libx264, but since there's no good reason to do that, you shouldn't.
Try the "head" version of ffmpeg and its dependencies from the source repository
You show Windows paths, but claim to be using Cygwin. Try to use an all-Cygwin environment: build from a Cygwin bash shell, use POSIX paths, etc. In particular, this will help ensure that libraries get installed in places the build tools can find them.
You may need to install some libraries in /usr/lib, rather than the default, /usr/local/lib.
Try a complete rebuild: make clean && make

Resources