前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >准备工作--ffmpeg编译

准备工作--ffmpeg编译

作者头像
小蚂蚁与大象
发布2020-04-17 17:58:53
1.4K0
发布2020-04-17 17:58:53
举报
文章被收录于专栏:构建FFmpeg Android播放器

为了能更好的学习和运用ffmpeg, 建议下载ffmpeg源码自己编译.这里的编译方法基于ubuntu16.04环境.直接按照编译FFmpeg来做可能会碰到一些错误, 我将自己编译碰到的错误记录在最后面. 我自己编译的工程已经传到github上 https://github.com/yizhongliu/ffmpegForAndroid

下载ndk,配置ndk环境

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官网下载最新4.1.3压缩文件 将下载的文件拷贝至合适的文件夹 在该目录下执行tar -jxvf ffmpeg-4.1.3.tar.bz2(请注意自己的版本和压缩格式)

编译FFmpeg

1 修改 ./configure 文件,该文件影响编译后so文件的命名,默认的命名在Android上会出现问题, 修改后生成以lib为前缀,.so为后置的name

代码语言:javascript
复制
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)'

替换成

代码语言:javascript
复制
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 新建可执行文件,在根目录下新建 build_android.sh,我的环境文件内容如下:

代码语言:javascript
复制
#!/bin/sh

MY_LIBS_NAME=ffmpeg-4.0
MY_DIR=ffmpeg-4.0

# cd ./${MY_DIR}

#编译的过程中产生的中间件的存放目录,为了区分编译目录,源码目录,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 "-------------------------按任意键继续---------------------"
    #read -n 1
    #echo "-------------------------继续执行-------------------------"

    mkdir -p ${BUILD_DIR}   #创建当前arch_abi的编译目录,比如:binary/armeabi-v7a
    #cd ${BUILD_DIR}         #此处 进了当前arch_abi的2级编译目录


    ./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

    #从当前arch_abi编译目录跳出,对应上面的cd ${BUILD_DIR},以便function多次执行
        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

熟悉开源C/C++代码的人应该会了解,一般都采用automake的方式来编译软件, 编译的步骤都是

代码语言:javascript
复制
./configure  //配置环境
./make   //编译
./make install   //安装

上面的sh最后编译了arm64-v8a的so, 需要编译其他arch, 将对应的#build 打开

编译ffmpeg错误记录

错误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,全面转向Clang.详细解释参考https://chuansongme.com/n/2251372 解决: 改用android-ndk-r17c

错误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版本将头文件和库文件进行了分离,我们指定的sysroot文件夹下只有库文件,而头文件放在了NDK目录下的sysroot内. 解决: 需在build_android.sh文件 –extra-cflags中添加 “-isysroot $NDK/sysroot”

错误3:

代码语言:javascript
复制
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.

代码语言:javascript
复制
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))
               ^

原因: 由于定义冲突导致的一个error,和ndk版本有关 解决: 修改libavcodec/aaccoder.c 文件 B0改成b0(ps:就是把int型变量名改一下,避免冲突,名字随便起).其他文件也可能报这个错误,按同样的方法修改

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 下载ndk,配置ndk环境
  • 下载ffmpeg源码
  • 编译FFmpeg
  • 编译ffmpeg错误记录
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档