安卓新的NDK编译工具替换成了clang,所以之前的编译脚本需要做相应调整,本文总结了编译过程中遇到的诸多问题,如果编译过程中遇到问题,或编出的库不符合需求,可参考后面的问题总结,希望能帮到你

环境

编译环境:win10 + msys2

DNK版本:android-ndk-21.2.6472646/ android-ndk-21.0.6113669/android-ndk-r20

ffmpeg版本: ffmpeg3.3.9/ffmpeg4.3.1

使用本文的编译脚本,测试了linux和window10,android-ndk-21.2.6472646/ android-ndk-21.0.6113669/android-ndk-r20,编译了 ffmpeg3.3.9/ffmpeg4.3.1,都能成功编译

环境搭建

网上许多安装类unix运行环境都需要翻墙,要么安装速度很慢,本文使用国内源不需要翻墙,如果你安装了其他的类unix运行环境(如cywin, MinGW),理论上应该是可以直接进入后面的编译步骤的,不过我没尝试过

1、msys2安装

在清华大学镜像网站下载并安装 msys2 最新版本 ,此外还有中科大,北京理工大学, 上海交大等镜像源,64位系统建议下载x86_64版本,安装一路点击下一步就行

2、msys2配置

将默认源地址替换为清华大学镜像地址,类似于Ubuntu设置镜像源,这样安装其他工具速度会快很多,配置步骤如下

见清华大学镜像网站msys2帮助文档,我下载的最新版本默认有许多国内镜像源在配置文件中,其他镜像源的没有试过,建议把国内的源放前面,我的配置顺序如下

#清华大学
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/i686/
#中科大
Server = http://mirrors.ustc.edu.cn/msys2/mingw/i686/
#北京理工大学
Server = http://mirror.bit.edu.cn/msys2/mingw/i686/
Server = https://mirror.selfnet.de/msys2/mingw/i686/
#上海交大
Server = https://mirrors.sjtug.sjtu.edu.cn/msys2/mingw/i686/
Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/
Server = https://sourceforge.net/projects/msys2/files/REPOS/MINGW/i686/
Server = https://www2.futureware.at/~nickoe/msys2-mirror/mingw/i686/

配置完打开安装路径下msys2.exe(或按win键在程序列表中打开),执行 pacman -Sy 刷新软件包数据即可。

然后执行安装路径下msys2_shell.cmd打开msys终端,执行"pacman -Syuu"命令,中途可能会提示关闭终端,此时关闭msys,重新         打   开,再次执行"pacman -Syuu"命令,更新软件包

这里顺便附一个pacman包管理工具命令开始编译

3、安装make

在msys2终端执行pacman -S make,安装make工具

pacman -S make

编译ffmpeg

msys2安装目录下打开mingw64.exe, 切换到ffmpeg源码路径,windows D:盘被挂载为/d/,以此类推,可用 df -h命令确认,不过盘符占用比较多时相应可能比较慢

新建一个buid.sh,将以下内容粘贴到文本,根据需求替换前三个变量,如果使用windows文本编辑器,切记保存为unix格式,否则可能会由于结束符不一致问题,报有语法错误,脚本加了一些辅助调试信息,和交互选项,所以比较长,将脚本保存到ffmpeg源码路径下,执行./build 5 ,可编译armeabi-v7a , arm64-v8a, x86, x86_64 所有动态和静态库,如果只编译某个版本的库执行./build可以看到编译选择,选择相应版本编号即可,输出路径下build.log可跟踪编译情况

#!/bin/bash#ffmpeg 版本
FFMPEG_VERSION=4.3.1
#NDK 路径, 根据情况替换
export NDK=/d/Green_Sorft/Android/Sdk/ndk/21.2.6472646
#编译输出路径 根据需求替换替换,默认在脚本上级目录ffmpeg_for_android目录下
OUT_DIR="`dirname $PWD`/ffmpeg_for_android/ffmpeg_${FFMPEG_VERSION}_lib"
#编译工具路径,linux版本需根据情况替换
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/windows-x86_64export TMPDIR=$OUT_DIR/tmp
mkdir -p $TMPDIR
#将ndk下yasm所在路径添加到PATH环境变量
PATH=$PATH:$TOOLCHAIN/bin
#创建/清空编译日志
> $OUT_DIR/build.logfunction build_start() {echo "build FFmpeg for $ABI"./configure \--prefix=$OUT_DIR/$ABI \--disable-gpl \--enable-shared \--enable-static \--disable-doc \--disable-programs \--disable-avdevice \--disable-doc \--disable-symver \--cross-prefix=$CROSS_PREFIX \--target-os=android \--enable-cross-compile \--arch=$ARCH \--cpu=$CPU \--cc=$CC \--cxx=$CXX \--sysroot=$TOOLCHAIN/sysroot \--extra-cflags="-Os -fPIC $OPTIMIZE_CFLAGS" \configRet=$?echo "* config for $ABI ret:$configRet" >> $OUT_DIR/build.logif [ $configRet -eq 0 ]; thenecho "start make $ABI"make cleanmake -j64makeRet=$?echo "* make for $ABI return:$makeRet" >> $OUT_DIR/build.logif [ $makeRet -eq 0 ]; thenmake installmv_libsfielseecho "The config of FFmpeg for $ABI is failded"echo "* config for $ABI failed !!" >> $OUT_DIR/build.logfiecho "The Compilation of FFmpeg for $ABI is completed"echo "*************************" >> $OUT_DIR/build.log
}function mv_libs() {mkdir -p $OUT_DIR/shared-libs/$ABImv $OUT_DIR/$ABI/lib/*.so $OUT_DIR/shared-libs/$ABImkdir -p $OUT_DIR/static-libs/$ABImv $OUT_DIR/$ABI/lib/*.a $OUT_DIR/static-libs/$ABIcp -rf $OUT_DIR/$ABI/include $OUT_DIR/cp -rf $OUT_DIR/$ABI/share/ffmpeg/examples $OUT_DIR/rm -rf $OUT_DIR/$ABI/
}#armv8-a aarch64
function build_arm64() {API=21ABI=arm64-v8aARCH=arm64CPU=armv8-aCC=$TOOLCHAIN/bin/aarch64-linux-android$API-clangCXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-OPTIMIZE_CFLAGS="-march=$CPU"echo "* buidl for $ABI start !!" >> $OUT_DIR/build.logbuild_startecho "* buidl for $ABI end !!" >> $OUT_DIR/build.logecho "*************************" >> $OUT_DIR/build.log
}#armv7-a
function build_arm() {API=16ABI=armeabi-v7aARCH=armCPU=armv7-aCC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clangCXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-OPTIMIZE_CFLAGS="-march=$CPU -mfloat-abi=softfp -mfpu=vfp -marm"echo "* buidl for $ABI start !!" >> $OUT_DIR/build.logbuild_startecho "* buidl for $ABI end !!" >> $OUT_DIR/build.logecho "*************************" >> $OUT_DIR/build.log
}#x86 i686
function build_x86() {API=16ABI=x86ARCH=x86CPU=x86CC=$TOOLCHAIN/bin/i686-linux-android$API-clangCXX=$TOOLCHAIN/bin/i686-linux-android$API-clang++CROSS_PREFIX=$TOOLCHAIN/bin/i686-linux-android-OPTIMIZE_CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 -mno-stackrealign"echo "* buidl for $ABI start !!" >> $OUT_DIR/build.logbuild_startecho "* buidl for $ABI end !!" >> $OUT_DIR/build.logecho "*************************">> $OUT_DIR/build.logecho "">> $OUT_DIR/build.log
}#x86_64
function build_x86_64() {API=21ABI=x86_64ARCH=x86_64CPU=x86-64CC=$TOOLCHAIN/bin/x86_64-linux-android$API-clangCXX=$TOOLCHAIN/bin/x86_64-linux-android$API-clang++CROSS_PREFIX=$TOOLCHAIN/bin/x86_64-linux-android-OPTIMIZE_CFLAGS="-march=$CPU -msse4.2 -mpopcnt -m64 -mtune=intel"echo "* buidl for $ABI start !!" >> $OUT_DIR/build.logbuild_startecho "* buidl for $ABI end !!" >> $OUT_DIR/build.logecho "*************************">> $OUT_DIR/build.log
}function read_opt()
{echo ""echo "please select onece"echo "    1、build for ABI=armeabi-v7a CPU=armv7-a"echo "    2、build for ABI=arm64-v8a CPU=armv8-a"echo "    3、build for ABI=x86 CPU=x86"echo "    4、build for ABI=x86_64 CPU=x86_64"echo "    5、build all"echo ""echo "input:"read option
}option=$1
if [ "$option" = "" ];thenread_opt
fiif [ "$option" = "1" ];thenecho "start build ABI=arm64-v8a CPU=armv8-a"build_arm64
elif [ "$option" = "2" ];thenecho "start build ABI=armeabi-v7a CPU=armv7-a"build_arm
elif [ "$option" = "3" ];thenecho "start build ABI=x86 CPU=x86"build_x86
elif [ "$option" = "4" ];thenecho "start build ABI=x86_64 CPU=x86_64"build_x86_64
elif [ "$option" = "5" ];thenecho "start build all"build_arm64build_armbuild_x86build_x86_64
elseecho "invalid input"
firm -rf $TMPDIR

问题总结

1、编译x86cpu时内联汇编报错

In file included from libswscale/x86/rgb2rgb.c:102:
libswscale/x86/rgb2rgb_template.c:1666:13: error: inline assembly requires more registers than available
            "mov                        %4, %%"FF_REG_a"\n\t"
            ^

提供了一下4个解决方案

1、禁用asm,在ffmpeg configure选项中添加--disable-asm禁用汇编,不过可能会影响运行效率

2、在修改ffmpeg路径下config.h,将HAVE_EBP_AVAILABLE 设置为0 #define HAVE_EBP_AVAILABLE 0

3、这是ndk低版本编译链中才存在的问题,可用24及以上版本编译链,及将脚本中x86_build中的API设置为24及以上(可能会影响兼容性)

4、(推荐)在configure --extra-cflags选项中添加 -mno-stackrealign编译选项

2、使用ffmpeg动态库,编译时提示找不到动态库

在app下build.gradle 文件android内添加如下代码

sourceSets.main{jniLibs.srcDirs=['libs']
}

3、使用模拟器调试时,提示java.lang.UnsatisfiedLinkError: dlopen failed: "xxx.so" has text relocations(https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md#Text-Relocations-Enforced-for-API-level-23)

模拟器基本都是x86cpu,网上说只有6.0以上才有这个问题,网上的方案都是把aap下build.gradle中的targetSdkVersion设置为23以下,但是我用模拟器调试时似乎不能这么操作,修改后编不出APK,我不是搞安卓framework的,应用相关的不是很清楚,所以我直接使用静态库了,或者使用手机

4,提示找不到ysam或版本过低

首先在msys终端输入yasm,看是否有这个命令,如果提示找不到命令,则在脚本中将ndk中android-ndk-r20\toolchains\llvm\prebuilt\windows-x86_64\bin\yasm添加到PATH环境变量中,PATH=$PATH:$TOOLCHAIN/bin ,如果有yasm,则用whereis yasm命令,找到电脑中的yasm,将其重命名(记得改回去)或直接删除,然后将ndk的yasm添加到path环境变量

5、在编译armv7-a时,汇编文件报错

libswscale/arm/rgb2yuv_neon_common.S:251:11: error: unexpected token in argument list
CO_BV .dn d2.s16[2]
          ^
<instantiation>:4:5: error: invalid instruction
    vmul y16x16_l, n16x16_l, CO_RY
    ^
我在编译ffmpeg4.3.1时没有这个问题,但是编译ffmpeg3.3.9时报错,简单粗暴的操作就是在ffmpeg configure选项中添加--disable-asm禁用汇编,但是我们要斯文一点,可以选择只禁用neon,即在armv7-a的ffmpeg configure选项中加入--disable-neon

6、将ffmpeg所有的库编译为一个libffmpeg.so库

目前只编译出静态库,动态库编译编译过程遇到了些问题,后面尝试解决

https://blog.csdn.net/mvp_Dawn/article/details/109136921

编译ffmpeg安卓库(clang篇),含armeabi-v7a , arm64-v8a, x86, x86_64相关推荐

  1. VC使用mingw32编译ffmpeg静态库所需文件(一),ffmpegshim.c

    VC使用mingw32编译ffmpeg静态库所需文件(一),ffmpegshim.c 哈哈,这是我从一些项目里面看到的,这些函数是ffmpeg.a缺少的函数.估计大家会用得上. 当然我移植的的项目都不 ...

  2. MinGW下编译ffmpeg静态库给Visual C++使用

    首先推荐 http://ffmpeg.zeranoe.com/builds/, 这里已经有编译好的动态连接库.可惜上面没静态链接库.我也试过 DLL2Lib, 但是无法连接LIBCMT库,只能使用MS ...

  3. 【Android 音视频开发打怪升级:FFmpeg音视频编解码篇】一、FFmpeg so库编译

    转自:https://juejin.im/post/5e130df55188253a8b42ebac 目录 一.Android音视频硬解码篇: 1,音视频基础知识 2,音视频硬解码流程:封装基础解码框 ...

  4. ffmpeg自学路(一)用ubantu编译支持android的ffmpeg支持库,感谢韩曙亮

    非常感谢韩曙亮的帮助,特以此篇记录编译过程. 韩兄相关文章的对应地址:https://blog.csdn.net/shulianghan/article/details/104351312 / 开始正 ...

  5. AndroidNDK工程FFmpeg(一)-- Android使用FFmpeg--Shell脚本编写与执行编译FFmpeg库

    FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计 算机程序.FFmpeg 是一个多媒体视频处理工具,有非常强大的功能包括视频采集功能. 视频格式转换.视频抓图.给视频加水印 ...

  6. Android NDK开发之旅29 云服务器Ubuntu下搭建NDK环境,并编译FFmpeg

    ###前言 因为在Linux环境下编译FFmpeg生成库和头文件下比较方便,所以接下来主要操作在Linux环境下进行.但是对于Android NDK 开发新手来说,自己电脑配置Ubuntu Linux ...

  7. 【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )

    文章目录 I . FFMPEG 交叉编译后的函数库及头文件 II . FFMPEG 静态库打包动态库 ( 仅做参考 ) III . 创建 Android Studio 工程 IV . FFMPEG 头 ...

  8. Android 编译FFmpeg x264

    1. Android FFmpeg开发基本流程 (1)X264/FFmpeg + NDK编译  (2)ffmpeg.so + 编解码C代码  (3)Android.mk 编译  (4)JNI  (5) ...

  9. 【Android 安装包优化】动态库打包配置 ( “armeabi-v7a“, “arm64-v8a“, “x86“, “x86_64“ APK 打包 CPU 指令集配置 | NDK 完整配置参考 )

    文章目录 一.动态库打包配置 二.NDK 完整配置参考 三.参考资料 一.动态库打包配置 在 build.gradle 构建脚本中 , 配置 ndk 编译的动态库 CPU 架构类型 ; 在 " ...

  10. linux编译ffmpeg成so,「ffmpeg」一 mac 环境下编译ffmpeg,生成so库文件

    1.下载ffmpeg源码,官网,我这里直接采用git 方式下载: 下载ffmpeg.png 终端输入git命令: 静静等待~ 最后下载的版本为3.4.6 . image.png 这里注意一下,刚开始我 ...

最新文章

  1. TensorFlow框架--Keras
  2. C# 使用AggregateException 信息
  3. apache服务器工作原理,Apache服务器的原理简介
  4. 一个U盘走天下,装机大神撩妹的不二之选
  5. app error login.php,如何解决uniapp登录错误提示问题
  6. nefu 984 我是一个粉刷匠
  7. 文件异步加载读取 php,js文件的异步加载的方法总结(附代码)
  8. 炫酷流光个人主页源码分享及在线部署教程
  9. 车规SoC芯片厂商征战功能安全,谁是最佳助力者?
  10. 广告管理系统的UML分析与设计
  11. Word文档打印又出新方法!Spire.Doc全新代码让文档更清晰
  12. 数字黑洞java,java解决数字黑洞问题
  13. iOS app上架app store流程详解
  14. c语言水王争霸链表,水王争霸(water)
  15. c语言ifi=1 2,第1部分_C语言程序设计练习一全解.doc
  16. 阿里云部署Java网站和微信开发调试心得技巧(下)
  17. Python 打字小游戏开发,来体验不一样的打字游戏乐趣(第二篇)
  18. JS中find()和findIndex()
  19. 计算机基础知识试题答案6,计算机基础知识试题及答案
  20. CSDN-MarkDown编辑器的姿势大全

热门文章

  1. 安装QQ、TIM提示:安装包可能被非法改动导致安装失败,请从官网下载最新安装包重新安装
  2. 王思聪吃热狗 - 飞机大战小游戏
  3. JAVA获取word书签内容_java操作word可操作书签
  4. pageoffice 选中部分文字 添加书签和空白处添加书签 删除空白以及内容书签
  5. 乌龟GIT的合并代码
  6. 如何批量转换图片格式为jpg?
  7. 路径跟踪之LQR控制算法
  8. aTrust项目的相关操作与分享
  9. python写TCP协议
  10. 一、数字图像处理分析与概述