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

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=21function 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-hwaccelsmake cleanmake -j4make installecho "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=$1if [ -z "$CPU" ]; thenprint_usageexit 1elif [ "$CPU" = "help" ]; thenprint_usageelif [ "$CPU" = "armv7-a" ]; thenARCH=armCC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clangCXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++SYSROOT=$TOOLCHAIN/sysrootCROSS_PREFIX=$TOOLCHAIN/bin/llvm-PREFIX=$(pwd)/android/$CPUADDI_LDFLAGS=" "OPTIMIZE_CFLAGS="-mfloat-abi=softfp -march=$CPU"build_androidelif [ "$CPU" = "armv8-a" ]; thenARCH=arm64CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clangCXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++SYSROOT=$TOOLCHAIN/sysrootCROSS_PREFIX=$TOOLCHAIN/bin/llvm-PREFIX=$(pwd)/android/$CPUOPTIMIZE_CFLAGS="-march=$CPU"build_androidelseecho "Unsupported CPU: $CPU"print_supported_cpusfi

环境设置

  • 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.firstjniavcodecavfilteravformatavutilswresampleswscale# 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.mzph.cn/pingmian/46886.shtml

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

相关文章

普通人还有必要学习 Python 之类的编程语言吗?

在开始前分享一些编程的资料需要的同学评论888即可拿走 是我根据网友给的问题精心整理的对于编程的重要性&#xff0c;这里就不详谈了。 未来&#xff0c;我们和机器的交流会越来越多&#xff0c;编程可以简单看作是和机器对话并分发给机器任务。机器不仅越来越强大&#xff0…

C# —— CRC16 算法

CRC16:即循环冗余校验码。数据通信当中一种常用的查错校验码 其特征信息字段和校验字段的长度可以是任意选定的&#xff0c;对数据进行指定多项式计算 并且将得到的结果附加在帧的后面&#xff0c;接受的设备也执行类似的算法&#xff0c;以保证数据传输的正确性和完整性 crc…

鸿蒙语言基础类库:【@system.configuration (应用配置)】

应用配置 说明&#xff1a; 从API Version 7 开始&#xff0c;该接口不再维护&#xff0c;推荐使用新接口[ohos.i18n]和[ohos.intl]。本模块首批接口从API version 3开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import configurati…

云服务器实际内存与购买不足量问题

君衍 一、本篇缘由二、问题研究1、dmidecode2、dmesg | grep -i memory 三、kdump四、解决方案1、卸载kdump-tools2、清理依赖包3、修改配置文件4、重新生成配置文件5、重启服务器6、再次查看 一、本篇缘由 本篇由于最近买了云服务器&#xff0c;之前基本在本地使用VMware进行虚…

web自动化测试selenium的基本使用

目录 初始化浏览器并打开网页 定位网页元素 定位的方法 模拟键盘操作 模拟鼠标操作 xpath方法 xpath结点 路径表达式 轴 selenium是一个很流行的自动化测试的库&#xff0c;主要用于模拟浏览器的运行&#xff0c;是web应用测试的工具。 在使用selenium时&#xff0c;…

(二)高并发压力测试调优篇——caffeine本地缓存调优

前言 在上一节内容中我们主要介绍了高并发请求下&#xff0c;mysql数据库的调优&#xff0c;其调优的主要原理是尽量减少数据库的IO操作&#xff0c;从而提高服务器的访问性能。在此基础上&#xff0c;本节内容是关于如何利用缓存&#xff0c;提高系统的并发访问能力。我们会首…

Linux部署禅道(无脑复制版)

目录 环境部署1、下载&#xff0c;解压2、启动3、设置开机自启 登录禅道登录数据库1、设置账号2、网页登录数据库 环境 Linux系统 Centos7 《Linux一键安装包安装禅道》视频链接&#xff1a; https://www.zentao.net/zentao-install/zentao-linux-install-80523.html 部署 …

谢启昆:乾隆年间的清廉典范与学术巨擘

谢启昆&#xff0c;一位生活在清朝乾隆年间的杰出人物&#xff0c;以其清廉的政绩和卓越的学术成就&#xff0c;成为后世效仿的典范。他的画像中&#xff0c;目光如炬&#xff0c;透露出坚毅与智慧的光芒&#xff0c;仿佛在诉说着他不平凡的一生。 谢启昆出生在一个书香门第&am…

多元统计分析概述

目录 1. 多元回归分析 2. 主成分分析&#xff08;PCA&#xff09; 3. 因子分析 4. 判别分析 5. 聚类分析 6. 多维尺度分析&#xff08;MDS&#xff09; 结论 多元统计分析是一组用于分析多个变量之间关系的统计方法。它广泛应用于各个领域&#xff0c;如市场研究、生物医…

PHP webshell 免杀方法

本文介绍php类webshell简单的免杀方法&#xff0c;总结不一定全面&#xff0c;仅供读者参考。 webshell通常可分为一句话木马&#xff0c;小马&#xff0c;大马&#xff0c;内存马。 一句话木马是最简单也是最常见的webshell形式&#xff0c;这种木马体积小&#xff0c;隐蔽较…

a newer or same version is present nvidia解决方案

安装时候出现a newer or same version is present nvidia 或者Night Visual Editor 失败&#xff0c;把显卡驱动卸载掉&#xff0c;打开service.mtc 服务控制面板&#xff0c;把nvidia开头的服务全停掉&#xff0c;重新启动cuda安装程序选择自定义安装 vse visual studio相关的…

鸿蒙语言基础类库:【@system.device (设备信息)】

设备信息 说明&#xff1a; 从API Version 6开始&#xff0c;该接口不再维护&#xff0c;推荐使用新接口[ohos.deviceInfo]进行设备信息查询。本模块首批接口从API version 3开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import dev…

手把手教你,如何利用积木易搭3D扫描仪完成文物三维建模?

当前&#xff0c;文物三维建模主要技术手段主要有摄影测量技术、三维激光扫描技术、结构光扫描技术。其中&#xff0c;积木易搭的MagicScan作为一款先进的3D扫描仪&#xff0c;是正是运用了结构光扫描技术的精髓&#xff0c;它巧妙地融合了点云相机的高精度空间数据采集能力、纹…

如何用python写接口

如何用python写接口&#xff1f;具体步骤如下&#xff1a;  1、实例化server 2、装饰器下面的函数变为一个接口 3、启动服务 开发工具和流程&#xff1a; python库&#xff1a;flask 》实例化server&#xff1a;server flask.Flask(__name__) 》server.route(/index,met…

【STM32嵌入式系统设计与开发---拓展】——1_9 GPIO的输入和输出

这里写目录标题 0、输入 输出1、输出&#xff08;1&#xff09;GPIO_SetBits:用于设置 GPIO 引脚的状态&#xff08;即将指定的引脚设置为高电平&#xff09; 2、输入&#xff08;1&#xff09;GPIO_ReadInputDataBit&#xff08;&#xff09; 0、输入 输出 咋们定义了一个结构…

解决ESLint和Prettier冲突的问题

在配置了ESLint的项目中使用Prettier进行格式化可能会出现冲突&#xff0c;不如Prettier配置了使用双引号&#xff0c;ESLint配置了单引号&#xff0c;当然可以一个一个改成一样的配置&#xff0c;但是比较麻烦。我发现可以直接使用ESLint的规则进行格式化。在VSCode配置过程如…

xss复习总结及ctfshow做题总结xss

xss复习总结 知识点 1.XSS 漏洞简介 ​ XSS又叫CSS&#xff08;Cross Site Script&#xff09;跨站脚本攻击是指恶意攻击者往Web页面里插入恶意Script代码&#xff0c;当用户浏览该页之时&#xff0c;嵌入其中Web里面的Script代码会被执行&#xff0c;从而达到恶意攻击用户的…

软考从报考到拿到证书的过程

一、报考阶段及参加考试阶段 这个阶段可以留意软考官网的的信息&#xff0c;一般上半年是3月份报名、5月份考试&#xff1b;下半年是8月份报名、11月份考试。以下是这个阶段会用到的链接&#xff0c;保持关注就好。 软考官网&#xff1a;中国计算机技术职业资格网 (ruankao.o…

六、 SpringBoot 配置⽂件 ★ ✔【value的引号注意事项、@ConfigurationProperties 、】

六、 SpringBoot 配置⽂件 本节⽬标1. 配置⽂件作⽤2. 配置⽂件快速⼊⼿3. 配置⽂件的格式4. properties 配置⽂件说明4.1 properties 基本语法4.2 读取配置⽂件4.3 properties 缺点分析 5. yml 配置⽂件说明5.1 yml 基本语法5.2 yml 使⽤进阶5.2.1 yml 配置不同数据类型及 nul…