rk平台(rv1126/rk3588)音视频-交叉编译FFmpeg7.1

本文优势:

  1. 最新的ffmpeg7.x版本

  2. 支持x264,fdk-aac,mp3,https

  3. 提供gitee相关的源码链接,更方便下载源码

对应视频: RK平台(rv1126/rk3588)嵌入式音视频-交叉编译ffmpeg7.1

1 编译环境

Ubuntu 20.04:直接使用了正点原子开发板提供的镜像

交叉编译工具链:atk-dlrv1126-toolchain

编译第三方库:

编译FFmpeg7.1 (当前最新稳定版本) https://gitee.com/qingfuliao/ffmpeg.git

PS: GitHub源码不稳定,我都导入到gitee了,如果需要原始连接看gitee的说明。

2 创建目录

在home目录下创建

  • ffmpeg7.1_sources:用于下载源文件(同样的源码可以编译arm版本/x86版本,这里我们只编译arm版本)

  • ffmpeg7.1_arm_build: 存储编译后的库文件

  • ffmpeg7.1_arm_bin:存储二进制文件(ffmpeg, ffprobe,x264等)

    cd ~ mkdir ffmpeg7.1_sources ffmpeg7.1_arm_build ffmpeg7.1_arm_bin

3 编译与安装第三方库

3.1 libx264

H.264视频编码器。更多信息和使用范例参考H.264 Encoding Guide

要求编译ffmpeg时配置:--enable-gpl --enable-libx264.

使用源码进行编译:

复制代码
$ cd ~/ffmpeg7.1_sources
$ git clone https://gitee.com/qingfuliao/x264.git
#进⼊x264⽬录
$ cd x264 
#切换到稳定的版本
$ git checkout stable

#配置环境变量并配置libx264编译
$ ./configure --prefix="$HOME/ffmpeg7.1_arm_build" --bindir="$HOME/ffmpeg7.1_arm_bin" --disable-asm --enable-shared --enable-pic --host=arm-linuxgnueabi --cross-prefix=/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf-

# 编译(这⾥设置4线程编译更快)
$ make -j4
# 安装到ffmpeg7.1_arm_build和ffmpeg7.1_arm_bin⽬录
$ make install

配置参数解析:

**--prefix="HOME/ffmpeg7.1_arm_build"**这是指定安装目录的参数。 prefix 选项告诉configure 脚本将编译后的文件安装到 HOME/ffmpeg7.1_arm_build 目录下。这个目录将包含所有最终安装的头文件、库文件和可执行文件等。例如,头文件可能会安装到 HOME/ffmpeg7.1_arm_build/include ,库文件安装到HOME/ffmpeg7.1_arm_build/lib ,可执行文件安装到 $HOME/ffmpeg7.1_arm_build/bin 等。

**--bindir="HOME/ffmpeg7.1_arm_bin"** 用于指定可执行文件的安装目录。这里会将编译生成的 x264 相关可执行文件安装到 HOME/ffmpeg7.1_arm_bin 目录。与 --prefix 参数指定的目录可以相互配合, --bindir 可以覆盖 --prefix 中对可执行文件安装目录的默认设置。

--disable-asm这个参数用于禁用汇编优化。通常,x264 可以利用汇编语言来对某些关键的编码操作进行优化,以提高性能。但是,在某些情况下,比如目标平台的汇编指令集不支持或者为了简化编译过程、提高代码的可移植性,就会选择禁用汇编优化。

  • 当交叉编译到一些不常见的或者资源受限的 ARM 架构设备上,而编译器对目标设备的汇编支持不完善时,禁用汇编优化可以确保编译过程顺利进行。

--enable-shared 启用共享库的构建。共享库( .so 文件)可以在多个程序之间共享,减少内存占用和磁盘空间。当一个程序使用共享库时,它在运行时加载库的代码,多个程序可以共享同一份库的代码在内存中,而不是每个程序都有自己的一份静态库副本。

--enable-pic PIC 代表位置无关代码(Position-Independent Code)。启用这个选项后,生成的代码可以在内存的任何位置正确地执行。这对于共享库的构建非常重要,因为共享库在不同的程序中可能会被加载到不同的内存位置。

--host = arm-linux-gnueabi 这个参数指定了目标主机系统的类型。在这里,它表明是为 arm-linux-gnueabi 架构的系统进行编译。 configure 脚本会根据这个目标主机的架构和系统类型来设置合适的编译选项,比如选择合适的编译器、链接器和库路径等

--cross-prefix=/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf - 用于指定交叉编译工具链前缀的参数。交叉编译工具链是一组用于在一个平台上编译另一个平台软件的工具。这个前缀指定了工具链中各种工具(如编译器 gcc 、链接器 ld 等)的路径和名称前缀。在这个例子中, arm-linux-gnueabihf - 前缀表示使用的是 arm-linux-gnueabihf 工具链相关的工具。

3.2 libfdk-aac

AAC音频编码器. 更多信息和使用范例参考AAC Audio Encoding Guide

要求编译ffmpeg时配置:--enable-libfdk-aac ( 如果你已经配置了 --enable-gpl则需要加上--enable-nonfree)。

使用源码进行编译:

复制代码
$ cd ~/ffmpeg7.1_sources 
# 下载fdk-aac
$ git clone https://gitee.com/qingfuliao/fdk-aac.git
$ cd fdk-aac
# 切换到稳定版本
$ git checkout v2.0.3

为了不破坏原始的CMakeList结构,可以直接在fdk-aac文件夹下创建一个arm_linux_setup.cmake文件,

在cmake编译时加载该配置文件即可。arm_linux_setup.cmake文件内容如下:

复制代码
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(tools /opt/atk-dlrv1126-toolchain)
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)

其中gcc-arm-linux-gnueabihf为自己的交叉编译工具链位置,可自行替换。

复制代码
$ mkdir build
$ cd build
$ cmake -DCMAKE_TOOLCHAIN_FILE=../arm_linux_setup.cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg7.1_arm_build" -DCMAKE_INSTALL_BINDIR="$HOME/ffmpeg7.1_arm_bin"

# 编译和安装
$ make -j4
$ make install

配置参数说明:

-DCMAKE_TOOLCHAIN_FILE=../arm_linux_setup.cmake 参数

  • -D 选项是 CMake 中用于定义变量的参数。在这里,它用于指定一个 CMake 变量。

  • CMAKE_TOOLCHAIN_FILE 是 CMake 中的一个内置变量,用于指定工具链文件的路径。

  • ../arm_linux_setup.cmake 是工具链文件的具体路径。这个文件通常包含了针对特定平台(这里是 ARM Linux)的编译选项和设置。

DCMAKE_BUILD_TYPE=Release 表示编译release版本(因为这个库不需要debug,可以编译为release)

-DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg7.1_arm_build"

  • -D 是 CMake 命令中的选项,用于定义一个 CMake 变量。

  • CMAKE_INSTALL_PREFIX 是 CMake 中的一个重要变量。这个变量指定了项目构建完成后,安装文件的目标路径前缀。

  • "HOME/ffmpeg7.1_arm_build" 是具体的安装路径。这里使用了环境变量 HOME 来指定用户的主目录,再加上特定的路径 ffmpeg7.1_arm_build 。

DCMAKE_INSTALL_BINDIR="$HOME/ffmpeg7.1_arm_bin" CMAKE_INSTALL_BINDIR 是CMake 中的一个特定变量,用于指定可执行文件的安装目录,可以覆盖 CMAKE_INSTALL_PREFIX 中对可执行文件安装目录的默认设置。

3.3 libmp3lame

MP3音频编码器.

要求编译ffmpeg时配置:--enable-libmp3lame.

复制代码
$ cd ~/ffmpeg7.1_sources 

# 1. 下载源码
$ git clone https://gitee.com/qingfuliao/lame.git

# 2. 进入源码
$ cd lame
# 3. 选择一个release版本
$ git checkout 3.100.r3706-2

修改configure,把-msse2删除,

复制代码
# 4. 配置交叉编译
$ ./configure --host=arm-linux-gnueabihf CC=/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf-gcc --prefix="$HOME/ffmpeg7.1_arm_build" --bindir="$HOME/ffmpeg7.1_arm_bin" 

# 5. 编译
$ make -j4

# 6. 安装
$ make install

参数说明:

  • CC=/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf-gcc 配置编译器

3.4 安装opensll

复制代码
$ cd ~/ffmpeg7.1_sources 
$ git clone https://gitee.com/qingfuliao/openssl.git

$ cd openssl
# 选择适合的版本
$ git checkout remotes/origin/OpenSSL_1_1_1-stable
#配置路径
$ ./config no-asm shared no-async --prefix="$HOME/ffmpeg7.1_arm_build" --bindir="$HOME/ffmpeg7.1_arm_bin" --cross-compile-prefix=/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf-
# 配置后要收到修改Makefile

之后,打开Makefile,删除里面所有的-m64和-m32编译选项。

复制代码
# 编译和安装
$ make -j4
$ make install

参数说明:

--cross-compile-prefix=/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf- :

  • 作用:指定交叉编译工具链的前缀。在进行交叉编译时,需要使用特定的工具链来为不同的架构和平台编译软件。这个参数告诉 OpenSSL 的编译系统使用 /opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf- 作为交叉编译工具链的前缀,以便找到正确的编译器、链接器等工具。

no-async :

  • 作用:禁止异步操作。异步操作通常用于提高性能,允许程序在等待某些操作完成时继续执行其他任务。禁止异步操作可能是因为在特定的环境中不需要或者不支持异步操作。

  • 应用场景:如果目标系统资源有限或者对实时性要求不高,可以禁用异步操作以简化代码和减少复杂性。例如,在一些嵌入式系统中,可能不需要复杂的异步操作,以节省资源和提高稳定性。

no-asm :

  • 作用:禁用汇编代码生成。在某些情况下,可能由于目标平台不支持特定的汇编指令集或者为了提高可移植性,选择禁用汇编优化。

4 编译ffmpeg7.1

4.1 下载/编译/安装ffmpeg

复制代码
$ cd ~/ffmpeg7.1_sources
# 我码云提供的连接是最新到7.1的版本
$ git clone https://gitee.com/qingfuliao/ffmpeg.git
$ cd ffmpeg
# 选择稳定的release版本,如果选择默认的master版本,可能有奇怪的异常问题
$ git checkout remotes/origin/release/7.1

配置FFmpeg,下面内容是一条命令

复制代码
PKG_CONFIG_PATH="$HOME/ffmpeg7.1_arm_build/lib/pkgconfig" ./configure --enable-cross-compile --target-os=linux --cc=/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf-gcc --strip=/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf-strip --arch=arm --prefix="$HOME/ffmpeg7.1_arm_build" --bindir="$HOME/ffmpeg7.1_arm_bin" --enable-ffmpeg --enable-shared --disable-static --enable-pic \
 --extra-cflags="-I$HOME/ffmpeg7.1_arm_build/include" \
 --extra-ldflags="-L$HOME/ffmpeg7.1_arm_build/lib" \
 --extra-cflags="-I/opt/atk-dlrv1126-toolchain/arm-buildroot-linux-gnueabihf/sysroot/usr/include" \
 --extra-ldflags="-L/opt/atk-dlrv1126-toolchain/arm-buildroot-linux-gnueabihf/sysroot/usr/lib" \
 --extra-libs="-lpthread -lm" \
 --enable-gpl \
 --enable-libfdk-aac \
 --enable-libmp3lame \
 --enable-libx264 \
 --enable-pic \
 --enable-shared \
 --enable-openssl \
 --enable-nonfree \
 --enable-debug=3 \
 --disable-optimizations \
 --disable-stripping

# 然后编译和安装
$ make -j4
$ make install
# 安装后头⽂件在$HOME/ffmpeg7.1_arm_build/include
# 库⽂件在$HOME/ffmpeg7.1_arm_build/lib

注意:这里arch选择arm,因为aarch64 是armv8的指令集,当前rv1126是armv7的指令集,如果配置 aarch64会造成汇编指令报错。

  • --enable-gpl: 启用GPL许可证,这允许使用GPL许可证下的代码。启用此选项将允许编译包含GPL许可证的代码,但是也意味着生成的FFmpeg库或工具可能受到GPL许可证的限制。

  • enable-nonfree: 启用非自由(非自由许可证)功能。如果需要使用一些不受自由许可证的代码或功能,则需要启用此选项。启用此选项可能会导致生成的FFmpeg库或工具包含一些受限制的功能。

  • --enable-debug=3: 启用调试模式,级别为3。这将使得生成的可执行文件包含更多的调试信息,以帮助诊断问题。

  • --disable-optimizations: 禁用优化。通常,编译器会对代码进行优化以提高执行速度或减少生成的可执行文件的大小。禁用优化意味着生成的可执行文件可能会执行得更慢或更大,但也可能更容易调试和理解。

  • --disable-stripping: 禁用剥离。剥离是指从生成的可执行文件中移除调试符号和其他不必要的信 息,以减小文件大小。禁用剥离可以保留这些信息,使得生成的可执行文件更容易调试。

我们编译debug版本,主要是为了学习时方便调试。

--extra-cflags="-I/opt/atk-dlrv1126-toolchain/arm-buildroot-linux-gnueabihf/sysroot/usr/include"

--extra-ldflags="-L/opt/atk-dlrv1126-toolchain/arm-buildroot-linux-gnueabihf/sysroot/usr/lib"

目的是alsa相关的头文件在这个目录,如果要编译支持alsa需要找到对应的头文件和库文件。

  • --cc 指定编译器 (交叉编译时指定交叉编译器)

  • --arch=arm 指定芯片架构(交叉编译时指定芯片类型)

4.2 查看库文件情况

make install后,对应的目录:

库文件目录:$HOME/ffmpeg7.1_arm_build/lib

头文件目录:$HOME/ffmpeg7.1_arm_build/include

执行文件目录:$HOME/ffmpeg7.1_arm_bin

我们可以使用readelf -h 命令查看执行文件或者库文件是否是arm架构,比如

复制代码
alientek@ubuntu:~/ffmpeg7.1_arm_bin$ readelf -h ffmpeg
ELF 头:
 Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
 类别: ELF32
 数据: 2 补码,⼩端序 (little endian)
 Version: 1 (current)
 OS/ABI: UNIX - System V
 ABI 版本: 0
 类型: EXEC (可执⾏⽂件)
 系统架构: ARM
 版本: 0x1
 入口点地址: 0x17838
 程序头起点: 52 (bytes into file)
 Start of section headers: 1292876 (bytes into file)
 标志: 0x5000400, Version5 EABI, hard-float ABI
 Size of this header: 52 (bytes)
 Size of program headers: 32 (bytes)
 Number of program headers: 9
 Size of section headers: 40 (bytes)
 Number of section headers: 39
 Section header string table index: 38

系统架构: ARM 即是ARM架构(x86上交叉编译)

4.3 把库文件和执行文件拷贝开发板

拷贝内容:

库文件:$HOME/ffmpeg7.1_arm_build/lib的库文件,这里姑且先把动态库/静态库都拷贝到开发板上,做产品时可以按需求拷贝和裁剪;

执行文件:$HOME/ffmpeg7.1_arm_bin的ffmpeg和ffprobe拷贝到开发板

通过adb将库文件和执行文件发送给开发板:

复制代码
# 发送库⽂件给开发板
alientek@ubuntu:~$ adb -s 20240802RV1126FD2G009C push $HOME/ffmpeg7.1_arm_build/lib /home/ffmpeg7.1_arm_build/lib

参数说明:

  • $HOME/ffmpeg7.1_arm_build/lib 为Ubuntu主机的交叉编译后的库文件路径

  • /home/ffmpeg7.1_arm_build/lib 为开发板的路径

    发送执行文件给开发板

    发送ffmpeg执行文件

    alientek@ubuntu:~ adb -s 20240802RV1126FD2G009C push HOME/ffmpeg7.1_arm_bin/ffmpeg /home/ffmpeg7.1_arm_build/lib/

    发送ffprobe执行文件

    alientek@ubuntu:~ adb -s 20240802RV1126FD2G009C push HOME/ffmpeg7.1_arm_bin/ffprobe /home/ffmpeg7.1_arm_build/lib/

4.4 测试命令是否正常

adb shell模式下操作开发板

在adb的shell 进入 /home/ffmpeg7.1_arm_build/lib/目录

复制代码
# 执行当前目录的ffmpeg命令(注意rv1126本身是有带了4.1.3的ffmpeg)
[root@ATK-DLRV1126:/home/ffmpeg7.1_arm_build/lib]# ./ffmpeg -version
可以看到这里打印我们编译的7.1版本
ffmpeg version n7.1-14-g87ccf995cb Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 8.3.0 (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)
configuration: --enable-cross-compile --target-os=linux --cc=/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf-gcc --strip=/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf-strip --arch=arm --prefix=/home/alientek/ffmpeg7.1_arm_build --bindir=/home/alientek/ffmpeg7.1_arm_bin --enable-ffmpeg--enable-shared --disable-static --enable-pic --extra-cflags=-I/home/alientek/ffmpeg7.1_arm_build/include --extra-ldflags=-L/home/alientek/ffmpeg7.1_arm_build/lib --extra-cflags=-I/opt/atk-dlrv1126-toolchain/arm-buildrootlinux-gnueabihf/sysroot/usr/include --extra-ldflags=-L/opt/atk-dlrv1126-toolchain/arm-buildroot-linux-gnueabihf/sysroot/usr/lib --extra-libs='-lpthread -lm' --enable-gpl --enable-libfdk-aac --enable-libmp3lame --enable-libx264 --enable-pic --enable-shared --enable-openssl --enable-nonfree --enable-debug=3 --disable-optimizations --disable-stripping
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.100 / 61. 19.100
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100

4.5 测试录音

adb shell模式下操作开发板

注意是执行程序的路径,我们是使用自己编译的ffmpeg命令,

复制代码
[root@ATK-DLRV1126:/home/ffmpeg7.1_arm_build/lib]# ./ffmpeg -f alsa -i default:CARD=rockchiprk809co out.wav

录制十来秒后CTRL +c 退出录制,使用aplay播放out.wav文件。

复制代码
[root@ATK-DLRV1126:/home/ffmpeg7.1_arm_build/lib]# aplay out.wav

4.6 直播推流测试

adb shell模式下操作开发板

复制代码
[root@ATK-DLRV1126:/home/ffmpeg7.1_arm_build/lib]# ./ffmpeg -f v4l2 -pix_fmt yuv420p -i /dev/video45 -f alsa -i default:CARD=rockchiprk809co -g 30 -c:v libx264 -preset ultrafast -tune zerolatency -c:a aac -f flv rtmp://114.215.111.66/live/rv1126

参数说明:

  • -i /dev/video45 这个是我插入的usb摄像头的设备名

  • -i default:CARD=rockchiprk809co 是默认的录音设备,不要设置错了,否则没有声音。

  • 编码视频用h264,音频用aac,后续可以考虑视频用硬件编码。

拉流:可以使用ffplay命令

复制代码
ffplay -vf "hflip" rtmp://114.215.111.66/live/rv1126 -fflags nobuffer

5 更多测试

可以小破站搜索 程序员老廖 获取更多音视频相关的知识。

比如gb28181 onvif rtsp相关的知识,rv1126硬件编码相关的知识等等。

相关推荐
mixboot9 分钟前
FFmpeg 图片处理
ffmpeg
Gappsong87434 分钟前
Rufus:Ubuntu U盘启动盘制作工具详解
linux·c++·web安全·网络安全
Kira Skyler2 小时前
c++,从汇编角度看lambda
汇编·c++
Algebraaaaa2 小时前
C++ 多线程中成员函数如何传参?拷贝、引用还是指针?
开发语言·c++
程序员编程指南2 小时前
Qt开发环境搭建全攻略(Windows+Linux+macOS)
linux·c语言·c++·windows·qt
Aurora_wmroy4 小时前
算法竞赛备赛——【图论】求最短路径——Bellman-Ford & SPFA
数据结构·c++·算法·蓝桥杯·图论
刚入坑的新人编程5 小时前
暑假算法训练.6
数据结构·c++·算法·哈希算法
cccyi75 小时前
c++-string
c++·string
lxmyzzs5 小时前
从 0 到 1 搞定nvidia 独显推流:硬件视频编码环境安装完整学习笔记
笔记·学习·音视频
南通SEO5 小时前
CentOS 7安装 FFmpeg问题可以按照以下步骤进行安装
linux·ffmpeg·centos