ffmpeg4.1 Android arm64位库裁剪移植

目录

                           ffmpeg4.1 Android arm64位库裁剪移植

1、绪言:

2、编译环境:

3、源代码下载:

4、编写编译脚本:

4.1 编译脚本

4.2 常见问题

5、库裁剪:

5.1 裁剪原理

5.2 裁剪方法

5.3 编译配置脚本

5.4 裁剪结果

6、引用


1、绪言:

ffmpeg是一个很强大的多媒体开源框架,几乎所有的音视频播放、编辑软件都用到,如抖音、斗鱼、学习强国等。因为他的强大所以造就了他的复杂。手头有个项目刚好需要用到ffmpeg。

google将在2019年8月份强制要求所有Android设备支持64位的库,之前32位的库可以很好的兼容64位的手机,很快所有含有jni库的APP都要支持起来。姑且不论中美贸易战结果如何,华为等手机是否放弃android。

鉴于上述原因,所以要重新编译裁剪ffmpeg,在这个过程中遇到了一些问题顺便记录下来。

2、编译环境:

操作系统:ubuntu 14.04

交叉编译工具:android-ndk-r14b

Android NDK 下载地址

这里推荐使用ubuntu而不是用cygwin,因为ffmpeg是C语言,编译脚本是MakeFIle,很多文件对空格换行等其他字符编码敏感。

 

3、源代码下载:

下载地址:
(1) ffmpeg官网下载地址 (2)github上FFmpeg的下载地址

4、编写编译脚本:

4.1 编译脚本

在编译之前需要配置很多项,最基本的配置是要:

(1)指定工具链;

(2)一些target-os的头文件;

(3)输出的路径;

(4)输出的可执行程序和库;

这些内容是通过根目录下的configure脚本配置的,因为配置项比较多所以最好写成一个脚本。下面是一个简单例子:

#!/bin/bash
API=14
NDK=/NDK安装位置/android-ndk-r14b
SYSROOT=$NDK/platforms/android-$API/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
function build_one
{
./configure \
  --prefix=$PREFIX \
  --disable-shared \
  --enable-static \
  --cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
  --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
  --target-os=linux \
  --arch=arm \
  --enable-cross-compile \
  --sysroot=$SYSROOT \
  --extra-cflags="-fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm -march=armv8-a" \
  --enable-neon

make clean all
make 
make install
}
CPU=armv64
PREFIX=$(pwd)/android/$CPU
build_one

在根目录下新建一个文件build_android.sh,将上述脚本文本复制到这个脚本中

chmod a+x build_android.sh

4.2 常见问题

(1) 这个过程中一般会遇到一些comand not found的问题,

导致原因及解决办法:

a、脚本在Windows系统下生成。这类问题可一在linux 下执行doc2unix build_android.sh;

b、主要是上述脚本中在有不合法的空格,如:“--prefix=$PREFIX \    ”后面有空格。这个需要删除空格;

c、在configure 配置项中有#注释的类容。configure是一条命令,后面都是参数,参数之间不能注释,否则无法解析。

 

(2)configure会在编译之前检验编译器是否正确如图4-1。当target-os=android时候,ffmpeg选择clang编译器,但是在ndk的交叉工具链中没有aarch64-linux-android-clang。


android media api 视频裁剪 android 视频裁剪框架_ffmpeg

图4-1 编译器错误

 解决办法:修改configure如下

set_default target_os
if test "$target_os" = android; then
    #cc_default="clang"
    cc_default="gcc"
fi

关于其他的一些配置问题,通过看ffbuild/config.log和configure脚本都可以找到解决办法。

 

5、库裁剪:

5.1 裁剪原理

ffmpeg裁剪就是把ffmpeg中你不需要用到的逻辑在编译时候去掉,每个项目的需求都不尽相同,所以完成这个工作的前提是要对自己项目业务有足够的了解,并且也要清楚ffmpeg处理的逻辑。

FFmpeg是一套可以用来记录、转换、分析处理数字音频、视频,并能将其转化为流或文件的跨平台开源计算机程序。ffmpeg常用的多媒体编解码处理方面,处理流程如图5-1.


android media api 视频裁剪 android 视频裁剪框架_arm64_02

图5-1 ffmpeg编解码流程图

按照蓝色箭头指向的顺序,从外部协议接收下来的数据依次经过解协议,解封装,解码,像素转换,编码,封装,发送这几个步骤。这些步骤按照处理数据类型的不同,可以分成几个层次:

    协议层(Protocol Layer):该层处理的数据为符合特定流媒体协议规范的数据,例如http,rtmp,file等。
    封装层(Container Layer):该层处理的数据为符合特定封装格式规范的数据,例如mkv,mp4,flv,mpegts,avi等。
    编码层(Codec Layer):该层处理的数据为符合特定编码标准规范的数据,例如h264,h265,mpeg2,mpeg4等。
    像素层(Pixel Layer):该层处理的数据为符合特定像素格式规范的数据,例如yuv420p,yuv422p,yuv444p,rgb24等。

由于多媒体协议格式复杂,所以强大的ffmpeg在以上各层都支持了很多,ffmpeg裁剪就是把上面不需要支持的协议格式在编译时候禁用。

5.2 裁剪方法

在ffmpeg根目录下执行:

./configure --help

 可以看到很多配置项,裁剪的具体方法就是依次按照上面四层设置启用/禁用这些配置项。这里以decoder配置为例介绍一下:

..
--disable-decoders \
--enable-decoder=aac \
--enable-decoder=flv \
--enable-decoder=h264 \
--enable-decoder=mp3* \
--enable-decoder=hevc \
..

首先通过--disable-decoders 禁用所有解码器,然后依次启用你所需要的解码器。协议层,封装层、像素层都是类似的配置。

关于configure 的配置项一些中文翻译可以参考ffmpeg裁剪。

5.3 编译配置脚本

下面是我完成版裁剪配置编译脚本,可按照第4章方法添加到工程。

#!/bin/bash 
# build_android.sh
NDK=/home/xxx/Android/android-ndk-r14b


function build_android {
 echo "Compiling FFmpeg for $CPU" 
./configure \
--prefix=$PREFIX \
--enable-neon \
--enable-shared \
--enable-jni \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--disable-static \
--disable-doc \
--enable-small \
--disable-gpl   \
--disable-programs \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver \
--disable-filters \
--disable-avdevice \
--disable-network \
--disable-zlib \
--disable-bsfs \
--disable-muxers \
--enable-muxer=mp4 \
--disable-demuxers \
--disable-decoders \
--enable-decoder=aac \
--enable-decoder=flv \
--enable-decoder=h264 \
--enable-decoder=mp3* \
--enable-decoder=hevc \
--disable-encoders \
--enable-encoder=png \
--enable-encoder=jpeg2000 \
--enable-encoder=mpeg4 \
--enable-version3 \
--cross-prefix=$CROSS_PREFIX \
--sysroot=$SYSROOT \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--enable-cross-compile \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS " \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
echo "configure finished"
make clean 
make -j4
make install 

}

#arm64-v8a 
ARCH=arm64
CPU=armv8-a 
TOOLCHAIN=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64
SYSROOT=$NDK/platforms/android-21/arch-arm64/ 
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android- 
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"

#armeabi-v7a 
ARCH=arm
CPU=armv7-a 
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
SYSROOT=$NDK/platforms/android-19/arch-arm/
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-marm"
export TMPDIR=$(pwd)/temp
build_android

 当执行以上脚本时会在终端输出配置结果如图5-2,这个结果和脚本中一致。


android media api 视频裁剪 android 视频裁剪框架_ffmpeg_03

图5-2 裁剪库配置结果

5.4 裁剪结果

运行第4章脚本和5.3章脚本库大小结果对比如图5-3.


android media api 视频裁剪 android 视频裁剪框架_编译_04

图5-3 库裁剪前后大小对比

6、引用

https://www.jianshu.com/p/9ee83933009a