解决Android NDK编译FFmpeg 4.2.2的x86 cpu版时的问题

老规矩,编译环境:Win10 1903,WSL ubuntu,ndk r20b,FFmpeg 4.2.2,首先分享下编译脚本:

#!/bin/bash
make clean

export NDK=/home/kres/android-ndk-r20b
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/
API=21

function build_android
{
	echo "Compiling FFmpeg for $CPU"
	./configure \
		--prefix=$PREFIX \
		--enable-neon \
		--enable-hwaccels \
		--enable-gpl \
		--enable-postproc \
		--enable-shared \
		--enable-jni \
		--enable-mediacodec \
		--disable-decoders \
		    --enable-decoder=h264_mediacodec \
		    --enable-decoder=vp9 \
		    --enable-decoder=h264 \
		    --enable-decoder=mpeg4 \
		    --enable-decoder=aac \
		    --enable-decoder=aac_latm \
		    --enable-decoder=mjpeg \
		    --enable-decoder=png \
		    --enable-decoder=mpeg4_mediacodec \
		--disable-encoders \
		    --enable-encoder=vp9_vaapi --enable-encoder=h264_nvenc --enable-encoder=h264_v4l2m2m --enable-encoder=hevc_nvenc \
		--disable-demuxers \
		    --enable-demuxer=rtsp --enable-demuxer=rtp --enable-demuxer=flv --enable-demuxer=h264 \
		--disable-muxers \
		    --enable-muxer=rtsp --enable-muxer=rtp --enable-muxer=flv --enable-muxer=h264 \
		--disable-parsers \
		    --enable-parser=mpeg4video --enable-parser=aac --enable-parser=h264 --enable-parser=vp9 \
		--disable-protocols \
		    --enable-protocol=rtmp --enable-protocol=rtp --enable-protocol=tcp --enable-protocol=udp \
		--disable-bsfs \
		--disable-indevs --enable-indev=v4l2 \
		--disable-outdevs \
		--disable-filters \
		--disable-postproc \
		--disable-static \
		--disable-doc \
		--disable-ffmpeg \
		--disable-ffplay \
		--disable-ffprobe \
		--enable-avdevice \
		--disable-doc \
		--disable-symver \
		--cross-prefix=$CROSS_PREFIX \
		--target-os=android \
		--arch=$ARCH \
		--cpu=$CPU \
		--cc=$CC \
		--cxx=$CXX \
		--enable-cross-compile \
		--sysroot=$SYSROOT \
		--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
		--extra-ldflags="$ADDI_LDFLAGS" \
		$ADDITIONAL_CONFIGURE_FLAG

		make clean
		make -j6
		make install
		echo "The Compilation of FFmpeg for $CPU is completed"

}
	#armv8-a
	ARCH=arm64
	CPU=armv8-a
	CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
	CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
	SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
	CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
	PREFIX=$(pwd)/android/$CPU
	OPTIMIZE_CFLAGS="-march=$CPU"
	build_android

	#armv7-a
	ARCH=arm
	CPU=armv7-a
	CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
	CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
	SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
	CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
	PREFIX=$(pwd)/android/$CPU
	OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
	build_android

	#x86
	ARCH=x86
	CPU=x86
	CC=$TOOLCHAIN/bin/i686-linux-android$API-clang
	CXX=$TOOLCHAIN/bin/i686-linux-android$API-clang++
	SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
	CROSS_PREFIX=$TOOLCHAIN/bin/i686-linux-android-
	PREFIX=$(pwd)/android/$CPU
	OPTIMIZE_CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32"
	build_android

	#x86_64
	ARCH=x86_64
	CPU=x86-64
	CC=$TOOLCHAIN/bin/x86_64-linux-android$API-clang
	CXX=$TOOLCHAIN/bin/x86_64-linux-android$API-clang++
	SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
	CROSS_PREFIX=$TOOLCHAIN/bin/x86_64-linux-android-
	PREFIX=$(pwd)/android/$CPU
	OPTIMIZE_CFLAGS="-march=$CPU -msse4.2 -mpopcnt -m64 -mtune=intel"
	build_android

其中,在编译到x86 32位版时,会遇到“error: inline assembly requires more registers than available”的问题:

libavcodec/x86/cabac.h:193:9: error: inline assembly requires more registers than available
        BRANCHLESS_GET_CABAC("%0", "%q0", "(%4)", "%1", "%w1",
        ^
libavcodec/x86/cabac.h:143:9: note: expanded from macro 'BRANCHLESS_GET_CABAC'
        "movzbl "statep"    , "ret"                                     \n\t"\
        ^
libavcodec/x86/cabac.h:193:9: error: inline assembly requires more registers than available
libavcodec/x86/cabac.h:143:9: note: expanded from macro 'BRANCHLESS_GET_CABAC'
        "movzbl "statep"    , "ret"                                     \n\t"\
        ^
libavcodec/x86/cabac.h:193:9: error: inline assembly requires more registers than available
libavcodec/x86/cabac.h:143:9: note: expanded from macro 'BRANCHLESS_GET_CABAC'
        "movzbl "statep"    , "ret"                                     \n\t"\
        ^
libavcodec/x86/cabac.h:193:9: error: inline assembly requires more registers than available
libavcodec/x86/cabac.h:143:9: note: expanded from macro 'BRANCHLESS_GET_CABAC'
        "movzbl "statep"    , "ret"                                     \n\t"\
        ^
libavcodec/x86/cabac.h:193:9: error: inline assembly requires more registers than available
libavcodec/x86/cabac.h:143:9: note: expanded from macro 'BRANCHLESS_GET_CABAC'
        "movzbl "statep"    , "ret"                                     \n\t"\
        ^
libavcodec/x86/cabac.h:193:9: error: inline assembly requires more registers than available
libavcodec/x86/cabac.h:143:9: note: expanded from macro 'BRANCHLESS_GET_CABAC'
        "movzbl "statep"    , "ret"                                     \n\t"\
        ^
libavcodec/x86/cabac.h:193:9: error: inline assembly requires more registers than available
libavcodec/x86/cabac.h:143:9CC  libavcodec/h264_refs.o
: note: expanded from macro 'BRANCHLESS_GET_CABAC'
        "movzbl "statep"    , "ret"                                     \n\t"\

各种修改编译脚本设置都无法解决,虽然ndk的32位abi感觉可能也不太会用到吧,但是强迫症发作还是想把它也编出来,最后查到这个: https://trac.ffmpeg.org/ticket/7796 ,研读后发现“ libavutil/x86/asm.h:75”中的

#define HAVE_7REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE && HAVE_EBP_AVAILABLE))

修改为:

#define HAVE_7REGS (ARCH_X86_64)

就可以编译通过了,先记下,后面发现副作用以及其它更新时再做补充。

博主友情提示:

如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。