本地电脑交叉编译ffmpeg 到 windows on arm64
我这里有编译好的win on arm 的 ffmpeg : https://github.com/wmx-github/ffmpeg-wos-arm64-build
使用 llvm-mingw 工具链 https://github.com/mstorsjo/llvm-mingw/releases
前缀 aarch64-w64-mingw32-
这个库是ubuntu 交叉编译的
在windows on arm 上开发使用,必须用llvm-mingw 工具链
参考ffmpeg官方文档:
https://trac.ffmpeg.org/wiki/CompilationGuide/CrossCompilingForWindows
参考:
https://github.com/BtbN/FFmpeg-Builds/issues/95
参考:
https://github.com/dvhh/ffmpeg-wos-arm64-build
docker镜像: llvm-mingw
https://hub.docker.com/r/mstorsjo/llvm-mingw/
1 拉取镜像运行容器
bash
docker run -it mstorsjo/llvm-mingw:latest
镜像选择:特别注意:
-
如果使用
mstorsjo/llvm-mingw:20230614
使用的编译工具是
LLVM 16.0.6
x264 执行 configure 传入参数
--extra-cflags="-mfpu=neon"
-
如果使用
mstorsjo/llvm-mingw:latest
目前2024年8月20 就是llvm-mingw 20240820
使用的编译工具是
LLVM 19.1.0
x264 执行 configure 传入参数
--extra-cflags="-march=armv8"
2 构建脚本
bash
root@0677f504e2da:/build# vi toolchain-llvm-mingw.cmake
toolchain-llvm-mingw.cmake 填入 :
bash
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER "aarch64-w64-mingw32-gcc")
set(CMAKE_CXX_COMPILER "aarch64-w64-mingw32-g++")
然后 Esc ,输入 :wq 回车保存
3 编译SDL
bash
root@0677f504e2da:/build# git clone https://github.com/libsdl-org/SDL.git
root@0677f504e2da:/build/ cd SDL
root@0677f504e2da:/build/SDL#
bash
cmake -S . -B build \
-DCMAKE_TOOLCHAIN_FILE=/build/toolchain-llvm-mingw.cmake \
-DCMAKE_INSTALL_PREFIX=/build/install
bash
root@0677f504e2da:/build/SDL# cmake --build build
root@0677f504e2da:/build/SDL# cmake --install build
查看格式:
bash
root@0677f504e2da:/build/SDL# file /build/install/bin/SDL2.dll
/build/install/bin/SDL2.dll: PE32+ executable (DLL) (GUI) Aarch64, for MS Windows
配置SDL 相关路径,使得pkgconfig能找到SDL
bash
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/build/install/lib/pkgconfig
配置sdl2-config
bash
ln -s /build/install/bin/sdl2-config /usr/local/bin/aarch64-w64-mingw32-sdl2-config
chmod +x /build/install/bin/sdl2-config /usr/local/bin/aarch64-w64-mingw32-sdl2-config
export PATH=$PATH:/usr/local/bin
4 编译x264
bash
root@0677f504e2da:/build# git clone --depth=1 https://code.videolan.org/videolan/x264.git x264
root@0677f504e2da:/build# cd x264
root@0677f504e2da:/build/x264#
配置
bash
./configure \
--host=aarch64-w64-mingw32 \
--cross-prefix=aarch64-w64-mingw32- \
--prefix=/build/install \
--enable-pic \
--extra-cflags="-march=armv8" \
--enable-shared \
--enable-static
编译安装
bash
root@0677f504e2da:/build/x264#``make -j12 && make install
5 编译FFmpeg
bash
root@0677f504e2da:/build# git clone https://github.com/FFmpeg/FFmpeg.git
root@0677f504e2da:/build# cd FFmpeg/
root@0677f504e2da:/build/FFmpeg#
bash
./configure --pkg-config=/usr/bin/pkg-config \
--pkgconfigdir=/build/install/lib/pkgconfig \
--cross-prefix=aarch64-w64-mingw32- \
--arch=arm64 \
--target-os=mingw32 \
--prefix=/build/install \
--enable-gpl \
--enable-nonfree \
--disable-doc \
--disable-static \
--enable-shared \
--enable-sdl \
--enable-libx264
./configure 输出:
bash
Enabled outdevs:
sdl2
bash
root@0677f504e2da:/build/FFmpeg# make -j12
查看格式:
bash
root@0677f504e2da:/build/FFmpeg# file ./ffmpeg.exe
./ffmpeg.exe: PE32+ executable (console) Aarch64, for MS Windows
6 copy 到win on arm64 电脑上
bash
(base) wmx@wmx-ubuntu:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0677f504e2da mstorsjo/llvm-mingw:latest "/bin/bash" 14 hours ago Up 7 hours friendly_goldstine
复制到本机
bash
docker cp 0677f504e2da:/build/install ./ffmpeg
把 ./ffmpeg 复制到win on arm64 电脑上测试
7 测试
系统:windows on arm
cpu: aarch64
动态库测试
build.bat
bash
@echo off
set LLVM_MINGW_PATH=C:\workspace\llvm-mingw-20240820-ucrt-aarch64
set FFMPEG_PATH=C:/workspace/ffmpeg-6.1\lib
set INCLUDE_PATH=C:/workspace/ffmpeg-6.1\include
%LLVM_MINGW_PATH%\bin\clang -o ffmpeg_test_dynamic.exe main.c -I %INCLUDE_PATH% -L %FFMPEG_PATH% -lavcodec -lavformat -lavutil
pause
main.c
c
#include <stdio.h>
#include <libavcodec/avcodec.h>
int main() {
printf("FFmpeg version: %s\n", av_version_info());
return 0;
}
在windows cmd.exe下运行 build.bat 生成 ffmpeg_test_dynamic.exe
把ffmpeg库文件copy到ffmpeg_test_dynamic.exe路径:
bash
C:\workspace\test_ffmpeg>dir |findstr dll
2024/09/04 15:46 11,254,784 avcodec-60.dll
2024/09/04 15:46 135,168 avdevice-60.dll
2024/09/04 15:46 3,683,328 avfilter-9.dll
2024/09/04 15:46 2,167,296 avformat-60.dll
2024/09/04 15:46 678,400 avutil-58.dll
2024/09/04 15:46 44,032 postproc-57.dll
2024/09/04 17:46 2,969,088 SDL2.dll
2024/09/04 15:46 95,744 swresample-4.dll
2024/09/04 15:46 584,192 swscale-7.dll
运行:
bash
C:\workspace\test_ffmpeg>ffmpeg_test_dynamic.exe
FFmpeg version: n6.1
静态链接测试
build_static.bat
bash
@echo off
set LLVM_MINGW_PATH=C:\workspace\llvm-mingw-20240820-ucrt-aarch64
set FFMPEG_PATH=C:/workspace/ffmpeg-6.1\lib
set INCLUDE_PATH=C:/workspace/ffmpeg-6.1\include
%LLVM_MINGW_PATH%\bin\clang -o ffmpeg_test_static.exe main.c -I %INCLUDE_PATH% -L %FFMPEG_PATH% -lavcodec -lavformat -lavutil -static
pause
cmd.exe 下运行 build_static.bat 生成 ffmpeg_test_static.exe ,运行:
bash
C:\workspace\test_ffmpeg>ffmpeg_test_static.exe
FFmpeg version: n5.1
msvc 编译测试
buid_msvc.bat
bash
@echo off
REM 配置路径
set FFMPEG_PATH=C:\workspace\ffmpeg-6.1\lib
set INCLUDE_PATH=C:\workspace\ffmpeg-6.1\include
REM 初始化 MSVC 环境,针对 ARM64
::call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" arm64
REM 编译 main.c 文件,链接 FFmpeg 库
cl /I %INCLUDE_PATH% main.c /Feffmpeg_msvc.exe /link /LIBPATH:%FFMPEG_PATH% avcodec.lib avformat.lib avutil.lib
pause
打开窗口 ARM64 Native Tools Command Prompt for VS 2022
bash
C:\workspace\test_ffmpeg>build_msvc.bat
用于 ARM64 的 Microsoft (R) C/C++ 优化编译器 19.41.34120 版
版权所有(C) Microsoft Corporation。保留所有权利。
main.c
Microsoft (R) Incremental Linker Version 14.41.34120.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:ffmpeg_msvc.exe
/LIBPATH:C:\workspace\ffmpeg-6.1\lib
avcodec.lib
avformat.lib
avutil.lib
main.obj
Press any key to continue . . .
C:\workspace\test_ffmpeg>ffmpeg_msvc.exe
FFmpeg version: n6.1
C:\workspace\test_ffmpeg>
附录
-mfpu=neon
是一个编译选项,用于指定在 ARM 处理器上使用哪种浮点运算单元 (FPU, Floating Point Unit)。neon
是 ARM 的高级 SIMD (Single Instruction Multiple Data) 指令集扩展,通常用于加速多媒体、信号处理和矩阵运算等高性能计算任务。
具体含义:
-mfpu
:用于指定 ARM 处理器的浮点运算单元类型。neon
:指的是 ARM 的 NEON 指令集,这是一种 SIMD 扩展,允许一次处理多个数据元素。它可以在同一指令周期内对多个数据点执行相同的运算,从而显著提高处理效率。
NEON 的特点:
- 并行处理:NEON 可以并行处理 64 位或 128 位的数据,从而加速计算。
- 应用场景:常用于图像处理、信号处理、音频解码等多媒体应用。
- 架构支持:通常在 ARMv7 和更高版本的处理器上支持(例如 Cortex-A 系列)。
使用场景:
当编译针对 ARM 处理器的程序时,-mfpu=neon
可以启用 NEON 指令集优化,提升性能,特别是在处理矢量运算、矩阵操作、图像处理等任务时。并非所有 ARM 处理器都支持 NEON,必须确保目标设备的处理器支持 NEON 扩展。aarch64
架构默认支持 NEON,因此在 64 位 ARM 系统中,通常不需要显式指定 -mfpu=neon
。