Android之NDK编译FFmpeg教程

// CLANG

// Android NDK 下载
// 本科教程使用 android-ndk-r20b-linux-x86_64.zip 
// 在 ubuntu 18.04 x64 下进行 ...
https://developer.android.google.cn/ndk/downloads/

// FFmpeg 下载
// 本教程使用 FFmpeg 4.2.2 "Ada" 下进行 ...
http://ffmpeg.org/download.html#releases

// 注意: FFmpeg h264_mediacodec 最高版本 3.4.7
// 环境准备 ...
apt-get install yasm
apt-get install pkg-config
// 修改 FFmpeg configure
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)'
--disable-asm // 如出现 asm 异常则增加 ...
// FFmpeg Build 脚本

#!/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-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
// 在编译脚本中添加了宏:BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD

CC  libavdevice/v4l2.o
libavdevice/v4l2.c:135:9: error: assigning to 'int (*)(int, unsigned long, ...)' from incompatible type '<overloaded function type>'
    SET_WRAPPERS();
    ^~~~~~~~~~~~~~
libavdevice/v4l2.c:121:17: note: expanded from macro 'SET_WRAPPERS'
    s->ioctl_f  = prefix ## ioctl;      \
        ^           ~~~~~
/home/cc/android-ndk-r19c/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/include/bits/ioctl.h:56:5: note: candidate function has type mismatch at 2nd parameter
      (expected 'unsigned long' but has 'unsigned int')
int ioctl(int __fd, unsigned __request, ...) __overloadable __enable_if(1, "") __RENAME(ioctl);
    ^
/home/cc/android-ndk-r19c/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/include/bits/ioctl.h:36:5: note: candidate function has type mismatch at 2nd parameter
      (expected 'unsigned long' but has 'int')
int ioctl(int __fd, int __request, ...);
    ^
1 error generated.
make: *** [ffbuild/common.mak:60: libavdevice/v4l2.o] Error 1
#!/bin/bash

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

#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 -DBIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD"

    echo "Compiling FFmpeg for $CPU"
    ./configure \
    --prefix=$PREFIX \
    --disable-asm \
    --enable-neon \
    --enable-hwaccels \
    --enable-shared \
    --enable-jni \
    --enable-mediacodec \
    --enable-decoders \
    --disable-encoders \
    --enable-demuxers \
    --enable-muxers \
    --enable-parsers \
    --enable-protocols \
    --disable-bsfs \
    --disable-indevs \
    --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