Shell生成支持x264的ffmpeg安卓全平台so

安卓 FFmpeg系列

第一章 Ubuntu生成ffmpeg安卓全平台so
第二章 Windows生成ffmpeg安卓全平台so
第三章 生成支持x264的ffmpeg安卓全平台so(本章)


文章目录

  • 安卓 FFmpeg系列
  • 前言
  • 一、实现步骤
    • 1、下载x264源码
    • 2、交叉编译生成.a
    • 3、加入x264配置
    • 4、编译ffmpeg
  • 二、完整代码
  • 三、生成好的包
  • 四、使用示例
    • 1、基本用法
      • (1)查看用法
      • (2)确认ffmpeg版本
      • (3)生成so
    • 2、ubuntu中使用
    • 3、windows msys2中使用
  • 总结


前言

前两张实现了ffmpeg全平台so的生成,但是ffmpeg依赖的第三方库是需要另外编译的,所以本章将提供编译x264库并加入ffmpeg的方法。本章提供的脚本在ubuntu以及windows的wsl、msys2都适用。


一、实现步骤

定义交叉编译相关变量

#ndk api版本 -可配置
API=24
#cpu 架构 -可配置 :armv7-a、armv8-a、i686、x86-64
CPU=x86-64
#msys则可设置为windows
OS=linux
#需要ANDROID_NDK_HOME指定ndk目录
TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$OS-x86_64
echo $TOOLCHAIN
SYSROOT=$TOOLCHAIN/sysroot
PREFIX=$(pwd)/output/ffmpeg${FFMPEG_VERSION}/${API}/${CPU}
PACKAGE_PREFIX=$PACKAGE_SOURCE_DIR/.output/${API}/${CPU}
export CC=${CROSS_PREFIX}clang
export CXX=${CROSS_PREFIX}clang++
case $CPU in
armv7-a)
  ARCH=arm
  CROSS_PREFIX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-
  ;;
armv8-a)
  ARCH=arm64
  CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android$API-
  ;;
i686)
  ARCH=x86
  CROSS_PREFIX=$TOOLCHAIN/bin/i686-linux-android$API-
  FFMPEG_EXTRA_CONFIGURE_FLAGS=--disable-asm
  ;;
x86-64)
  ARCH=x86_64
  CROSS_PREFIX=$TOOLCHAIN/bin/x86_64-linux-android$API-
  ;;

1、下载x264源码

 wget https://code.videolan.org/videolan/x264/-/archive/master/x264-master.tar.bz2
 tar -xf $PACKET_X264.tar.bz2

2、交叉编译生成.a

在x264源码目录执行如下操作。其中X264_OUTPUT_DIR 为输出目录,ARCH为cpu架构

./configure \
    --prefix=$X264_OUTPUT_DIR \
    --enable-static \
    --enable-pic \
    --host=$ARCH-linux \
    --disable-opencl \
    --disable-cli \
    --cross-prefix=$CROSS_PREFIX \
    --sysroot=$SYSROOT \
    FFMPEG_EXTRA_CONFIGURE_FLAGS
make -j$(nproc) 
make install

3、加入x264配置

FFMPEG_EXTRA_CFLAGS="$FFMPEG_EXTRA_CFLAGS -I$X264_OUTPUT_DIR/include"
FFMPEG_EXTRA_LDFLAGS="$FFMPEG_EXTRA_LDFLAGS -L$X264_OUTPUT_DIR/lib"
FFMPEG_EXTRA_CONFIGURE_FLAGS="$FFMPEG_EXTRA_CONFIGURE_FLAGS --enable-encoder=libx264 --enable-libx264"
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$X264_OUTPUT_DIR/lib/pkgconfig"

4、编译ffmpeg

 ./configure --target-os=android \
    --prefix=$PREFIX \
    --arch=$ARCH \
    --cpu=$CPU \
    --cc=$CC \
    --cxx=$CXX \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --enable-gpl \
    --cross-prefix=$CROSS_PREFIX \
    --enable-cross-compile \
    --enable-jni \
    --enable-mediacodec \
    --enable-decoder=h264_mediacodec \
    --enable-decoder=hevc_mediacodec \
    --enable-decoder=vp8_mediacodec \
    --enable-decoder=vp9_mediacodec \
    --enable-decoder=mpeg2_mediacodec \
    --enable-decoder=mpeg4_mediacodec \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic -DVK_ENABLE_BETA_EXTENSIONS=0 -march=$CPU $FFMPEG_EXTRA_CFLAGS" \
    --extra-ldflags="$FFMPEG_EXTRA_LDFLAGS" \
    --pkg-config="pkg-config --static" \
    $SHARED_OR_STATIC_FLAG \
    $FFMPEG_EXTRA_CONFIGURE_FLAGS
make -j$(nproc)
make install

二、完整代码

下列代码可以在ubuntu、wsl ubuntu、msys2中执行。无需任何额外操作,只需调用脚本即可生成so。可以指定cpu、安卓api、以及ffmpeg版本号。如果没有指定ANDROID_NDK_HOME会自动下载ndk,x264源码也会自动下载以及ffmpeg源码也会自动下载,然后自动生成so。同时还会生成ffmpeg.so,是ffmpeg可执行程序,笔者将其生成了so,其内包含的main符号可以直接调用,以输入命令行
注:合并所有库到libffmpeg.so的方式本文暂不提供。
下列代码可复制保存为build.sh直接执行。

set -e
show_usage() {
  echo "usage:
      -p is cpu (armv7-a、armv8-a、i686、x86-64) 
      -a is android api number
      -f is ffmpeg version
      -h is help
   "
}
#ffmpeg版本 -可配置
FFMPEG_VERSION=4.3.6
#ndk api版本 -可配置
API=24
#cpu 架构 -可配置 :armv7-a、armv8-a、i686、x86-64
CPU=x86-64
while getopts "p:a:f:h" arg; do
  case $arg in
  p)
    CPU=$OPTARG
    ;;
  a)
    API=$OPTARG
    ;;
  f)
    FFMPEG_VERSION=$OPTARG
    ;;
  h)
    show_usage
    exit 1 
    ;;
  ?)
    echo "unkonw argument"
    show_usage
    exit 1
    ;;
  esac
done
OS=$(uname -o)
echo $OS
if [ $OS == "Msys" ]; then
  OS="windows"
  NDK_URL="https://googledownloads.cn/android/repository/android-ndk-r26d-windows.zip"
  NDK_SHA1="c7ea35ffe916082876611da1a6d5618d15430c29"
else
  OS="linux"
  NDK_URL=" https://googledownloads.cn/android/repository/android-ndk-r26d-linux.zip"
  NDK_SHA1="fcdad75a765a46a9cf6560353f480db251d14765"

fi
echo "************************************Build Info*********************************"
echo "Host os :$OS"
echo "Target cpu :$CPU"
echo "Android api :$API"
echo "FFmpeg version :$FFMPEG_VERSION"
echo "************************************Build Info End*****************************"
PACKAGE_SOURCE_DIR=$(pwd)/.package
#下载NDK
if [ ! -d "$PACKAGE_SOURCE_DIR" ]; then
  mkdir $PACKAGE_SOURCE_DIR
fi
if [ ! -d "$ANDROID_NDK_HOME" ]; then
  pushd $PACKAGE_SOURCE_DIR
  if [ ! -d "ndk" ]; then
    if [ -e "ndk.zip" ]; then
      sha1=$(sha1sum ndk.zip)
    fi
	sha1=($sha1)
    echo "${sha1[0]}"
    if [ "$sha1" != "$NDK_SHA1" ]; then
      if [ -e "ndk.zip" ]; then
        rm ndk.zip
      fi
      echo ndk Downloading...
      wget $NDK_URL -O ndk.zip
	  exit 1
    fi
    if [ -d "ndk" ]; then
      rm -rf ndk
    fi
    unzip ndk.zip -d ndk
  fi
  ANDROID_NDK_HOME=$PACKAGE_SOURCE_DIR/ndk/$(ls ndk)
  popd
fi
#下载NDK -end
TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$OS-x86_64
echo $TOOLCHAIN

SYSROOT=$TOOLCHAIN/sysroot
case $CPU in
armv7-a)
  ARCH=arm
  CROSS_PREFIX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-
  USR_LIB=$SYSROOT/usr/lib/armv7a-linux-androideabi/$API
  ;;
armv8-a)
  ARCH=arm64
  CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android$API-
  USR_LIB=$SYSROOT/usr/lib/aarch64-linux-android/$API
  ;;
i686)
  ARCH=x86
  CROSS_PREFIX=$TOOLCHAIN/bin/i686-linux-android$API-
  USR_LIB=$SYSROOT/usr/lib/i686-linux-android/$API
  FFMPEG_EXTRA_CONFIGURE_FLAGS=--disable-asm
  ;;
x86-64)
  ARCH=x86_64
  CROSS_PREFIX=$TOOLCHAIN/bin/x86_64-linux-android$API-
  USR_LIB=$SYSROOT/usr/lib/x86_64-linux-android/$API
  ;;
esac
PREFIX=$(pwd)/output/ffmpeg${FFMPEG_VERSION}/${API}/${CPU}
PACKAGE_PREFIX=$PACKAGE_SOURCE_DIR/.output/${API}/${CPU}
export CC=${CROSS_PREFIX}clang
export CXX=${CROSS_PREFIX}clang++
CROSS_PREFIX=$TOOLCHAIN/bin/llvm-
#x264
pushd $PACKAGE_SOURCE_DIR
PACKET_X264=x264-master
X264_OUTPUT_DIR=$PACKAGE_PREFIX/x264
FFMPEG_EXTRA_LINK_LIBRARY="$FFMPEG_EXTRA_LINK_LIBRARY $X264_OUTPUT_DIR/lib/libx264.a"
FFMPEG_EXTRA_CFLAGS="$FFMPEG_EXTRA_CFLAGS -I$X264_OUTPUT_DIR/include"
FFMPEG_EXTRA_LDFLAGS="$FFMPEG_EXTRA_LDFLAGS -L$X264_OUTPUT_DIR/lib"
FFMPEG_EXTRA_CONFIGURE_FLAGS="$FFMPEG_EXTRA_CONFIGURE_FLAGS --enable-encoder=libx264 --enable-libx264"
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$X264_OUTPUT_DIR/lib/pkgconfig"
if [ ! -e "$X264_OUTPUT_DIR/lib/libx264.a" ]; then
  if [ ! -d "$PACKET_X264" ]; then
    echo x264 Downloading...
    wget https://code.videolan.org/videolan/x264/-/archive/master/x264-master.tar.bz2
    tar -xf $PACKET_X264.tar.bz2
  fi
  if [ "$ARCH" != "x64" ]; then
    PACKET_X264_EXTRA_CONFIGURE_FLAG="--disable-asm"
  fi
  echo x264 Configuring...
  pushd $PACKET_X264
  ./configure \
    --prefix=$X264_OUTPUT_DIR \
    --enable-static \
    --enable-pic \
    --host=$ARCH-linux \
    --disable-opencl \
    --disable-cli \
    --cross-prefix=$CROSS_PREFIX \
    --sysroot=$SYSROOT \
    $PACKET_X264_EXTRA_CONFIGURE_FLAG
  echo x264 Building...
  if [ -e "Makefile" ]; then
    make clean
  fi
  make -j$(nproc) -s
  echo x264 Installing...
  make install
  popd
  popd
fi
#x264 -end
#ffmpeg
pushd $PACKAGE_SOURCE_DIR
FFMPEG_SOURCE_DIR=$(pwd)/ffmpeg$FFMPEG_VERSION
if [ ! -d "$FFMPEG_SOURCE_DIR" ]; then
  echo ffmpeg Downloading...
  git clone -b n$FFMPEG_VERSION --depth 1 https://git.ffmpeg.org/ffmpeg.git $FFMPEG_SOURCE_DIR
  tar -xf $PACKET_X264.tar.bz2
fi
pushd $FFMPEG_SOURCE_DIR
build_ffmpeg() {
  #./configure -h
  # echo ffmpeg surport decoders...
  # ./configure --list-decoders
  # echo ffmpeg surport hwaccels...
  # ./configure --list-hwaccels
  echo ffmpeg Configuring...
  ./configure --target-os=android \
    --prefix=$PREFIX \
    --arch=$ARCH \
    --cpu=$CPU \
    --cc=$CC \
    --cxx=$CXX \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --enable-gpl \
    --cross-prefix=$CROSS_PREFIX \
    --enable-cross-compile \
    --enable-jni \
    --enable-mediacodec \
    --enable-decoder=h264_mediacodec \
    --enable-decoder=hevc_mediacodec \
    --enable-decoder=vp8_mediacodec \
    --enable-decoder=vp9_mediacodec \
    --enable-decoder=mpeg2_mediacodec \
    --enable-decoder=mpeg4_mediacodec \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic -DVK_ENABLE_BETA_EXTENSIONS=0 -march=$CPU $FFMPEG_EXTRA_CFLAGS" \
    --extra-ldflags="$FFMPEG_EXTRA_LDFLAGS" \
    --pkg-config="pkg-config --static" \
    $SHARED_OR_STATIC_FLAG \
    $FFMPEG_EXTRA_CONFIGURE_FLAGS
  echo ffmpeg Building...
  if [ -e "Makefile" ]; then
    make clean
  fi
  make -j$(nproc)
  echo ffmpeg Installing...
  make install
}
# SHARED_OR_STATIC_FLAG="--disable-shared --enable-static"
# echo "ffmpeg build static library"
# build_ffmpeg
SHARED_OR_STATIC_FLAG="--enable-shared  --disable-static"
echo "ffmpeg build shared library"
build_ffmpeg
$CC -shared -fPIC \
  $(find $FFMPEG_SOURCE_DIR/fftools -name '*.c' -and -not -name 'ffplay.c' -and -not -name 'ffprobe.c' -and -not -name 'ffplay_renderer.c' -and -not -name 'ffmpeg_qsv.c' -and -not -name 'ffmpeg_videotoolbox.c') \
  -I$FFMPEG_SOURCE_DIR -lm \
  $(find $PREFIX/lib -name "*.so" -type f -print) \
  -o $PREFIX/lib/ffmpeg.so
popd
popd
echo "Generated files in: $PREFIX"
#ffmpeg -end

三、生成好的包

已加入第二章生成好的包里。


四、使用示例

1、基本用法

创建一个ffmpeg-android目录,将完整代码复制保存为build.sh

(1)查看用法

./build.sh -h

在这里插入图片描述

(2)确认ffmpeg版本

ffmpeg版本参考:https://git.ffmpeg.org/ffmpeg.git 去掉前缀n
在这里插入图片描述

(3)生成so

生成全平台、api24、ffmpeg6.1.1的so

arm

./build.sh -p armv7-a -a 24 -f 6.1.1

arm64

./build.sh -p armv8-a -a 24 -f 6.1.1

x86

./build.sh -p i686 -a 24 -f 6.1.1

x64

./build.sh -p x86-64 -a 24 -f 6.1.1

生成好的so在build.sh脚本所在目录的output文件夹下
在这里插入图片描述

2、ubuntu中使用

wsl、虚拟机都可以。参考第一章安装必要的工具。

sudo apt install git unzip
./build.sh -p armv7-a -a 24 -f 6.1.1

3、windows msys2中使用

在msys2生成需要参考第二章配置环境,以及安装必要的工具。

pacman -S unzip git
./build.sh -p armv7-a -a 24 -f 6.1.1

总结

以上就是今天讲述的内容,生成ffmpeg安卓so其实并不难,如果熟悉交叉编译以及shell,编译起来还是比较简单的,尤其是想生成最小或者完整依赖的包,最好还是自己生成。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【ZIP技巧】ZIP分卷压缩包如何解压?

经过压缩的文件仍然过大,大家可能都会选择“分卷压缩”来压缩ZIP文件,但是当我们将压缩包分卷之后,解压的时候该如何解压?今天我们分享两个ZIP分卷压缩包如何解压的方法给大家。 一、 我们可以直接点击第一个分卷压缩包&#xf…

DHC:用于类别不平衡的半监督医学图像分割的双重去偏异构协同框架

文章目录 DHC: Dual-Debiased Heterogeneous Co-training Framework for Class-Imbalanced Semi-supervised Medical Image Segmentation摘要方法Distribution-aware Debiased Weighting (DistDW)Difficulty-aware Debiased Weighting (DiffDW) 实验结果 DHC: Dual-Debiased He…

Context capture/Pix4Dmapper/AutoCAD/CASS/EPS软件的安装流程与使用方法;土方量计算;无人机摄影测量数据处理

目录 专题一 无人机摄影测量技术应用现状及其发展 专题二 基本原理和关键技术讲解 专题三 无人机影像外业数据获取 专题四 数据处理环境建立与软件熟悉 专题五 GNSS数据土方量计算 专题六 基于无人机影像数据的正射影像制作 专题七 基于无人机影像数据的三维模型制作 专…

TS流加扰的判断

一般情况下,1套节目是否加扰 在SDT表中或者包头的加扰位2处判断。 1.SDT表的free_CA_mode0是未加密,1是加密;在SDT表中,只是一个规范(如果节目加密了,应该让free_CA_mode1)。实际上&#xff0c…

燃气电力瓶装气行业入户安检小程序开发

我们开发的小区业主入户安检小程序,旨在满足燃气、电力以及其他需要入户安检的行业需求。该程序支持自定义安检项目,实现线下实地安检与线上数据保存的完美结合。在安检过程中,我们可以拍照或录像,以确保安检的透明性和可追溯性&a…

【C++】-【QT】类库使用-001

1主窗口创建 1.1【makefile】配置 1 源码 QT widgetsSOURCES main.cpp2 图示 1.2源码 1 源码 #include <QWidget> #include <QApplication>using namespace std;int main(int argc,char *argv[]) {QApplication a(argc,argv);QWidget w;w.show();return a…

应聘项目经理,软考证书会是一个加分项吗?

加分项是必需的&#xff0c;特别是IT行业的项目经理职位。您可以在各大招聘网站上搜索项目经理职位&#xff0c;前景好、薪资高、待遇好的项目经理岗位&#xff0c;基本上都有证书的要求。非IT行业项目经理&#xff0c;可以考虑PMP证书或者其他与专业相关的证书&#xff0c;比如…

Android 高版本实现沉浸式状态栏

目前实现的android高版本沉浸式状态栏分为两类&#xff1a; 1、是纯透明状态栏&#xff1b; 2、是纯透明状态栏&#xff0c;但是状态栏字体是黑色&#xff1b; 将状态栏的代码封装到BaseActivity中更方便使用&#xff1a; BaseActivity: public abstract class BaseActivit…

大模型微调实战之强化学习 贝尔曼方程及价值函数(一)

大模型微调实战之强化学习 贝尔曼方程及价值函数 强化学习&#xff08;RL&#xff09;是机器学习中一个话题&#xff0c;不仅在人工智能方面。它解决问题的方式与人类类似&#xff0c;我们每天都在学习并在生活中变得更好。 作为一名大模型学习者&#xff0c;当开始深入研究强…

校验--ECC详细分析

ECC介绍 ECC 以下是针对瑞萨MCU的应用的ECC检测的详细分析。 当前公认安全有效的三大类公钥密钥体制分别为基于大数因子分解难题(RSA)、离散对数难题(DSA)和椭圆曲线离散对数&#xff08;ECC&#xff09;难题的密码体制。 保证RSA的安全性&#xff0c;则必须要增加密钥长度…

【最优传输二十九】Wasserstein Barycenterand Its Application to Texture Mixing

motivation 本文提出了离散概率分布的平均作为Monge-Kantorovich最优传输空间重心的新定义。为了克服数值求解这类问题所涉及的时间复杂性&#xff0c;原始的Wasserstein度量被一维分布上的切片近似所取代。这使我们能够引入一种新的快速梯度下降算法来计算点云的Wasserstein质…

Cesium 问题:billboard 加载未出来

文章目录 问题分析问题 接上篇 Cesium 展示——图标的依比例和不依比例缩放,使用加载 billboard 时,怀疑是路径的原因导致未加载成功 分析 原先

初步了解Kubernetes

目录 1. K8S概述 1.1 K8S是什么 1.2 作用 1.3 由来 1.4 含义 1.5 相关网站 2. 为什么要用K8S 3. K8S解决的问题 4. K8S的特性 5. Kubernetes集群架构与组件 6. 核心组件 6.1 Master组件 6.1.1 Kube-apiserver 6.1.2 Kube-controller-manager 6.1.3 kube-schedul…

算法学习008-登山爬石梯 c++动态规划/递归算法实现 中小学算法思维学习 信奥算法解析

目录 C登山爬石梯 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、推荐资料 C登山爬石梯 一、题目要求 1、编程实现 小明周末和朋友约好了一起去爬山&#xff0c;来到山下&#xff0c;发现登山道是…

【问题实操】银河高级服务器操作系统实例分享,开机之后反复重启

1.服务器环境以及配置 物理机/虚拟机/云/容器 物理机 外网/私有网络/无网络 私有网络 处理器&#xff1a; PHYTIUM FT2000PLUS 2200 MHz 内存&#xff1a; 128 GiB 整机类型/架构&#xff1a; HIKVISION DS-V BIOS版本&#xff1a; HK 601FBE02HK 网卡&#xff1…

VTK数据的读写--Vtk学习记录1--《VTK图形图像开发进阶》

读和写操作是VTK可视化管线两端相关的类--Reader和Writer类 Reader:将外部数据读入可视化管线&#xff0c;主要步骤如下 s1:实例化Reader对象 s2:指定所要读取的文件名 s3:调用Update()促使管线执行 对应的Writer: s1:实例化Writer对象 s2输入要写的数据以及指定写入的文…

实习报告怎么写?笔灵AI实习体验报告模版分享:AI产品前端实习生

实习报告怎么写&#xff1f;笔灵AI实习体验报告模版可以帮你 点击即可使用&#xff1a;https://ibiling.cn/scene/inex?fromcsdnsx 下面分享AI产品前端实习生的实习报告 尊敬的导师和领导们&#xff1a;首先&#xff0c;我想对你们表达我的诚挚感谢&#xff0c;感谢你们给我…

暗区突围国际服pc端海外版如何快速致富 暗区突围pc端怎么赚钱

暗区突围是一款由腾讯魔方工作室研发的高拟真硬核射击手游&#xff0c;以现代战争为游戏题材&#xff0c;采用了全新的u3d引擎打造&#xff0c;整体游戏画风逼真写实&#xff0c;搭配上优秀的射击玩法&#xff0c;辅以史诗级的背景配乐&#xff0c;致力于带给玩家无与伦比的枪战…

“漫画之家”|基于Springboot+vue的“漫画之家”系统(源码+数据库+文档)

“漫画之家”系统 目录 基于Springbootvue的“漫画之家”系统 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2后台模块 5.2.1管理员功能模块 5.2.2用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&a…

linux代码实操——信号的使用

信号的基本概念 信号是系统响应某个条件而产生的事件&#xff0c;进程接收到信号会执行相应的操作。 与信号有关的系统调用在“signal.h”头文件中有声明 常见信号的值&#xff0c;及对应的功能说明&#xff1a; 修改信号的响应方式 – signal() 我们来做个小实验: 在键盘上…