编译 FFmpeg Android 库(FFmpeg + openh264 合并到一个 libffmpeg.so)

18 篇文章 2 订阅
7 篇文章 3 订阅



编译脚本和文档已放入 github

当前编译环境:
Mac OSX 10.15.4
NDK : android-ndk-r15c

1、编译 openh264
我编的 openh264-2.1.1 ,源码地址
编译脚本如下:

#!/bin/bash

# Author: AlanWang
# Email: alanwang4523@gmail.com
# Date: 2020-06-30
# https://github.com/cisco/openh264/tree/v2.1.1

# 需要指定 ANDROID_NDK 和 ANDROID_NDK
export ANDROID_SDK=/Users/AlanWang/AndroidDev/sdk
export ANDROID_NDK=/Users/AlanWang/AndroidDev/android-ndk-r15c
export PATH=$ANDROID_SDK/tools:$PATH

function build_openh264 {
  ABI=$1
  API_LEVEL=$2

  case $ABI in
    armeabi-v7a )
      ARCH=arm
      ;;
    arm64-v8a )
      ARCH=arm64
      ;;
    x86 )
      ARCH=x86
      ;;
    x86_64 )
      ARCH=x86_64
      ;;
  esac

  TARGET_OS=android
  ANDROID_TARGET=android-$API_LEVEL
  BUILD_PREFIX=$(pwd)/../libs/openh264-out/$ABI

  echo "build libopenh264 ${ABI} ${ANDROID_TARGET}"
  echo "build libopenh264 ${ABI} output : ${BUILD_PREFIX}"

  make \
      OS=${TARGET_OS} \
      NDKROOT=$ANDROID_NDK \
      TARGET=$ANDROID_TARGET \
      ARCH=$ARCH \
      clean
  make \
      OS=${TARGET_OS} \
      NDKROOT=$ANDROID_NDK \
      TARGET=$ANDROID_TARGET \
      NDKLEVEL=$API_LEVEL \
      ARCH=$ARCH \
      PREFIX=$BUILD_PREFIX \
      -j4 install
}


ROOT_PATH=$(pwd)
OPENH264_SOURCE_DIR=$ROOT_PATH/openh264-2.1.1
mkdir $ROOT_PATH/libs

if [[ ! -d $OPENH264_SOURCE_DIR ]]; then
  echo "Did not found $OPENH264_SOURCE_DIR"
  exit 1
fi

cd $OPENH264_SOURCE_DIR

build_openh264 armeabi-v7a 16
build_openh264 arm64-v8a 21

2、编译 ffmpeg
i. 下载 FFmpeg-n4.0.2 源码并解压到当前目录(build_android.sh 所在目录)
ii. FFmpeg-n4.0.2 目录下的 configure 文件,修改如下:

configure 中实际上只做下面修改: #line 6014
# enabled libopenh264       && require_pkg_config libopenh264 openh264 wels/codec_api.h WelsGetCodecVersion
替换成:
enabled libopenh264       && require  libopenh264 wels/codec_api.h WelsGetCodecVersion -lopenh264 -lm -lstdc++

将 ffmpeg 各模块静态库合并成 libffmpeg.so,脚本如下:

function merge_static_to_share
{
  ${CROSS_PREFIX}ld \
    -rpath-link=$SYSROOT/usr/lib \
    -L$SYSROOT/usr/lib \
    -soname libffmpeg.so -shared -Bsymbolic --whole-archive -o \
    $TARGET_PREFIX/lib/libffmpeg.so \
    $TARGET_PREFIX/lib/libavcodec.a \
    $TARGET_PREFIX/lib/libavfilter.a \
    $TARGET_PREFIX/lib/libswresample.a \
    $TARGET_PREFIX/lib/libavformat.a \
    $TARGET_PREFIX/lib/libavutil.a \
    $TARGET_PREFIX/lib/libswscale.a \
    $TARGET_PREFIX/lib/libpostproc.a \
    ${X264_LIB_PATH}/lib/libopenh264.a \
    -lstdc++ -fPIC -lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
    $CROSS_GCC_LIB/libgcc.a
}

FFmpeg 完整编译脚本如下:

#!/bin/bash

# Author: AlanWang
# Email: alanwang4523@gmail.com
# Date: 2019-06-12


# 需要指定 ANDROID_NDK 和 ANDROID_NDK
export ANDROID_SDK=/Users/AlanWang/AndroidDev/sdk
export ANDROID_NDK=/Users/AlanWang/AndroidDev/android-ndk-r15c

HOST_OS_ARCH=darwin-x86_64

function configure_ffmpeg {

  ABI=$1
  API_LEVEL=$2
  TOOLCHAIN_PATH=

  # 配置参考 : https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html
  case ${ABI} in
  armeabi-v7a)
    TOOLCHAIN_PREFIX=arm-linux-androideabi
    ARCH=armv7-a

    TOOLCHAIN_PATH=$ANDROID_NDK/toolchains/$TOOLCHAIN_PREFIX-4.9/prebuilt/$HOST_OS_ARCH
    CROSS_PREFIX=$TOOLCHAIN_PATH/bin/$TOOLCHAIN_PREFIX-
    CROSS_GCC_LIB=$TOOLCHAIN_PATH/lib/gcc/$TOOLCHAIN_PREFIX/4.9.x

    SYSROOT=$ANDROID_NDK/platforms/android-$API_LEVEL/arch-arm
    SYSROOT_INC=$SYSROOT/usr/include

    ADDI_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mcpu=cortex-a8"
    ADDI_CXXFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mcpu=cortex-a8"
    ADDI_LDFLAGS="-Wl,--fix-cortex-a8 -lm -lz"
    EXTRA_CONFIG="--arch=arm --enable-neon --enable-asm --enable-inline-asm"
    ;;
  arm64-v8a)
    TOOLCHAIN_PREFIX=aarch64-linux-android
    ARCH=aarch64

    TOOLCHAIN_PATH=$ANDROID_NDK/toolchains/$TOOLCHAIN_PREFIX-4.9/prebuilt/$HOST_OS_ARCH
    CROSS_PREFIX=$TOOLCHAIN_PATH/bin/$TOOLCHAIN_PREFIX-
    CROSS_GCC_LIB=$TOOLCHAIN_PATH/lib/gcc/$TOOLCHAIN_PREFIX/4.9.x

    SYSROOT=$ANDROID_NDK/platforms/android-$API_LEVEL/arch-arm64
    SYSROOT_INC=$SYSROOT/usr/include

    ADDI_CFLAGS="-march=armv8-a"
    ADDI_CXXFLAGS="-march=armv8-a"
    ADDI_LDFLAGS="-lm -lz"
    EXTRA_CONFIG="--enable-neon --enable-asm --enable-inline-asm"
    ;;
  x86)
    TOOLCHAIN_PREFIX=i686-linux-android
    ARCH=x86

    TOOLCHAIN_PATH=$ANDROID_NDK/toolchains/x86-4.9/prebuilt/$HOST_OS_ARCH
    CROSS_PREFIX=$TOOLCHAIN_PATH/bin/$TOOLCHAIN_PREFIX-
    CROSS_GCC_LIB=$TOOLCHAIN_PATH/lib/gcc/$TOOLCHAIN_PREFIX/4.9.x

    SYSROOT=$ANDROID_NDK/platforms/android-$API_LEVEL/arch-x86
    SYSROOT_INC=$SYSROOT/usr/include

    ADDI_CFLAGS="-march=atom -msse3 -mfpmath=sse"
    ADDI_CXXFLAGS="-march=atom -msse3 -mfpmath=sse"
    ADDI_LDFLAGS="-lm -lz"
    EXTRA_CONFIG="--disable-asm --disable-amd3dnow --disable-avx"
    ;;
  x86_64)
    TOOLCHAIN_PREFIX=x86_64-linux-android
    ARCH=x86_64

    TOOLCHAIN_PATH=$ANDROID_NDK/toolchains/x86_64-4.9/prebuilt/$HOST_OS_ARCH
    CROSS_PREFIX=$TOOLCHAIN_PATH/bin/$TOOLCHAIN_PREFIX-
    CROSS_GCC_LIB=$TOOLCHAIN_PATH/lib/gcc/$TOOLCHAIN_PREFIX/4.9.x

    SYSROOT=$ANDROID_NDK/platforms/android-$API_LEVEL/arch-x86_64
    SYSROOT_INC=$SYSROOT/usr/include

    ADDI_CFLAGS="-march=atom -msse3 -mfpmath=sse"
    ADDI_CXXFLAGS="-march=atom -msse3 -mfpmath=sse"
    ADDI_LDFLAGS="-lm -lz"
    EXTRA_CONFIG="--disable-asm --disable-amd3dnow --disable-avx"
    ;;
  esac


  # TARGET_PREFIX=$(pwd)/android_build/${ABI}
  TARGET_PREFIX=$(pwd)/../libs/ffmpeg-out/${ABI}
  X264_LIB_PATH=$(pwd)/../libs/openh264-out/${ABI}

  if [[ -f $X264_LIB_PATH/lib/libopenh264.so ]]; then
    rm $X264_LIB_PATH/lib/libopenh264.so
    echo "rm libopenh264.so "
  fi

  echo "Output prefix ${TARGET_PREFIX}"
  echo "Configuring FFmpeg build for ${ABI}"
  echo "SYSROOT : $SYSROOT"
  echo "CROSS_PREFIX : $CROSS_PREFIX"
  echo "X264_LIB_PATH : ${X264_LIB_PATH}"

  ./configure \
    --prefix=${TARGET_PREFIX} \
    --enable-gpl \
    --disable-shared \
    --enable-static \
    --disable-small \
    --disable-stripping \
    --disable-debug \
    --enable-ffmpeg \
    --enable-pthreads \
    --disable-w32threads \
    --disable-os2threads \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-avdevice \
    --disable-devices \
    --disable-symver \
    --disable-doc \
    --disable-decoders \
    --disable-encoders \
    --disable-parsers \
    --disable-protocols \
    --enable-protocol=file \
    --enable-parser=aac \
    --enable-parser=mpegaudio \
    --enable-parser=h264\
    --disable-devices \
    --enable-decoder=aac \
    --enable-decoder=pcm_s16le \
    --enable-decoder=pcm_f32le \
    --enable-decoder=h264\
    --enable-decoder=png \
    --enable-decoder=mjpeg \
    --enable-encoder=aac \
    --enable-encoder=pcm_s16le \
    --enable-encoder=pcm_f32le \
    --enable-libopenh264 \
    --enable-encoder=libopenh264 \
    --enable-decoder=libopenh264 \
    --disable-bsfs \
    --enable-bsf=aac_adtstoasc \
    --enable-bsf=hevc_mp4toannexb \
    --enable-bsf=mpeg4_unpack_bframes \
    --enable-bsf=h264_mp4toannexb \
    --disable-muxers \
    --enable-muxer=mp4 \
    --enable-muxer=wav \
    --enable-muxer=adts \
    --disable-demuxers \
    --enable-demuxer=h264 \
    --enable-demuxer=aac \
    --enable-demuxer=wav \
    --enable-demuxer=flv \
    --enable-demuxer=avi \
    --enable-demuxer=mov \
    --enable-demuxer=matroska \
    --enable-demuxer=concat \
    --enable-demuxer=image2 \
    --disable-filters \
    --enable-filter=aresample \
    --enable-filter=transpose \
    --enable-filter=crop \
    --enable-filter=scale \
    --enable-filter=hflip \
    --enable-filter=vflip \
    --enable-filter=overlay \
    --enable-zlib \
    --enable-runtime-cpudetect \
    --cross-prefix=$CROSS_PREFIX \
    --target-os=android \
    --arch=$ARCH \
    --enable-cross-compile \
    --sysroot=$SYSROOT \
    --extra-cflags="-O3 -ffast-math -fPIC $ADDI_CFLAGS -I$X264_LIB_PATH/include -I$SYSROOT_INC" \
    --extra-cxxflags="-O3 -ffast-math -fPIC $ADDI_CXXFLAGS -I$X264_LIB_PATH/include -I$SYSROOT_INC" \
    --extra-ldflags="$ADDI_LDFLAGS -L$X264_LIB_PATH/lib" \
    --extra-ldexeflags="-pie -fPIC $ADDI_LDFLAGS -L$X264_LIB_PATH/lib" \
    ${EXTRA_CONFIG}

  return $?
}

function merge_static_to_share
{
  ${CROSS_PREFIX}ld \
    -rpath-link=$SYSROOT/usr/lib \
    -L$SYSROOT/usr/lib \
    -soname libffmpeg.so -shared -Bsymbolic --whole-archive -o \
    $TARGET_PREFIX/lib/libffmpeg.so \
    $TARGET_PREFIX/lib/libavcodec.a \
    $TARGET_PREFIX/lib/libavfilter.a \
    $TARGET_PREFIX/lib/libswresample.a \
    $TARGET_PREFIX/lib/libavformat.a \
    $TARGET_PREFIX/lib/libavutil.a \
    $TARGET_PREFIX/lib/libswscale.a \
    $TARGET_PREFIX/lib/libpostproc.a \
    ${X264_LIB_PATH}/lib/libopenh264.a \
    -lstdc++ -fPIC -lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
    $CROSS_GCC_LIB/libgcc.a
}


function build_ffmpeg_static {
  configure_ffmpeg $1 $2
  if [ $? -eq 0 ]
  then
      make clean
      make -j12
      make install

      merge_static_to_share
  else
      echo "FFmpeg build failed, please check the configurations and error log."
  fi
}


function build_ffmpeg {
  build_ffmpeg_static  $1 $2
  ${CROSS_PREFIX}strip $TARGET_PREFIX/lib/libffmpeg.so
}


ROOT_PATH=$(pwd)
FFMPGE_SOURCE_DIR=$ROOT_PATH/FFmpeg-n4.0.2

if [[ ! -d $FFMPGE_SOURCE_DIR ]]; then
  echo "Did not found $FFMPGE_SOURCE_DIR"
  exit 1
fi

cd $FFMPGE_SOURCE_DIR

build_ffmpeg armeabi-v7a 16
build_ffmpeg arm64-v8a 21

github 地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值