The starting address will be even more wrong
foreword
Before compiling FFmpeg, we must first know what content (components) FFmpeg contains, how should we view and select? Here we briefly talk about the process of FFmpeg compilation, as well as integrating x264 and compiling the dynamic library required for the android platform. (The test here uses the Mac system)
FFmpeg compilation process
The compilation process is mainly divided into two steps (below):
- (1)
configure
: Byconfigure --help
looking at the configurations we can choose. Go to view configure configuration option comments . After this step, manyMakefile
things needed for compilation will be generated. Among them,ffbuild/config.log
you can view the current execution log. - (2)
make install
: Compile and generate what we configured. If it has been compiled before,make clean
the data compiled before needs to be cleared before executionmake install
.
Note: The generated execution file or portable class library will be different according to the system. For example, when generating ffplay
: Unix system will be ffplay
, windows will be ffplay.exe
.
FFmpeg basic composition structure
From configure
the configuration file, we can see that the basic structure of FFmpeg can be divided into the following parts (below):
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-UkjOnZTY-1610868972645)(03_build_ffmpeg/build-struct.png)]
It is mainly composed of four basic modules AVCodec
(related to codec), AVDevice
(related to input/output devices), AVFilter
(related to filtering processing) and AVFormat
(related to data format processing). Under these four modules, some small modules are subdivided. Here is a brief description of the functions of the small modules:
bsfs
: format conversion. By./configure --list-bsfs
viewing all supported formats for conversion.decoders
:decoder. By./configure --list-decoders
viewing all supported codecs.encoders
:Encoder. Check out./configure --list-encoders
all supported encoders.hwaccels
: hardware codec. By./configure --list-hwaccels
viewing all supported hardware codecs.parsers
: parser. By./configure --list-parsers
viewing all supported parsers.indevs
: Input device (such as Android camera). By./configure --list-indevs
viewing all supported input devices.outdevs
: output device (such as opengl). By./configure --list-outdevs
viewing all supported output devices.filters
: filter processor (like gblur Gaussian blur). By./configure --list-filters
viewing all supported filter processors.muxers
: Encapsulation (such as dismantling the flv container format video into video streams, audio streams, etc.). Check./configure --list-muxers
out all supported packages.demuxers
: Decapsulation (corresponding to encapsulation). By./configure --list-demuxers
looking at all can support decapsulation.protocols
: protocol (such as rtmp). By./configure --list-protocols
looking at all supported protocols.
Select modules to compile
The above briefly introduces the compilation process of ffmpeg and which class libraries are included in the ffmpeg library. Knowing this, we can choose the class library we need to compile. If the ffmpeg compiled by default will be quite large, like a dynamic library transplant, it will be very troublesome if the library is too large. And some third-party libraries like x264 library also need to know how to configure. Here we will discuss how to choose the class library we need for compilation.
Prepare
- (1) Download the ffmpeg source file , choose according to your own system, and decompress it after downloading.
- (2) Refer to official documents , such as: Mac needs to follow Xcode, etc., and you should also read the introduction of official website documents first when compiling. (The most reliable way, right?)
- (3) Master the basic knowledge of Shell , in order to facilitate modification and compilation.
- (4) Download x264 , which is required for "Test 3".
- (5) Download NDK , pay attention to the type of the system. "Test 4" needs to be used.
Test 1: Only compile the ffplay program
configure
The default in the configuration file is to output all programs (ffmpeg, ffplay and ffprobe). But because ffplay needs the sdl2 library, so here is how to configure the ffplay program to output only.
- (1) Install sdl2
It is known from configure
the configuration file that the ffplay program needs to rely on the sdl2 library. brew install sdl2
Mac can be installed by executing the command.
- (2) Compile and verify ffplay
Write build.sh
a script file in the root directory of the project and authorize it, as follows. Then execute it directly in the console ./build.sh
.
#!/bin/bash
./configure \
--disable-programs \
--enable-ffplay
make clean
make install
Then see the output information in the console and find that only the ffplay program will be compiled.
After waiting for more than ten minutes, we found that only the ffplay executable file was generated in the root directory of the project. We executed the du -sh ./ffplay
command on the console to see that the size of the generated file was 20M.
qincji:ffmpeg mac$ du -sh ./ffplay
20M ./ffplay
Execute the command to play an rtmp: ./ffplay -window_title "版本1" rtmp://slive.ytn.co.kr/dmb/ydlive_20140419_1
, the result is as follows:
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-CS8wIbBH-1610868972653) (03_build_ffmpeg/build-ffplay-rtmp.jpg )]
Well, the ffplay player we compiled can be used normally. Use ./ffplay --help
to view specific usage.
- (3) Find the reason for this configuration
We have already known the compilation results above, and we need to find out the reason here. Why is this? We configure
found some clues from the file:
#略……………………
#program队列
PROGRAM_LIST="
ffplay
ffprobe
ffmpeg
"
#略……………………
#disable方法,将调用set_all,并传值为no,以及将要设置disable的名称($*)。
disable(){
set_all no $*
}
#略……………………
set_all(){
value=$1
shift
for var in $*; do
eval $var=$value
done
}
:<<EOF
这里的opt其实就是我们输入的 --disable-programs 和 --enable-ffplay
./configure \
--disable-programs \
--enable-ffplay
EOF
for opt do
optval="${opt#*=}"
case "$opt" in
#略……………………
#当我们配置了--disable-programs,就会命中这里,将PROGRAM_LIST列表里面的disable掉。
--disable-programs)
disable $PROGRAM_LIST
;;
#略……………………
#当我们配置了--enable-ffplay时,就会命中这里,将启用ffplay。这里语法不太熟悉,我们可以在这个地方中打印就下即可
*)
optname="${opt%%=*}"
optname="${optname#--}"
optname=$(echo "$optname" | sed 's/-/_/g')
if is_in $optname $CMDLINE_SET; then
eval $optname='$optval'
elif is_in $optname $CMDLINE_APPEND; then
append $optname "$optval"
else
die_unknown $opt
fi
;;
esac
done
#略……………………
Test 2: According to test 1, remove the support for rtmp protocol
In Test 1, we uncompile all the program modules first, and then select one of them. Here we choose to only remove a single component in a module. Let's take an example to cancel the protocol protocols
in support rtmp
:
- (1) How to get started?
We know that all compilations come from configure
the configuration file, so we have to find the information we need from this file. I just started looking for rtmp
relevant information, only to find librtmp
the enabling or canceling of the library, and then compiled it, and found that it is not! Then I searched protocols
and found a key piece of information, as follows:
#单个组件配置
Individual component options:
#略…………
#这就是我想要的!!后面NAME是rtmp!如何知道?通过 ./configure --list-protocols 看到所有支持协议的名称
--disable-protocol=NAME disable protocol NAME
--disable-protocols disable all protocols
- (2) Compilation verification results
Modify build.sh
the script as follows. Then execute it directly in the console ./build.sh
.
#!/bin/bash
./configure \
--disable-programs \
--enable-ffplay \
--disable-protocol=rtmp
make clean
make install
Then I saw the output information in the console, and found that Enabled protocols:
there is no rtmp
agreement in it!
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-dvH3BfzM-1610868972654)(03_build_ffmpeg/build-rtmp-hint.jpg)]
Wait for the compilation to complete, execute the command to play an rtmp: ./ffplay -window_title "版本2" rtmp://slive.ytn.co.kr/dmb/ydlive_20140419_1
, the result is as follows:
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-qKMKZLur-1610868972655)(03_build_ffmpeg/build-rtmp-nofound.jpg)]
The same is true for enabling or disabling other components.
Test 3: Integrate third-party libraries: x264
The ffmpeg official mac compilation guide integrates libx264 , but the information given is not very clear (some of which I don't understand). After several twists and turns, I found that it needs to specify CFLAGS
the sum LDFLAGS
(that is, --extra-cflags
the sum --extra-ldflags
) to compile and pass. The compilation script is given here. Before writing, we rename the downloaded and decompressed x264 library and libx264
put it into the root directory of the ffmpeg project. Modify build.sh
the script as follows. Then execute it directly in the console ./build.sh
.
#!/bin/bash
function build_x264() {
cd libx264
./configure \
--prefix=${X264_LIBS} \
--enable-static
make clean
make install
}
function build_ffmpeg() {
cd ..
./configure \
--disable-programs \
--enable-ffmpeg \
--enable-gpl \
--extra-cflags="-I${X264_LIBS}/include" \
--extra-ldflags="-L${X264_LIBS}/lib" \
--enable-libx264
make clean
make install
}
#设置x264变成出来的静态库保存路径,然后编译ffmpeg时,链接进去
X264_LIBS=$(pwd)/libx264/libouput
build_x264
build_ffmpeg
During the compilation process, we noticed the output information of the console and found that libx264
the protocol was enabled:
[External link image transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the image and upload it directly (img-cWRFuSDj-1610868972657) (03_build_ffmpeg/build-x264-enable.jpg)]
After the compilation is successful, verify whether the currently generated ffmpeg
program has been integrated libx264
, find an mp4 video and put it in the current directory, and name it input.mp4. Then execute the following command, if no error is reported, it has been successfully integrated:
./ffmpeg -re -i input.mp4 -vcodec libx264 -an output.mp4
Test 4: android cross compilation
ffmpeg official website android compilation guide , tested it, and finally found that these parameters are more critical:
--enable-cross-compile
: Enable cross-compilation.--cross-prefix
: Prefix for gcc. (If you use clang to compile, you can not give it)--target-os
: Specifies the platform used by android.--arch
: Processor type.--cpu
: cpu type.--cc
: C language compiler (for the currently specified absolute path).--cxx
: C++ language compiler (for the currently specified absolute path).--extra-cflags
: to the arguments passed to the compiler.
Modify build.sh
the script as follows. Then execute it directly in the console ./build.sh
.
#!/bin/bash
API=21
export NDK=/Users/Qincji/Desktop/develop/android/source/sdk/ndk-bundle
export SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
function build_android() {
./configure \
--prefix=$PREFIX \
--disable-programs \
--disable-static \
--enable-shared \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--cc=$CC \
--cxx=$CXX \
--enable-cross-compile \
--extra-cflags="$CFLAG" || exit 0
make clean
make install
}
ARCH=arm
CPU=armv7-a
CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU"
CFLAG="-Os -fpic $OPTIMIZE_CFLAGS"
build_android
Waiting for the compilation to complete, we found that the dynamic library can be successfully compiled:
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-aEiTqmVn-1610868972658)(03_build_ffmpeg/build-android-susccess.jpg)]
Summarize
Well, ffmpeg compilation has been basically finished. Here is a summary of some thoughts on my compilation process:
- Use the IDE to manage the project, just handle it yourself. I use clion here, and github has a cracking method.
configure
The file is very important, andshell
the grammar still needs to be understood a little bit.- If an error is reported, check the log
ffbuild/config.log
. - The path must be checked to see if it actually exists, for example, it may not exist
$CC
on some API versions .xxx-clang
reference
- https://blog.csdn.net/leixiaohua1020/article/details/44587465
- https://blog.csdn.net/leixiaohua1020/article/details/44556525