RK3588 baresip AEC3 交叉编译与配置指南

RK3588 baresip AEC3 交叉编译与配置指南

组件:webrtc-audio-processing 1.3(AEC3)+ baresip 4.12.0(webrtc_aec 模块)
平台:RK3588 (aarch64),工具链 gcc-arm-10.3-2021.07(aarch64-none-linux-gnu)
验证环境:Ubuntu 22.04 VM(hunter@192.168.159.128),2026-10-10 全流程实测通过
路径约定:

  • SDK 根:/home/hunter/rk3588/rk3588_6.1_2025-02-26
  • baresip 工程:/home/hunter/rk3588/baresip-arm64(deps/ = 交叉依赖安装前缀)
  • overlay:SDK/buildroot/board/rockchip/rk3588/fs-overlay

0. 组件关系与产物清单

baresip (STATIC) ──链接──> libwebrtc-audio-processing-1.so.3   (AEC3,自包含)
                                  └── 静态内嵌 abseil-cpp 20230125.1(不会以 .so 形式出现)
产物 路径 说明
AEC3 库 deps/lib/libwebrtc-audio-processing-1.so.3 soname libwebrtc-audio-processing-1.so.3
AEC3 头文件 deps/include/webrtc-audio-processing-1/modules/audio_processing/include/ 供 baresip 的 FindWEBRTC_AEC.cmake 查找
baresip deps/bin/baresip NEEDED 含 libwebrtc-audio-processing-1.so.3、libstdc++.so.6
板端二进制 /root/baresip 由 overlay 或 scp 部署
板端库 /usr/lib/libwebrtc-audio-processing-1.so.3 随 rootfs 固化或 scp 部署
板端配置 /root/.baresip/config 功能开关在此

关键决策:webrtc-audio-processing 编成 shared(-Ddefault_library=shared)。
原因:meson wrapdb 提供的 abseil 全部是显式 static_library(),静态库不会被打进 webrtc 的 .a(链接 baresip 时会缺 abseil 符号);编成 .so 时 abseil 被静态链接进 .so 内部,产物自包含,板端只需部署 1 个库文件。


1. 前置条件

1.1 环境变量(每次开新终端先 source)

cat > /home/hunter/rk3588/baresip-arm64/env.sh <<'EOF'
export TC=$HOME/rk3588/rk3588_6.1_2025-02-26/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu
export DEPS=$HOME/rk3588/baresip-arm64/deps
export PATH=$TC/bin:$PATH
export PKG_CONFIG_LIBDIR=$DEPS/lib/pkgconfig   # 交叉编译只认自己的库,防止误用主机的
export T=$HOME/rk3588/baresip-arm64/aarch64-toolchain.cmake
EOF
source /home/hunter/rk3588/baresip-arm64/env.sh

1.2 安装 meson + ninja(webrtc-audio-processing 用 meson 构建)

pip3 install --user meson ninja
# 若 pypi 慢可加:-i https://pypi.tuna.tsinghua.edu.cn/simple
export PATH=$HOME/.local/bin:$PATH     # meson/ninja 装在 ~/.local/bin,不在默认 PATH
meson --version    # 实测:1.12.1
ninja --version    # 实测:1.13.2

前置依赖库(libre / openssl / opus / alsa-lib)此前已编好并安装在 $DEPS,baresip 主工程直接复用。


2. 编译 webrtc-audio-processing 1.3

2.1 下载源码(freedesktop 官方源,实测可达)

cd /tmp
curl -L -f -o webrtc-audio-processing-1.3.tar.xz \
  "https://freedesktop.org/software/pulseaudio/webrtc-audio-processing/webrtc-audio-processing-1.3.tar.xz"
sha256sum webrtc-audio-processing-1.3.tar.xz
# 必须为:2365e93e778d7b61b5d6e02d21c47d97222e9c7deff9e1d0838ad6ec2e86f1b9(与 buildroot .hash 一致)

mkdir -p /home/hunter/rk3588/baresip-arm64/deps-src
tar xf webrtc-audio-processing-1.3.tar.xz -C /home/hunter/rk3588/baresip-arm64/deps-src/

2.2 下载 abseil-cpp 到 meson wrap 缓存(packagecache)

webrtc-audio-processing 的 meson 构建依赖 abseil(subprojects/abseil-cpp.wrap)。
服务器直连 github 不通时,URL 前加 https://gh-proxy.com/ 前缀。
文件名必须与 wrap 文件中的 source_filename / patch_filename 完全一致,meson 才会使用本地缓存:

cd /home/hunter/rk3588/baresip-arm64/deps-src/webrtc-audio-processing-1.3/subprojects
mkdir -p packagecache && cd packagecache

# 1) abseil 源码(wrap source)
curl -L -f -o abseil-cpp-20230125.1.tar.gz \
  "https://gh-proxy.com/https://github.com/abseil/abseil-cpp/archive/20230125.1.tar.gz"
sha256sum abseil-cpp-20230125.1.tar.gz
# 必须为:81311c17599b3712069ded20cca09a62ab0bf2a89dfa16993786c8782b7ed145

# 2) wrapdb patch(wrapdb 会 301 到 github releases,套 gh-proxy 下载)
curl -L -f -o abseil-cpp_20230125.1-4_patch.zip \
  "https://gh-proxy.com/https://github.com/mesonbuild/wrapdb/releases/download/abseil-cpp_20230125.1-4/abseil-cpp_20230125.1-4_patch.zip"

2.3 创建 meson cross-file

cat > /home/hunter/rk3588/baresip-arm64/aarch64-meson-cross.txt <<'EOF'
[binaries]
c = '/home/hunter/rk3588/rk3588_6.1_2025-02-26/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc'
cpp = '/home/hunter/rk3588/rk3588_6.1_2025-02-26/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++'
ar = '/home/hunter/rk3588/rk3588_6.1_2025-02-26/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-ar'
strip = '/home/hunter/rk3588/rk3588_6.1_2025-02-26/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-strip'
ranlib = '/home/hunter/rk3588/rk3588_6.1_2025-02-26/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-ranlib'

[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'

[properties]
needs_exe_wrapper = true
sys_root = '/home/hunter/rk3588/rk3588_6.1_2025-02-26/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc'
EOF

2.4 配置 / 编译 / 安装

export PATH=$HOME/.local/bin:$PATH
source /home/hunter/rk3588/baresip-arm64/env.sh
cd /home/hunter/rk3588/baresip-arm64/deps-src/webrtc-audio-processing-1.3

# 配置(如需全清重建先:rm -rf build)
meson setup build \
  --cross-file /home/hunter/rk3588/baresip-arm64/aarch64-meson-cross.txt \
  --prefix=$DEPS --buildtype=release -Ddefault_library=shared

# 编译(实测 462 个目标,约几分钟)
ninja -C build

# 安装到 $DEPS
ninja -C build install

配置成功的标志(输出里应包含):

  • Dependency absl_base ... found: YES(5 个 absl_* 全部 YES,来自 subproject)
  • Library rt found: YES
  • Found ninja-... at /home/hunter/.local/bin/ninja

2.5 验证产物

ls -la $DEPS/lib/ | grep webrtc
# 应见:libwebrtc-audio-processing-1.so.3 及符号链接

find $DEPS/include/webrtc-audio-processing-1 -name "audio_processing.h"
# 应见:.../modules/audio_processing/include/audio_processing.h

readelf -d $DEPS/lib/libwebrtc-audio-processing-1.so.3 | grep -E "SONAME|NEEDED"
# SONAME: libwebrtc-audio-processing-1.so.3
# NEEDED: 仅 libstdc++.so.6 / libm / libgcc_s / libpthread / libc(无 libabsl*,已静态内嵌)

3. 编译带 AEC 的 baresip

在原 26 模块命令上增加 3 处(WEBRTC_AEC_* 两个变量 + MODULES 末尾 ;webrtc_aec):

source /home/hunter/rk3588/baresip-arm64/env.sh
cd /home/hunter/rk3588/baresip-arm64/src/baresip-4.12.0/build

cmake .. -DCMAKE_TOOLCHAIN_FILE=$T -DCMAKE_INSTALL_PREFIX=$DEPS -DCMAKE_BUILD_TYPE=Release \
  -DSTATIC=ON \
  -DOPENSSL_ROOT_DIR=$DEPS -DOPENSSL_USE_STATIC_LIBS=ON -DUSE_OPENSSL=ON \
  -DRE_INCLUDE_DIR=$DEPS/include/re -DRE_LIBRARY=$DEPS/lib/libre.a \
  -DWEBRTC_AEC_INCLUDE_DIRS=$DEPS/include/webrtc-audio-processing-1 \
  -DWEBRTC_AEC_LIBRARY_DIRS=$DEPS/lib \
  -DMODULES="stdio;alsa;g711;opus;l16;auconv;auresamp;vumeter;augain;in_band_dtmf;aubridge;aufile;ausine;uuid;stun;turn;ice;srtp;dtls_srtp;ctrl_tcp;account;contact;debug_cmd;menu;netroam;syslog;webrtc_aec"

make -j$(nproc) && make install

配置成功的标志:

  • -- Found WEBRTC_AEC: /home/hunter/rk3588/baresip-arm64/deps/lib/libwebrtc-audio-processing-1.so
  • MODULES_DETECTED=...;webrtc_aec

验证

strings $DEPS/bin/baresip | grep webrtc_aec
# 应见 "webrtc_aec: unsupported channels" 等运行期字符串

readelf -d $DEPS/bin/baresip | grep -E "NEEDED.*(webrtc|stdc)"
# 应见 libwebrtc-audio-processing-1.so.3 与 libstdc++.so.6

aarch64-none-linux-gnu-nm $DEPS/bin/baresip | grep webrtc_aec_alloc
# 应见 T _Z16webrtc_aec_alloc... 符号

grep -n webrtc_aec $HOME/rk3588/baresip-arm64/src/baresip-4.12.0/build/src/static.c
# 应见 exports_webrtc_aec 已注册进 mod_table[](静态模块注册表)

静态构建下模块只"编入"还不够,必须由 config 的 module 指令加载(module_init 遍历 config 查找 mod_table[]),所以第 5 节的开关是必须的。


4. 部署

4.1 固化进 rootfs(overlay,推荐)

OVERLAY=/home/hunter/rk3588/rk3588_6.1_2025-02-26/buildroot/board/rockchip/rk3588/fs-overlay

cp -f $DEPS/bin/baresip $OVERLAY/root/baresip
mkdir -p $OVERLAY/usr/lib
cp -f $DEPS/lib/libwebrtc-audio-processing-1.so.3 $OVERLAY/usr/lib/

# 启用 config(见第 5 节)后,重新编译 rootfs 打包:
#   ./build.sh rootfs     (增量即可,target-finalize 每次都会重新 rsync overlay)

4.2 板端热更新(不重刷)

scp $DEPS/bin/baresip root@<板IP>:/root/baresip
scp $DEPS/lib/libwebrtc-audio-processing-1.so.3 root@<板IP>:/usr/lib/
# 再在板端改 config(第 5 节),重启 baresip

baresip 没有开机自启脚本(S99audio 只做 amixer/增益初始化),板端是手动启动,更新后手动重启即可。


5. config 开关(/root/.baresip/config)

以下三行控制 AEC 功能的开与关,改完重启 baresip 生效。

5.1 AEC 总开关 —— module webrtc_aec.so

状态 该行写法 效果
启用 module webrtc_aec.so 取消注释,AEC3 加入音频滤镜链(发送方向消除回声)
禁用 #module webrtc_aec.so 注释掉,音频链与未编 AEC 时完全一致

改法(VM 端 GNU sed):

# 启用
sed -i 's|^#module[[:space:]]*webrtc_aec\.so|module webrtc_aec.so|' /root/.baresip/config
# 禁用(退回)
sed -i 's|^module[[:space:]]*webrtc_aec\.so|#module webrtc_aec.so|' /root/.baresip/config

5.2 AEC 必需项 —— opus 强制单声道

AEC 模块 MAX_CHANNELS = 1(单声道处理器)。opus 模块默认 stereo=yes;sprop-stereo=yes → 协商 2ch → 报错 webrtc_aec: unsupported channels (2 > 1),AEC 被踢出音频链。

配置行 启用 AEC 时必须 说明
opus_stereo no ✔ 不请求对端发立体声
opus_sprop_stereo no ✔ 本端不发送立体声

源码依据(modules/opus/opus.c):if (!stereo || !sprop_stereo) opus.ch = 1;

改法:

# 强制单声道(启用 AEC 时)
sed -i 's|^#opus_stereo.*|opus_stereo no|' /root/.baresip/config
sed -i 's|^#opus_sprop_stereo.*|opus_sprop_stereo no|' /root/.baresip/config
# 恢复默认(禁用 AEC 后可还原,还原后 = 立体声)
sed -i 's|^opus_stereo.*|#opus_stereo yes|' /root/.baresip/config
sed -i 's|^opus_sprop_stereo.*|#opus_sprop_stereo yes|' /root/.baresip/config

板端是 busybox sed,上面的写法([[:space:]]、无 \s/\t)已兼容;baresip 解析 config 用空白分词,缩进无所谓。

5.3 可选增强 —— extended filter

配置行 默认 说明
webrtc_aec_extended_filter yes no 扩展回声尾滤波器,免提/大房间场景更稳(略增 CPU)
grep -q '^webrtc_aec_extended_filter' /root/.baresip/config \
  && sed -i 's|^webrtc_aec_extended_filter.*|webrtc_aec_extended_filter yes|' /root/.baresip/config \
  || echo 'webrtc_aec_extended_filter yes' >> /root/.baresip/config

5.4 一键启用 / 一键退回

# ── 启用 AEC(三条一起) ──
sed -i 's|^#module[[:space:]]*webrtc_aec\.so|module webrtc_aec.so|' /root/.baresip/config
sed -i 's|^#opus_stereo.*|opus_stereo no|' /root/.baresip/config
sed -i 's|^#opus_sprop_stereo.*|opus_sprop_stereo no|' /root/.baresip/config
sync; # 重启 baresip

# ── 退回(三条一起,恢复原状) ──
sed -i 's|^module[[:space:]]*webrtc_aec\.so|#module webrtc_aec.so|' /root/.baresip/config
sed -i 's|^opus_stereo.*|#opus_stereo yes|' /root/.baresip/config
sed -i 's|^opus_sprop_stereo.*|#opus_sprop_stereo yes|' /root/.baresip/config
sync; # 重启 baresip

5.5 生效检查点(重启后看启动日志)

启用成功时日志应出现:

audio_recv: Set audio decoder: opus 48000Hz 1ch          ← 单声道协商成功
webrtc_aec: creating shared state: [48000 Hz, 1 channels, blocksize 480 samples]
audio tx pipeline: alsa ---> aubuf ---> augain ---> auconv ---> auresamp ---> webrtc_aec ---> opus
audio rx pipeline: alsa <--- aubuf <--- auconv <--- auresamp <--- webrtc_aec <--- opus

6. 已知问题与排错

现象 原因 处理
webrtc_aec: unsupported channels (2 > 1),AEC 报 Operation not supported [95] 并从 pipeline 消失 opus 协商 2ch 设 opus_stereo no + opus_sprop_stereo no(第 5.2 节)
module webrtc_aec.so: module not found 二进制未编入 AEC(旧固件)或模块名拼写错误 用新版 baresip(第 3 节产物)
启用 AEC 后 pipeline 里没有 webrtc_aec module 行仍是注释 取消注释(第 5.1 节)
库加载失败(板端) /usr/lib/libwebrtc-audio-processing-1.so.3 缺失 部署 .so(第 4 节)
github.com 直连超时 网络阻断 下载 URL 前加 https://gh-proxy.com/

效果评估注意事项

  1. 验收方向:板子侧 AEC 负责消除"板子喇叭→板子 mic"的回授,即让对端不再听到他自己的回声。若你在板子旁听到喇叭里回放出自己的声音,那是对端把声音传回来(对端免提回环/对端无 AEC),需要在对端侧解决;双端都开 AEC 才能互消。
  2. 收敛时间:AEC3 需要 1~2 秒收敛,通话刚建立时的残余回声属正常。
  3. 增益配合:micboost / BoostCapture(+30dB 级)是非线性增益,会显著破坏 AEC 消除效果,启用 AEC 时建议调小增益再联调。
  4. AEC 与远端回环无关的"本地听自己"现象,先做隔离测试:不拨号对板说话(排除本地硬件回路)、静音对端 mic(定位是否对端回传)。

7. 关键踩坑记录(为什么这样做)

  1. github 直连不通:abseil 源码与 wrapdb patch 均通过 https://gh-proxy.com/ 前缀下载;wrapdb get_patch 会 301 到 github releases,直接对 releases URL 加前缀即可。
  2. wrap 缓存文件名必须精确:abseil-cpp-20230125.1.tar.gz / abseil-cpp_20230125.1-4_patch.zip,与 .wrap 文件里的 source_filename/patch_filename 逐字一致,否则 meson 会尝试联网。
  3. 必须 -Ddefault_library=shared:abseil 在 wrapdb 里全部是显式 static_library();把 webrtc 编成 .so 才能把 abseil 静态内嵌,否则 baresip 链接静态 .a 会缺 abseil 符号。library() 定义跟随 default_library,一行搞定。
  4. 交叉编译要 needs_exe_wrapper = true:否则 meson 会尝试在 x86 主机上运行 aarch64 的测试程序而失败。
  5. 静态构建的模块也要 config 加载:STATIC=ON 只是把模块编进二进制并注册到 mod_table[],实际加载由 config module xxx.so 行控制(lookup_static_module 去 .so 后缀匹配)。
  6. AEC 必须单声道:opus 默认立体声会直接顶翻 AEC(MAX_CHANNELS=1),必须同时关闭 opus_stereo/opus_sprop_stereo。
  7. 板端 sed 兼容性:busybox sed 不支持 \s/\t 转义,脚本里用 [[:space:]] 并避免替换串中的 \t。
posted @ 2026-10-10 14:30  风间澈1998  阅读(6)  评论(0)    收藏  举报