compile ffmpeg4.2.2

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: By configure --helplooking at the configurations we can choose. Go to view configure configuration option comments . After this step, many Makefilethings needed for compilation will be generated. Among them, ffbuild/config.logyou can view the current execution log.
  • (2) make install: Compile and generate what we configured. If it has been compiled before, make cleanthe data compiled before needs to be cleared before execution make install.

process

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 configurethe 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-bsfsviewing all supported formats for conversion.
  • decoders:decoder. By ./configure --list-decodersviewing all supported codecs.
  • encoders:Encoder. Check out ./configure --list-encodersall supported encoders.
  • hwaccels: hardware codec. By ./configure --list-hwaccelsviewing all supported hardware codecs.
  • parsers: parser. By ./configure --list-parsersviewing all supported parsers.
  • indevs: Input device (such as Android camera). By ./configure --list-indevsviewing all supported input devices.
  • outdevs: output device (such as opengl). By ./configure --list-outdevsviewing all supported output devices.
  • filters: filter processor (like gblur Gaussian blur). By ./configure --list-filtersviewing all supported filter processors.
  • muxers: Encapsulation (such as dismantling the flv container format video into video streams, audio streams, etc.). Check ./configure --list-muxersout all supported packages.
  • demuxers: Decapsulation (corresponding to encapsulation). By ./configure --list-demuxerslooking at all can support decapsulation.
  • protocols: protocol (such as rtmp). By ./configure --list-protocolslooking 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

configureThe 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 configurethe configuration file that the ffplay program needs to rely on the sdl2 library. brew install sdl2Mac can be installed by executing the command.

  • (2) Compile and verify ffplay

Write build.sha 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.
output

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 ./ffplaycommand 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 --helpto 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 configurefound 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 protocolsin support rtmp:

  • (1) How to get started?

We know that all compilations come from configurethe configuration file, so we have to find the information we need from this file. I just started looking for rtmprelevant information, only to find librtmpthe enabling or canceling of the library, and then compiled it, and found that it is not! Then I searched protocolsand 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.shthe 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 rtmpagreement 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 CFLAGSthe sum LDFLAGS(that is, --extra-cflagsthe sum --extra-ldflags) to compile and pass. The compilation script is given here. Before writing, we rename the downloaded and decompressed x264 library and libx264put it into the root directory of the ffmpeg project. Modify build.shthe 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 libx264the 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 ffmpegprogram 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.shthe 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.
  • configureThe file is very important, and shellthe 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 $CCon some API versions .xxx-clang

reference

  • https://blog.csdn.net/leixiaohua1020/article/details/44587465
  • https://blog.csdn.net/leixiaohua1020/article/details/44556525


Guess you like

Origin blog.csdn.net/github_38117599/article/details/112747857