Compile the Android platform in the Unbuntu environment and use ffmpeg (with three-party libraries fdk-aac and lame)

Zero, ready

  • Compiler Environment:Ubuntu16.0.4
  • NDK version:android-ndk-r21c-linux-x86_64
  • ffmpeg version: 4.4.1
  • fdk-aac:  fdk-aac-2.0.2
  • lame: lame-3.100

1. Theoretical basis

1.1. Environment variables in the shell

There are three ways to set environment variables:

  • The first is NDKROOT=your actual path. This is a temporary environment variable, which is only visible and usable in the current terminal, and is invisible to some deeper compilations, unless you clearly know that your variables are in this layer of shell used in
  • The second is export CC=YOUR_CC, which is also a temporary environment variable, but its visibility is wider than the first one, and it can take effect or be used in sub-level or even deeper directories. So conservatively, when we reassign some system environment variables, we will addexport
  • The third is system-level environment variable configuration, which will be set when our terminal is initialized, NDKROOT path. We need to understand this because we need to simplify some content when writing our shell, such as defining common file paths as constants, and we only need to quote constants later, which is also very convenient for modification. For some environment variables of the system itself, setting the environment variable will overwrite its value, so when defining the environment variable, pay attention to whether you want to overwrite its value or create a new environment variable, through which you can view all environment variables under the terminal  envprint .

1.2, GCC related compilation instructions

When we compile the code available on the Android side, we first need to specify CCthe tool to be the C language compiler. If we do not specify that we use the default CC under Linux, the compiled program can only be used under Linux, and it is not available for the Android platform. After all, there is still a difference between the two, so we need to specify our CC. The CC path is under our NDK path. NDK includes compilation tools for each architecture, and of course CXX C++ language compiler. I will talk about it in detail below. Secondly, we need to specify the library. If the ffmpeg we compiled wants to integrate fdk-aac and other third-party libraries, we must import the dynamic link library and header files of the third-party library CFLAGS. )  -I三方库的头文件路径, and LDFLAGS(command line arguments to the linker)-L三方库的库文件路径(动态或静态库)

2. Configure NDK

  • Download the corresponding NDK version and extract it to the computer

Try not to use Chinese, and pay attention to the NDK version. If there are strange problems in the compilation that cannot be solved, you may wish to try another NDK version. If it is too old, don’t use it.

  • Set NDK path to environment variable

Open our environment variables file

vim ~/.bashrc

Add the path of our NDK at the end, and reassign PATH, PATH is the default environment variable of the system, we need to add it on the basis of it, otherwise the original environment variable will be unavailable

export NDKROOT=/home/zhoubin/Documents/android-ndk-r21c
export PATH=$NDKROOT:$PATH

make the environment variable take effect

source ~/.bashrc

3. Compile the appetizer

3.1 compile lame.so

  • Download the lame source code compression package and decompress it
  • Write our shell script (take 32-bit V7 as an example)

Write a build_v7.sh under the decompressed source path (name it whatever you want)

#NDKROOT我们已经配置环境变量了所以可以直接用,TOOLCHAIN我们在这设置一个零时变量
TOOLCHAIN="$NDKROOT/toolchains/llvm/prebuilt/linux-x86_64" 
#重新赋值我们的CC和CXX,用我们Android自己的C编译器,而且会有32和64之分
#32位V7的我们用armv7a-linux-androideabi
#64位V8的我们用aarch64-linux-android
HOST=armv7a-linux-androideabi
V=21
#至于这个21你可以自己选版本号,看你的目录下有哪些版本
export CC=$TOOLCHAIN/bin/$HOST$V-clang
export CXX=$TOOLCHAIN/bin/$HOST$V-clang++
echo $CC
#PREFIX定义我们的编译输出目录,这里指的是上级目录下新建armeabi-v7a文件夹存放
PREFIX=$(dirname $(pwd))/armeabi-v7a

#最简版本 指定编译动态链接库不编译静态库
#其它参数配置可以在lame源码根目录下执行./configure -h查看默认和支持的配置
function build_config
{
	./configure \
	--enable-static=no \
	--host=$HOST \ #我们代码需要运行的平台
	--disable-frontend \ #不编译可执行的命令程序
	--prefix=$PREFIX
}
build_config
make clean
make -j8 #8是线程数 数字越大编译速度越快,前提是你电脑支持
make install

If you compile directly like this, there will be problems. The problem lies in the ./fdk-aac-2.0.2/libSBRdec/src/lpp_tran.cpp file. It refers to a header file that cannot be found "log/log.h". We need to replace it with "android/log.h", and  android_errorWriteLogcomment out the method at the same time. If you value this log very much, you can replace it with your own log (possible but not necessary). In fact, you can also comment out the __ANDROID__three paragraphs with packages. If there is no accident after a while, we can see our .so library and header files in the PREFIX path we set.

3.2 Compile ffd-aac.so

In fact, the process is the same as that of lame. The difference is that fdk-aac does not have --disable-frontendthis configuration. You ./configure -hcan also know what configuration items are in its help.

4. Compile ffmpeg

  • Download ffmpeg source code

There are many ways to download, you can download the compressed package or get it by git clone

  • Modify the dynamic link library output name

If you do not modify the name of the dynamic link library, then its original appearance is libavutils.56.so. This form is different from our usual naming habits, and netizens say that Android cannot be loaded (there is no falsification here, which means little), So to be on the safe side, let's change the name. Modify the configure file in the root directory of the source code in

SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'  
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'  
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'  
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)'  

changed to

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'

  • write shell

With the previous experience, most of them are almost the same. The difference is that we need to import the compiled packages of ffd-aac and lame, so we need to configure them. We can configure the header files of ffd-aac and lame separately CFLAGS. LDFLAGSIt can also be placed in the same path as the library file path. I prefer to put it in the same path, at least there are not so many paths to specify. Others are the configuration settings of ffmpeg, which can also be passed

./configure -h

Check out the optional and default configuration of ffmpeg. The following is my shell script. We can set and enable specific compilers according to our own needs. For example, if we only do audio editing, we can only enable audio codecs and remove video codecs, so that our package The size is smaller and it takes less time to compile. Of course, if you don't mind the package size, you are more afraid that some codecs will miss the configuration. You can also make no specific settings, as long as we enable our ffd-aac and lame packages. . Of course, some configurations require tripartite packages. For example, ffplay needs to import SDL tripartite packages. It relies on SDL for playback. X264 also requires tripartite packages. By default, X264 is not included. Importing these tripartite packages is actually the same as lame. I won't talk about them one by one here. Some configurations I will comment in the following shell script, this is a v8 version of the shell script

#!/bin/bash
NDK=$NDKROOT

#我编译的ffd-aac和lame动态链接库生成的位置
EXTC=$(pwd)/libextern
lib_cflag="-I$EXTC/armeabi-v8a/include"
lib_ldflags="-L$EXTC/armeabi-v8a/lib"

#arm
CPU=arm

#版本号,可自选
V=21

#armv7a 和 aarch64
ARCH=aarch64

#32位V7的我们用armv7a-linux-androideabi
#64位V8的我们用aarch64-linux-android
HOST=aarch64-linux-android

TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin

CROSS_PREFIX=$TOOLCHAIN/aarch64-linux-android-

SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot

PREFIX=$(pwd)/android/$ARCH
configure()
{
    ./configure \
    --prefix=$PREFIX \
    --enable-cross-compile \#交叉编译所需配置 使能交叉编译
    --cross-prefix=$CROSS_PREFIX \#交叉编译所需配置,在这个路径下自动去找到nm ar等这些编译工具
    --target-os=android \#交叉编译所需配置 指定代码运行环境
    --arch=$ARCH \#交叉编译所需配置 指定架构(指令集)
    --extra-cflags=$lib_cflag \ #引入外部头文件
    --extra-ldflags=$lib_ldflags \ #引入外部链接库文件
    --cc=$TOOLCHAIN/$HOST$V-clang \
    --cxx=$TOOLCHAIN/$HOS$V-clang++ \
    --disable-static \
    --enable-shared \
    --disable-doc \#禁用文档编译
    --disable-programs \#禁用编译命令行程序
    --disable-avdevice \
    --disable-network \#禁用了网络加载音视频
    --disable-symver \
    --enable-gpl \#开源代码所需
    --enable-pic \#编译位置无关代码
    --enable-jni \#适配Android的jni
    --enable-pthreads \
    --enable-libfdk-aac \
    --enable-neon \#开源代码所需 fdk-aac和lame需要,毕竟别人开源的东西
    --enable-nonfree \#开源代码所需
    --enable-libmp3lame 
  
}

build()
{
    configure
    make clean
    make -j8
    make install
}

build

After reading the above, you may have a few questions:

  • what is position independent code

Baidu Security Verification

  • what is nm ar

The use of ar and nm commands_Liuzi's Column-CSDN
Blog

V. Summary

Because I currently focus on audio editing, all I import are audio libraries. If some students want to introduce x264, opencv, these are all possible, and ffmpeg is very playable. I'm also currently a novice. The reason for writing this article is that there are a lot of teaching how to compile on the Internet, but few talk about why it is configured in this way, and there are probably some things that are copied from everywhere, so although I can compile, there are still many things I don’t understand. So I spent a little time talking about a lot of things that I didn't understand at the beginning to sort out, so I came up with this article. First, I wrote a process that I can understand, and second, I also hope to help others. If there are mistakes, please criticize and correct. If you want my compiled dynamic link library, you can also chat with me privately and send me an email.

Guess you like

Origin blog.csdn.net/qq_37841321/article/details/122294098
Recommended