FFmpeg 中编译和使用 soxr 重采样引擎

1. soxr vs swr 重采样器

FFmpeg 的 libswresample 默认使用内置的 SWR 引擎进行音频重采样。此外还支持通过编译选项 --enable-libsoxr 集成 SoX Resampler (soxr) 作为替代引擎。

特性 内置 SWR soxr
重采样质量 良好,适合大多数场景 更高,适合对音频质量敏感的场景
性能 较快 略慢(高质量滤波器更长)
编译依赖 无,FFmpeg 自带 需要额外编译 libsoxr

适用场景:对重采样质量有较高要求的音频处理流程,例如专业音频制作、科学信号处理、需要与其他高质量重采样库对齐结果的场景等。

2. 四端编译 soxr

SourceForge 下载 soxr 0.1.3 源码,使用 CMake 编译静态库。

macOS (Fat 库,支持 arm64 + x86_64)

bash 复制代码
for ARCH in $ARCHS; do
    echo "building soxr for $ARCH..."
    BUILD_DIR="$SHELL_DIR/soxr-build-$ARCH"
    mkdir -p "$BUILD_DIR"
    cd "$BUILD_DIR"
    cmake "$SOXR_SRC" -DCMAKE_OSX_ARCHITECTURES="$ARCH" \
        -DCMAKE_INSTALL_PREFIX="$THIN_SOXR/$ARCH" \
        -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release \
        || exit 1
    cmake --build . -j8 || exit 1
    cmake --install . || exit 1
    cd -
    rm -rf "$BUILD_DIR"
done
# 合并 Fat 库
lipo -create "$THIN_SOXR/arm64/lib/libsoxr.a" "$THIN_SOXR/x86_64/lib/libsoxr.a" \
     -output "$FAT_SOXR/lib/libsoxr.a"

iOS

bash 复制代码
if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]; then
    SOXR_SDK="iphonesimulator"
else
    SOXR_SDK="iphoneos"
fi
SOXR_SYSROOT=$(xcrun --sdk $SOXR_SDK --show-sdk-path)

cmake "$SOXR_SRC" \
    -DCMAKE_OSX_ARCHITECTURES="$ARCH" \
    -DCMAKE_OSX_SYSROOT="$SOXR_SYSROOT" \
    -DCMAKE_OSX_DEPLOYMENT_TARGET="$DEPLOYMENT_TARGET" \
    -DCMAKE_INSTALL_PREFIX="$THIN_SOXR/$ARCH" \
    -DBUILD_SHARED_LIBS=OFF \
    -DBUILD_TESTS=OFF \
    -DCMAKE_BUILD_TYPE=Release

Android

bash 复制代码
cmake "$SOXR_SRC" \
    -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} \
    -DANDROID_ABI=${ANDROID_ABI} \
    -DANDROID_PLATFORM=${ANDROID_PLATFORM} \
    -DCMAKE_INSTALL_PREFIX=${SOXR_INSTALL_DIR} \
    -DBUILD_SHARED_LIBS=OFF \
    -DCMAKE_BUILD_TYPE=Release \
    -DWITH_OPENMP=OFF \
    -DBUILD_TESTS=OFF \
    -DBUILD_EXAMPLES=OFF

Windows

bash 复制代码
cmake -G "Ninja" -S "${SOXR_SRC}" -B "${basepath}/soxr-build" \
    -DCMAKE_BUILD_TYPE=Release \
    -DBUILD_SHARED_LIBS=OFF \
    -DBUILD_TESTS=OFF \
    -DBUILD_SHARED_RUNTIME=OFF \
    -DCMAKE_INSTALL_PREFIX=${basepath}/soxr_install

Windows 注意事项 :soxr 的 CMakeLists.txt 最低版本要求为 3.1,不支持 CMAKE_MSVC_RUNTIME_LIBRARY。MT/MD 的切换只能通过 soxr 自身提供的 BUILD_SHARED_RUNTIME 选项控制(OFF = MT,ON = MD)。

编译完成后,在 FFmpeg 的 configure 中添加:

bash 复制代码
--enable-libsoxr --extra-cflags="-I${SOXR_INSTALL}/include" --extra-ldflags="-L${SOXR_INSTALL}/lib"

静态库打包 :如果 soxr 和 FFmpeg 都编译为静态库,需要将 libsoxr.a 的目标文件合并到 libswresample.a 中,否则下游链接时会出现未定义符号错误。

3. 使用 soxr 引擎

在创建 SwrContext 后、swr_init 之前(或首次 swr_convert_frame 前),通过 AVOption 设置引擎及参数:

cpp 复制代码
SwrContext* swr = swr_alloc();
av_opt_set_int(swr, "resampler", SWR_ENGINE_SOXR, 0);     // 切换到 soxr 引擎
av_opt_set_double(swr, "precision", 33.0, 0);              // 重采样精度(bit)
av_opt_set_double(swr, "cutoff", 0.84, 0);                 // 通带截止频率

以上参数配置下的重采样效果与 Python resampy 库的默认重采样结果一致。

可以通过运行时检测当前 FFmpeg 是否编译了 soxr 支持:

cpp 复制代码
bool isSoxrSupported() {
    return strstr(swresample_configuration(), "enable-libsoxr") != nullptr;
}

4. 注意事项:soxr flush 阶段的已知问题

使用 swr_convert_frame + SWR_ENGINE_SOXR 复用输出 AVFrame 时,如果 output buffer 容量不足,SwrContext 内部会累积未消耗的输入数据(in_buffer)。在最后 flush 阶段,FFmpeg 的 soxr 集成层(soxr_resample.c)会先向 soxr 发送输入终结信号,再尝试处理 in_buffer 残留数据,导致 soxr 在终结状态下收到输入而崩溃。内置 SWR 引擎不受此影响。

规避方法 :每次 swr_convert_frame 调用前,通过 swr_get_out_samples 获取预期输出量,确保 output buffer 容量足够,使 in_buffer 始终为空:

cpp 复制代码
if (swr_is_initialized(swrCtx)) {
    int expected = swr_get_out_samples(swrCtx, in_frame->nb_samples);  // flush 时传 0
    reserveFrame(expected);  // 仅在 expected > capacity 时才重新分配
}

该问题属于 FFmpeg soxr_resample.c 的集成缺陷,后续计划尝试从 FFmpeg 源码层面修复。

相关推荐
weixin_495248405 小时前
短剧视频翻译配音指南:古装、甜宠与悬疑如何本地化?
音视频
禹亮科技6 小时前
制造业100㎡跨国技术评审会议室音视频整体解决方案(亿联+思必驰+讯飞AI落地实践)
人工智能·音视频·视频会议系统集成
潜创微科技7 小时前
HDMI 分配器芯片方案商 IT66630 有源分配芯片方案
音视频
不爱记笔记8 小时前
多模态AI如何理解视频内容?从视觉、语音到语义的三层技术拆解
人工智能·自然语言处理·nlp·音视频·多模态
论迹复利10 小时前
Sniff 省电模式参数调优——续航与音频稳定性平衡实操
音视频·sniff·bt·功耗、
星核0penstarry11 小时前
从 Dialog-RSN-1 看语音 Agent 走向:企业如何评估音频原生模型与 API 服务
人工智能·音视频·音频·api
明如正午13 小时前
【python】Python + OpenCV 实现视频关键帧提取与智能去重
python·opencv·音视频
呆呆敲代码的小Y13 小时前
5 分钟上手 OpenMontage:把 AI 编程助手变成视频工作室
人工智能·aigc·音视频·ai视频生成·claude code·openmontage
奈斯先生Vector14 小时前
大模型 Agentic Workflow 架构解构:异构 API 调度与 Token 路由的多模态系统设计
开发语言·前端·架构·prompt·aigc·音视频
海带紫菜菠萝汤14 小时前
FFmpeg.wasm 实践:在浏览器中运行 FFmpeg 的能力边界与性能瓶颈
前端·javascript·ffmpeg·音视频·wasm