NDK R25b 交叉编译FFMpeg4,项目集成,附库下载地址

news2024/9/24 7:22:28

1.准备工作

文件下载:

NDK R25b下载地址:Android NDK历史版本下载网址 - 君*邪 - 博客园 (cnblogs.com)

FFmpeg4.4.4 下载地址:https://ffmpeg.org/releases/ffmpeg-4.4.4.tar.xz

环境配置:

本次编译环境是在PC虚拟机中使用Ubuntu18.04

在这里插入图片描述

下载好NDK和FFmpeg 之后,复制到Ubuntu下然后解压,为交叉编译做准备

2.交叉编译FFmpeg流程

解压完FFmpeg源码之后,进入源码根目录,新建编译脚本android.sh

在这里插入图片描述

新版 ndk 已放弃 gcc,转而使用更高效的 clang,下述脚本以 clang 为例编译 FFmpeg 源码。支持编译armv8-a 和armv7-a,注意修改成你的NDK目录地址

 #!/bin/bash

 # 修改成你的NDK目录
 TOOLCHAIN=/home/marxist/ndk/android-ndk-r25b-linux/android-ndk-r25b/toolchains/llvm/prebuilt/linux-x86_64
 # 最低支持的android sdk版本
 API=21

 function build_android
 {
 echo "Compiling FFmpeg for $CPU"

 ./configure \
  --prefix=$PREFIX \
  --enable-neon \
  --enable-shared \
  --enable-small \
  --disable-vulkan \
  --disable-gpl \
  --disable-postproc \
  --disable-jni \
  --disable-mediacodec \
  --disable-decoder=h264_mediacodec \
  --disable-static \
  --disable-doc \
  --disable-programs \
  --disable-ffmpeg \
  --disable-ffplay \
  --disable-ffprobe \
  --disable-avdevice \
  --disable-symver \
  --enable-cross-compile \
  --cross-prefix=$CROSS_PREFIX \
  --target-os=android \
  --arch=$ARCH \
  --cpu=$CPU \
  --cc=$CC \
  --cxx=$CXX \
  --sysroot=$SYSROOT \
  --extra-cflags="-mno-stackrealign -Os -fpic -mfpu=neon $OPTIMIZE_CFLAGS" \
  --extra-ldflags="$ADDI_LDFLAGS"
  #--disable-debug
  #--disable-stripping
  #--disable-linux-perf
  #--disable-hwaccels

 make clean
 make -j4
 make install

 echo "The Compilation of FFmpeg for $CPU is completed"
 }

 function print_supported_cpus
 {
     echo "Supports the following CPUs:"
     echo "1. armv7-a"
     echo "2. armv8-a"
 }

 function print_usage
 {
     echo "Usage: $0 [CPU]"
     echo "Example: $0 armv7-a"
     print_supported_cpus
 }

 # 传入CPU参数
 CPU=$1

 if [ -z "$CPU" ]; then
     print_usage
     exit 1
 elif [ "$CPU" = "help" ]; then
     print_usage
 elif [ "$CPU" = "armv7-a" ]; then
     ARCH=arm
     CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
     CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
     SYSROOT=$TOOLCHAIN/sysroot
     CROSS_PREFIX=$TOOLCHAIN/bin/llvm-
     PREFIX=$(pwd)/android/$CPU
     ADDI_LDFLAGS=" "
     OPTIMIZE_CFLAGS="-mfloat-abi=softfp -march=$CPU"
     build_android
 elif [ "$CPU" = "armv8-a" ]; then
     ARCH=arm64
     CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
     CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
     SYSROOT=$TOOLCHAIN/sysroot
     CROSS_PREFIX=$TOOLCHAIN/bin/llvm-
     PREFIX=$(pwd)/android/$CPU
     OPTIMIZE_CFLAGS="-march=$CPU"
     build_android
 else
     echo "Unsupported CPU: $CPU"
     print_supported_cpus
 fi

环境设置

  • TOOLCHAIN: 指向 NDK 中包含的 LLVM 工具链的路径。这个路径用于定位编译工具(如 clang)和系统根目录。
  • API: 设置编译目标的最低 Android API 级别。

函数定义

  1. build_android

    • 打印正在为特定 CPU 架构编译 FFmpeg。
    • 运行 FFmpeg 的 ./configure 脚本来配置编译选项。
    • 调用 make clean 清理之前的构建结果。
    • 使用 make -j4 启动并行编译过程。
    • 调用 make install 将编译结果安装到指定的前缀路径 $PREFIX
    • 打印完成编译的消息。
  2. print_supported_cpus

    • 打印支持的 CPU 类型。
  3. print_usage

    • 打印脚本的使用方法。

主体逻辑

  • 脚本接收一个参数($1),即 CPU 类型。
  • 根据传入的 CPU 类型,设置相关的编译参数:
    • ARCH: 指定目标架构。
    • CCCXX: 指定 C 和 C++ 编译器。
    • SYSROOT: 设置系统根目录。
    • CROSS_PREFIX: 设置交叉编译工具前缀。
    • PREFIX: 指定安装目录。
    • ADDI_LDFLAGS: 设置额外的链接器标志。
    • OPTIMIZE_CFLAGS: 设置针对特定 CPU 优化的编译标志。
  • 调用 build_android 函数开始编译流程。

详细配置参数(./configure)

  • --prefix=$PREFIX: 指定安装路径。
  • --enable-neon, --enable-shared, --enable-small: 启用 ARM NEON 指令集支持,生成共享库,优化库大小。
  • --disable-...: 禁用多个功能,如 Vulkan, GPL 功能,文档生成等。
  • --enable-cross-compile: 启用交叉编译模式。
  • --cross-prefix=$CROSS_PREFIX: 设置交叉编译前缀。
  • --target-os=android: 设置目标操作系统为 Android。
  • --arch=$ARCH: 设置目标架构。
  • --cpu=$CPU: 设置目标 CPU。
  • --cc=$CC, --cxx=$CXX: 设置 C 和 C++ 编译器。
  • --sysroot=$SYSROOT: 设置系统根目录。
  • --extra-cflags: 设置额外的编译标志,主要用于性能优化和适应特定硬件。
  • --extra-ldflags: 设置额外的链接标志。

编译成功之后,在源码目录的android文件夹生成目标CPU的so库和相关的头文件,libavcodec.so libavformat.so libswresample.so libavfilter.so libavutil.so

在这里插入图片描述

如果需要其他的so 注释掉编译脚本的disable 就能生成对应的其他库

3.Android项目集成FFmpeg库

在项目main文件夹新建 ThirdLib文件夹,根据需求添加不同CPU架构下的so库,这里主要是添加了arm64v8-a的库(在ThirdLib文件夹新建arm64-v8a 文件夹,方便与CMakeLists.txt做对应)

在cpp文件夹新建include文件夹,将FFmpeg头文件放入进去,头文件编译的时候会生成。

在这里插入图片描述

项目目录层级如上图所示,ThirdLib文件夹与cpp文件夹同一目录,include文件夹与CMakeLists.txt同一目录。如果所有设置都与我一致,就可以直接copy CMakeLists.txt

接下来就是配置CMakeLists.txt

引入FFmpeg 头文件,添加FFmpeg相关的库

# Include directories
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

add_library(avcodec SHARED IMPORTED)
set_target_properties(avcodec PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../ThirdLib/arm64-v8a/libavcodec.so)
add_library(avfilter SHARED IMPORTED)
set_target_properties(avfilter PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../ThirdLib/arm64-v8a/libavfilter.so)
add_library(avformat SHARED IMPORTED)
set_target_properties(avformat PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../ThirdLib/arm64-v8a/libavformat.so)
add_library(avutil SHARED IMPORTED)
set_target_properties(avutil PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../ThirdLib/arm64-v8a/libavutil.so)
add_library(swresample SHARED IMPORTED)
set_target_properties(swresample PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../ThirdLib/arm64-v8a/libswresample.so)
add_library(swscale SHARED IMPORTED)
set_target_properties(swscale PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../ThirdLib/arm64-v8a/libswscale.so)

编译的时候链接库, firstjni是我的项目名称,不同项目名称自动生成不同的名字,主要是添加五个库

#编译链接库
target_link_libraries( # Specifies the target library.
        firstjni
        avcodec
        avfilter
        avformat
        avutil
        swresample
        swscale
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

4.示例代码,获取FFmpeg版本

在MainActivity生成JNI函数接口

 public native String getFFMpegVersion();

使用Android Studio自动创建相应的c++实现

native-lib.cpp 引入FFmpeg头文件

extern "C"{
#include <libavutil/avutil.h>
}

实现接口,获取FFMpeg当前版本

extern "C"
JNIEXPORT jstring JNICALL
Java_com_marxist_firstjni_MainActivity_getFFMpegVersion(JNIEnv *env, jobject thiz) {
    // TODO: implement getFFMpegVersion()
    const char *ffmpeg_version = av_version_info();
    return env->NewStringUTF(ffmpeg_version);
}

效果如图: 输出了4.4.4

在这里插入图片描述

5.资源下载

提供armv7 和 armv8两个版本

编译平台:NDK R25b

FFmpeg版本: 4.4.4

链接:https://pan.baidu.com/s/1PH6bVRv8_0hda-VjesoRyw
提取码:c0rc

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1932209.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

水表数字识别2:Pytorch DBNet实现水表数字检测(含训练代码和数据集)

水表数字识别2&#xff1a;Pytorch DBNet实现水表数字检测(含训练代码和数据集) 目录 水表数字识别2&#xff1a;Pytorch DBNet实现水表数字检测(含训练代码和数据集) 1.前言 2. 水表数字识别的方法 3. 水表数字识别数据集 4. 水表数字分割模型训练 &#xff08;1&#x…

Oracle线上执行SQL特别慢的原因分析

一、背景&#xff1a; 线上反馈一张表select * from table where idxxx语句执行特别慢&#xff0c;超过60s超时不能处理&#xff0c;第一直觉是索引失效了&#xff0c;开始执行创建索引语句create index index_name on table() online。但是执行了超过20分钟索引还没有创建成功…

NestJs框架getRepository方法废弃解决办法,顺便介绍一下typeORM框架

报错&#xff1a; Connection "default" was not found. ... ...因为 typeorm 版本不对&#xff0c;这是旧版的 api, 可以考虑降版本到 <0.3.0 解决 介绍一下 typeORM 我们如果直接使用 Node.js 操作 mysql 提供的接口&#xff0c; 那么编写的代码就比较底层&a…

彩电上自带的推箱子游戏是什么编程语言开发的?

2000年左右的厦新彩电上&#xff0c;自带了推箱子、华容道游戏。界面如下&#xff1a; 在线版推箱子游戏&#xff0c;网址&#xff1a;https://www.tuixiangzi.cn/ BASIC&#xff0c;全称是Beginners All-purpose Symbolic Instruction Code&#xff0c;含义是初学者通用符号…

Nuxt.js头部魔法:轻松自定义页面元信息,提升用户体验

title: Nuxt.js头部魔法&#xff1a;轻松自定义页面元信息&#xff0c;提升用户体验 date: 2024/7/16 updated: 2024/7/16 author: cmdragon excerpt: 摘要&#xff1a;“Nuxt.js头部魔法&#xff1a;轻松自定义页面元信息&#xff0c;提升用户体验”介绍如何使用useHead函数…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【查询密钥别名集(ArkTS)】

查询密钥别名集(ArkTS) HUKS提供了接口供应用查询密钥别名集。 开发步骤 初始化密钥属性集。用于查询指定密钥别名集TAG&#xff0c;TAG仅支持HUKS_TAG_AUTH_STORAGE_LEVEL。调用接口[listAliases]&#xff0c;查密钥别名集。 HarmonyOS与OpenHarmony鸿蒙文档籽料&#xff1…

中国星坤X0800HI系列线对板连接器:创新技术连接,引领智能家居未来!

近日&#xff0c;中国星坤推出的X0800HI系列线对板连接器&#xff0c;凭借其独特的设计和卓越的性能&#xff0c;引起了业界的广泛关注。 X0800HI系列线对板连接器在极小空间内实现了线对板的W-B连接&#xff0c;这不仅解决了传统连接方式中剥线和焊接的繁琐步骤&#xff0c;还…

【Linux 配置静态IP】Ubuntu20.04

最近学习网络编程&#xff0c;为了方便学习需要Ubuntu配置静态IP&#xff0c;网上看了好多贴子跟着试了下可以实现&#xff0c;但重启虚拟机后有时就无法连接&#xff0c;总之各种各样问题&#xff1b;相关的配置方法也比较凌乱&#xff0c;有用netplan 或者 ifupdown ,笔者简单…

【日常记录】【插件】excel.js 的使用

文章目录 1. 引言2. excel.js2.1 创建工作簿和工作表2.2 excel文件的导出2.3 excel文件的导入2.4 列2.5 行2.6 添加行2.7 单元格2.8 给总价列设置自动计算(除表头行) 3. 总结参考链接 1. 引言 前端导出excel文件常用库一般是 excel.js 和 xlsx.js xlsx.js 导出数据确实方便&…

函数定义、合约与面向对象(以太坊solidity合约)

函数定义、合约与面向对象&#xff08;以太坊solidity合约&#xff09; 1-函数定义、构造与多态2-事件日志3-面向对象特征 1-函数定义、构造与多态 创建合约就是创建类&#xff0c;部署合约就是实例化 合约的方法还支持多态 还能使用第三方的库进行开发 整个合约部署后&…

AAD Connect自定义同步用户上云

使用场景&#xff1a;我想同步本地AD域的那些用户信息、账号上云端做SSO登录和权限管控&#xff0c;但是不希望使用快速上传一股脑传上去&#xff0c;所以使用自定义同步功能上传&#xff0c;这是一篇对AAD CONNECT这个应用的详解和配置步骤推荐 AD Connect如何自定义配置&…

百分点科技签约潍坊市数据产业发展战略合作

近日&#xff0c;潍坊市数据产业发展战略合作签约仪式举行&#xff0c;潍坊市人民政府副市长张震生&#xff0c;潍坊市财政局党组书记、局长王金祥&#xff0c;潍坊市大数据局党组书记陈强出席大会并致辞。百分点科技受邀进行战略合作签约&#xff0c;共同见证潍坊市数据要素市…

Python和C++骨髓细胞进化解析数学模型

&#x1f3af;要点 &#x1f3af; 数学模型邻接矩阵及其相关的转移概率 | &#x1f3af;蒙特卡罗模拟进化动力学 | &#x1f3af;细胞进化交叉图族概率 | &#x1f3af;进化图模型及其数学因子 | &#x1f3af;混合图模式对进化概率的影响 | &#x1f3af;造血干细胞群体的空间…

【异步爬虫:利用异步协程抓取一部电影】

利用异步协程抓取一部电影 我们把目光转向wbdy. 目前该案例还是可以用的. 我们想要抓取网上的视频资源就必须要了解我们的视频网站是如何工作的. 这里我用91看剧来做举例. 其他网站的原理是一样的. 1.视频网站是如何工作的 假设, 你现在想要做一个视频网站. 也有很多的UP猪…

【数学建模】高温作业专用服装设计(2018A)隐式差分推导

为方便计算&#xff0c;对区域进行离散化处理&#xff0c;采用隐式差分格式进行离散计算。隐式差分格式如图&#xff1a; 每层材料内部 对第 j j j层材料: 其中&#xff0c; λ j \lambda_j λj​表示第 j j j层的热扩散率&#xff0c; c j c_j cj​表示第 j j j层的比热容…

IntelliJ IDEA 2024.1 最新变化 附问卷调查 AI

IntelliJ IDEA 2024.1 最新变化 问卷调查项目在线AI IntelliJ IDEA 2024.1 最新变化关键亮点全行代码补全 Ultimate对 Java 22 功能的支持新终端 Beta编辑器中的粘性行 AI AssistantAI Assistant 改进 UltimateAI Assistant 中针对 Java 和 Kotlin 的改进代码高亮显示 Ultimate…

第100+16步 ChatGPT学习:R实现Xgboost分类

基于R 4.2.2版本演示 一、写在前面 有不少大佬问做机器学习分类能不能用R语言&#xff0c;不想学Python咯。 答曰&#xff1a;可&#xff01;用GPT或者Kimi转一下就得了呗。 加上最近也没啥内容写了&#xff0c;就帮各位搬运一下吧。 二、R代码实现Xgboost分类 &#xff08…

智能守护校园餐桌:校园阳光食堂视频AI监控智能管理方案

一、背景分析 随着科技的飞速发展&#xff0c;智能化、信息化已成为现代校园管理的重要趋势。校园食堂作为学校重要的服务设施&#xff0c;其食品安全、环境卫生和秩序管理显得尤为重要。作为校园生活中不可或缺的一部分&#xff0c;食堂的管理也急需引入先进技术&#xff0c;…

【Git】(基础篇二)—— Git操作

Git操作 在了解git理论知识之后&#xff0c;本文将结合实践操作为你讲解git的底层逻辑 Git的安装和配置 git官网下载&#xff1a;https://git-scm.com/ 下载后安装时除了选择安装地址外&#xff0c;其余都保持默认下一步即可。 安装好后鼠标右键会出现两个新的选项【Open …

STM32 BootLoader 刷新项目 (五) 获取软件版本号-命令0x51

STM32 BootLoader 刷新项目 (五) 获取软件版本号-命令0x51 下面我们来讲解第一个指令&#xff0c;获取软件版本号命令-0x51. 在BootLoader中获取软件版本号的操作有多个重要的作用&#xff0c;具体如下&#xff1a; 版本管理&#xff1a; 识别当前版本&#xff1a;通过获取软…