安卓新的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. pytorch手动实现梯度下降法,随机梯度法--基于logistic Regression并探索Mini batch作用
  2. 国网浙江电力组建网络安全分析室
  3. “智云大咖秀”:大咖摄影师谈惊艳亮相的“大咖级”设备
  4. 给ULWOW 写的广告效果(缓动切换)
  5. CentOS下使用rpm-build制作nginx的RPM包
  6. 【转】EL表达式 (详解) .
  7. 萌新向Python数据分析及数据挖掘 第二章 pandas 第二节 Python Language Basics, IPython, and Jupyter Notebooks...
  8. Linux怎么修改用户密码
  9. Xbox360手柄驱动xbcd+
  10. Docker破解AWVS和Nessus
  11. nodejs调用google翻译api
  12. QCC300x hello world
  13. unas 下 Transmission 下载使用体会
  14. 单片机流水单C语言程序,51单片机流水灯C语言源程序
  15. 微信小程序获取access_token报错errcode: 40125,errmsg: invalid appsecret
  16. DotNet 资源大全(转)
  17. 2022年证券从业资格证券投资基金考试多选题专练及答案
  18. 使用wireshark抓取账号密码
  19. pwnable kr 之 passcode
  20. 使用遗传算法和模拟退火改进的K均值聚类

热门文章

  1. Java设计模式总结
  2. R语言:关于我国各地区消费水平的聚类分析
  3. 王思聪吃热狗的c语言小程序,王思聪吃热狗火了,各种恶搞小程序!王校长:我不要脸的啊...
  4. comps电磁场模拟软件_|Mentor Graphics IE3D(电磁场仿真软件)下载v15.0官方版 - 欧普软件下载...
  5. 计算机主机前耳机没声音,电脑前面耳机没声音的解决办法 电脑前面插耳机没声音怎么办...
  6. 手把手教你学习DSP_硬件设计
  7. 俄罗斯独立自主的计算机技术和计算机网络
  8. 金蝶KIS 11.0专业版账套升级至WISE 13.1版本实施步骤
  9. 如何破解qq仅三天可见
  10. 计算机基础试题及答案 完整版,大学计算机基础试题及答案(完整版)