ubuntu14.04 NDK编译ffmpeg

环境:ubuntu14.04
NDK:android-ndk-r17
ffmpeg:4.2.2

关于apt-get install部分不再赘述,文章较多,下面这条建议先执行

sudo apt-get install build-essential -y

1.配置NDK PATH

NDK_PATH=/home/zjs/android-ndk-r17
export PATH=${PATH}:${NDK_PATH}

2.目录结构

ffmpeg->ffmpeg-4.2.2
      ->ffmpeg_android.sh

3.脚本ffmpeg_android.sh
脚本内容有修改,没有动态适配,制作64bit时注意修改,中文注释为修改点

#!/bin/bash

# Don't forget to install yasm.

#set -e

# Set your own NDK here
NDK=/home/zjs/android-ndk-r17

ARM_PLATFORM=$NDK/platforms/android-21/arch-arm/
ARM_PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64

ARM64_PLATFORM=$NDK/platforms/android-21/arch-arm64/
ARM64_PREBUILT=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64

X86_PLATFORM=$NDK/platforms/android-21/arch-x86/
X86_PREBUILT=$NDK/toolchains/x86-4.9/prebuilt/linux-x86_64

X86_64_PLATFORM=$NDK/platforms/android-21/arch-x86_64/
X86_64_PREBUILT=$NDK/toolchains/x86_64-4.9/prebuilt/linux-x86_64

#NDK r17 sysroot inlcude及lib相关移到了根目录,cflag中添加链接
ISYSROOT=$NDK/sysroot
ASM=$ISYSROOT/usr/include/arm-linux-androideabi

#生成的so及.h文件路径
BUILD_DIR=`pwd`/ffmpeg-android

#ffmpeg版本,后面pushd用,所以要建立第2步正确的目录结构
FFMPEG_VERSION="4.2.2"

function build_one
{
if [ $ARCH == "arm" ]
then
    PLATFORM=$ARM_PLATFORM
    PREBUILT=$ARM_PREBUILT
    HOST=arm-linux-androideabi
elif [ $ARCH == "arm64" ]
then
    PLATFORM=$ARM64_PLATFORM
    PREBUILT=$ARM64_PREBUILT
    HOST=aarch64-linux-android
elif [ $ARCH == "x86_64" ]
then
    PLATFORM=$X86_64_PLATFORM
    PREBUILT=$X86_64_PREBUILT
    HOST=x86_64-linux-android
else
    PLATFORM=$X86_PLATFORM
    PREBUILT=$X86_PREBUILT
    HOST=i686-linux-android
fi

#extra-cflags配置-I$ASM -isysroot $ISYSROOT,否则会报出.h找不到
pushd ffmpeg-$FFMPEG_VERSION
./configure --target-os=linux \
    --incdir=$BUILD_DIR/include \
    --libdir=$BUILD_DIR/lib/$CPU \
    --enable-cross-compile \
    --arch=$ARCH \
    --cc=$PREBUILT/bin/$HOST-gcc \
    --cross-prefix=$PREBUILT/bin/$HOST- \
    --nm=$PREBUILT/bin/$HOST-nm \
    --sysroot=$PLATFORM \
    --extra-cflags="-I$ASM -isysroot $ISYSROOT -I$BUILD_DIR/include -fPIC -DANDROID -Wfatal-errors -Wno-deprecated $OPTIMIZE_CFLAGS" \
    --enable-gpl \
    --enable-small \
    --extra-ldflags="-L$BUILD_DIR/lib/$CPU" \
    --enable-shared \
    --disable-doc \
    --disable-programs \
    --disable-stripping \
    --disable-symver \
    --disable-static \
    --pkg-config=/usr/bin/pkg-config \
    $ADDITIONAL_CONFIGURE_FLAG

make clean
make -j8
make install
popd
}

#arm v7vfpv3
#CPU=armv7-a
#ARCH=arm
#OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU -D__thumb__ -mthumb"
#PREFIX=$BUILD_DIR/$CPU
#ADDITIONAL_CONFIGURE_FLAG=
#build_one

#arm v7vfp
#CPU=armv7-a
#ARCH=arm
#OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
#PREFIX=`pwd`/ffmpeg-android/$CPU-vfp
#ADDITIONAL_CONFIGURE_FLAG=
#build_one

#arm v7n
CPU=armv7-a
ARCH=arm
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=neon -marm -march=$CPU -mtune=cortex-a8"
PREFIX=$BUILD_DIR/$CPU
ADDITIONAL_CONFIGURE_FLAG=
build_one
#arm64-v8a
#CPU=arm64-v8a
#ARCH=arm64
#OPTIMIZE_CFLAGS=
#PREFIX=$BUILD_DIR/$CPU
#ADDITIONAL_CONFIGURE_FLAG=
#build_one

#x86_64
#CPU=x86_64
#ARCH=x86_64
#OPTIMIZE_CFLAGS="-fomit-frame-pointer"
#PREFIX=$BUILD_DIR/$CPU
#ADDITIONAL_CONFIGURE_FLAG=
#build_one

#x86
#CPU=i686
#ARCH=i686
#OPTIMIZE_CFLAGS="-fomit-frame-pointer"
#PREFIX=$BUILD_DIR/$CPU
#ADDITIONAL_CONFIGURE_FLAG=
#build_one

sysroot位置变动导致的编译错误如下:

/home/zjs/android-ndk-r17/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>
                          ^

这个stdint.h就在sysroot的include中,必须添加–extra-cflags="-I$ASM -isysroot $ISYSROOT……

4.修改configure
默认生成的so名称以版本做后缀,不适用于android app开发,修改如下:

#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)'

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

5.执行脚本
因为有些路径需要建立在/usr下,因此sudo执行。

chmod 777 ffmpeg_android.sh
sudo ffmpeg_android.sh

6.错误修正:
编译期间会报出以下三个错误:

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;
                         ^
libavcodec/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))
               ^         
libavcodec/opus_pvq.c: In function 'quant_band_template':
libavcodec/opus_pvq.c:498:9: error: expected identifier or '(' before numeric constant
     int B0 = blocks;
         ^

问题原因在B0在ndk中被用作宏定义了:
androideabi/include/asm/termbits.h 中

#define B0 0000000 

因此把文件中的B0全替换为b0即可。

7.生成so

├── ffmpeg-android
│   ├── include
│   │   ├── libavcodec
……
│   └── lib
│       └── armv7-a
│           ├── libavcodec-58.so
│           ├── libavcodec.so -> libavcodec-58.so
│           ├── libavdevice-58.so
│           ├── libavdevice.so -> libavdevice-58.so
│           ├── libavfilter-7.so
│           ├── libavfilter.so -> libavfilter-7.so
│           ├── libavformat-58.so
│           ├── libavformat.so -> libavformat-58.so
│           ├── libavutil-56.so
│           ├── libavutil.so -> libavutil-56.so
│           ├── libpostproc-55.so
│           ├── libpostproc.so -> libpostproc-55.so
│           ├── libswresample-3.so
│           ├── libswresample.so -> libswresample-3.so
│           ├── libswscale-5.so
│           ├── libswscale.so -> libswscale-5.so
│           └── pkgconfig
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值