美文网首页FFmpeg
准备工作--ffmpeg编译

准备工作--ffmpeg编译

作者: llm_5243 | 来源:发表于2020-03-14 09:29 被阅读0次

    为了能更好的学习和运用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

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

    2 新建可执行文件,在根目录下新建 build_android.sh,我的环境文件内容如下:

    #!/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的方式来编译软件, 编译的步骤都是

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

    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.
    

    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型变量名改一下,避免冲突,名字随便起).其他文件也可能报这个错误,按同样的方法修改

    错误4:

    相关文章

      网友评论

        本文标题:准备工作--ffmpeg编译

        本文链接:https://www.haomeiwen.com/subject/gntmshtx.html