為了能更好的學(xué)習(xí)和運(yùn)用ffmpeg, 建議下載ffmpeg源碼自己編譯.這里的編譯方法基于ubuntu16.04環(huán)境.直接按照編譯FFmpeg來(lái)做可能會(huì)碰到一些錯(cuò)誤, 我將自己編譯碰到的錯(cuò)誤記錄在最后面. 我自己編譯的工程已經(jīng)傳到github上
https://github.com/yizhongliu/ffmpegForAndroid
下載ndk,配置ndk環(huán)境
https://developer.android.google.cn/ndk/downloads/
export ANDROID_NDK=/home/llm/Android/android-ndk-r19c-linux-x86_64/android-ndk-r17c/
這里建議使用android-ndk-r17c版本
下載ffmpeg源碼
在FFmpeg官網(wǎng)下載最新4.1.3壓縮文件
將下載的文件拷貝至合適的文件夾
在該目錄下執(zhí)行tar -jxvf ffmpeg-4.1.3.tar.bz2(請(qǐng)注意自己的版本和壓縮格式)
編譯FFmpeg
1 修改 ./configure 文件,該文件影響編譯后so文件的命名,默認(rèn)的命名在Android上會(huì)出現(xiàn)問(wèn)題, 修改后生成以lib為前綴,.so為后置的name
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)'
替換成
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
2 新建可執(zhí)行文件,在根目錄下新建 build_android.sh,我的環(huán)境文件內(nèi)容如下:
#!/bin/sh
MY_LIBS_NAME=ffmpeg-4.0
MY_DIR=ffmpeg-4.0
# cd ./${MY_DIR}
#編譯的過(guò)程中產(chǎn)生的中間件的存放目錄,為了區(qū)分編譯目錄,源碼目錄,install目錄
MY_BUILD_DIR=binary
NDK_PATH=/home/llm/Android/android-ndk-r17c
BUILD_PLATFORM=linux-x86_64
TOOLCHAIN_VERSION=4.9
ANDROID_VERSION=21
ANDROID_ARMV5_CFLAGS="-march=armv5te"
ANDROID_ARMV7_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon" #-mfloat-abi=hard -mfpu=vfpv3-d16 #-mfloat-abi=hard -mfpu=vfp
ANDROID_ARMV8_CFLAGS="-march=armv8-a"
ANDROID_X86_CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32"
ANDROID_X86_64_CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel"
# params($1:arch,$2:arch_abi,$3:host,$4:cross_prefix,$5:cflags)
build_bin() {
echo "-------------------star build $2-------------------------"
ARCH=$1 # arm arm64 x86 x86_64
ANDROID_ARCH_ABI=$2 # armeabi armeabi-v7a x86 mips
PREFIX=$(pwd)/dist/${MY_LIBS_NAME}/${ANDROID_ARCH_ABI}/
HOST=$3
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-${ARCH}
CFALGS=$5
TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
CROSS_PREFIX=${TOOLCHAIN}/bin/$4-
# build 中間件
BUILD_DIR=./${MY_BUILD_DIR}/${ANDROID_ARCH_ABI}
echo "pwd==$(pwd)"
echo "ARCH==${ARCH}"
echo "PREFIX==${PREFIX}"
echo "HOST==${HOST}"
echo "SYSROOT=${SYSROOT}"
echo "CFALGS=$5"
echo "CFALGS=${CFALGS}"
echo "TOOLCHAIN==${TOOLCHAIN}"
echo "CROSS_PREFIX=${CROSS_PREFIX}"
#echo "-------------------------按任意鍵繼續(xù)---------------------"
#read -n 1
#echo "-------------------------繼續(xù)執(zhí)行-------------------------"
mkdir -p ${BUILD_DIR} #創(chuàng)建當(dāng)前arch_abi的編譯目錄,比如:binary/armeabi-v7a
#cd ${BUILD_DIR} #此處 進(jìn)了當(dāng)前arch_abi的2級(jí)編譯目錄
./configure \
--prefix=${PREFIX} \
--target-os=linux \
--arch=${ARCH} \
--sysroot=$SYSROOT \
--enable-cross-compile \
--cross-prefix=${CROSS_PREFIX} \
--extra-cflags="-I$NDK_PATH/sysroot/usr/include/$4 -isysroot $NDK_PATH/sysroot $CFALGS -Os -fPIC -DANDROID -Wfatal-errors -Wno-deprecated" \
--extra-cxxflags="-D__thumb__ -fexceptions -frtti" \
--extra-ldflags="-L${SYSROOT}/usr/lib" \
--enable-shared \
--enable-asm \
--enable-neon \
--disable-encoders \
--enable-encoder=aac \
--enable-encoder=mjpeg \
--enable-encoder=png \
--enable-encoder=mpeg4 \
--disable-decoders \
--enable-decoder=aac \
--enable-decoder=aac_latm \
--enable-decoder=h264 \
--enable-decoder=mpeg4 \
--enable-decoder=mjpeg \
--enable-decoder=png \
--disable-demuxers \
--enable-demuxer=image2 \
--enable-demuxer=h264 \
--enable-demuxer=aac \
--enable-demuxer=mpegvideo \
--enable-demuxer=avi \
--enable-demuxer=mov \
--disable-parsers \
--enable-parser=aac \
--enable-parser=ac3 \
--enable-parser=h264 \
--enable-parser=mpeg4video \
--enable-parser=mjpeg \
--enable-gpl \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-symver \
--disable-debug \
--enable-small
make clean
make
make install
#從當(dāng)前arch_abi編譯目錄跳出,對(duì)應(yīng)上面的cd ${BUILD_DIR},以便function多次執(zhí)行
cd ../../
echo "-------------------$2 build end-------------------------"
}
# build armeabi
#build_bin arm armeabi arm-linux-androideabi arm-linux-androideabi "$ANDROID_ARMV5_CFLAGS"
#build armeabi-v7a
#build_bin arm armeabi-v7a arm-linux-androideabi arm-linux-androideabi "$ANDROID_ARMV7_CFLAGS"
#build arm64-v8a
build_bin arm64 arm64-v8a aarch64-linux-android aarch64-linux-android "$ANDROID_ARMV8_CFLAGS"
#build x86
#build_bin x86 x86 x86 i686-linux-android "$ANDROID_X86_CFLAGS"
#build x86_64
#build_bin x86_64 x86_64 x86_64 x86_64-linux-android "$ANDROID_X86_64_CFLAGS"
3 chmod 777 build_android.sh
4 ./build_android.sh
熟悉開(kāi)源C/C++代碼的人應(yīng)該會(huì)了解,一般都采用automake的方式來(lái)編譯軟件, 編譯的步驟都是
./configure //配置環(huán)境
./make //編譯
./make install //安裝
上面的sh最后編譯了arm64-v8a的so, 需要編譯其他arch, 將對(duì)應(yīng)的#build 打開(kāi)
編譯ffmpeg錯(cuò)誤記錄
錯(cuò)誤1:
找不到文件/home/llm/Android/android-ndk-r19c-linux-x86_64/android-ndk-r19c/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin/x86_64-linux-android-gcc
原因:
Android NDK放棄GCC,全面轉(zhuǎn)向Clang.詳細(xì)解釋參考https://chuansongme.com/n/2251372
解決:
改用android-ndk-r17c
錯(cuò)誤2:
/home/llm/Android/android-ndk-r17c-linux-x86_64/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/include/stdint.h:9:26: fatal error: stdint.h: No such file or directory #include_next <stdint.h>
原因:
NDK r17c版本將頭文件和庫(kù)文件進(jìn)行了分離,我們指定的sysroot文件夾下只有庫(kù)文件,而頭文件放在了NDK目錄下的sysroot內(nèi).
解決:
需在build_android.sh文件 –extra-cflags中添加 “-isysroot $NDK/sysroot”
錯(cuò)誤3:
libavcodec/aaccoder.c: In function 'search_for_ms':
libavcodec/aaccoder.c:803:25: error: expected identifier or '(' before numeric constant
int B0 = 0, B1 = 0;
^
compilation terminated due to -Wfatal-errors.
和
ibavcodec/hevc_mvs.c: In function 'derive_spatial_merge_candidates':
libavcodec/hevc_mvs.c:208:15: error: 'y0000000' undeclared (first use in this function)
((y ## v) >> s->ps.sps->log2_min_pu_size))
^
原因:
由于定義沖突導(dǎo)致的一個(gè)error,和ndk版本有關(guān)
解決:
修改libavcodec/aaccoder.c 文件 B0改成b0(ps:就是把int型變量名改一下,避免沖突,名字隨便起).其他文件也可能報(bào)這個(gè)錯(cuò)誤,按同樣的方法修改
錯(cuò)誤4: