当前位置: 首页 > news >正文

FFmpeg libswresample 模块的关键函数swr_convert 到底在干嘛?

目录

一、先给一句话定性

二、swr_convert 函数原型

三、参数逐个拆(重点在“样本不是字节”)

① SwrContext *s

② out[]/ in[]—— 不是 void*

packed(S16 / S32 / U8)

planar(FLTP / S16P)

③ in_count/ out_count单位是什么?

四、返回值到底什么意思?

五、最经典的坑:残留 FIFO(90%人踩)

现象

原因

正确 flush 姿势

六、AVFrame 流派的“标准模板”

解码 → swr → SDL / D3D

七、S16 packed → SDL 最小完整例子

八、常见翻车表(血泪)

九、swr_convert 内部在干嘛

十、一句话总结


觉得有用,就请您帮忙点赞转发收藏吧,您的鼓励是我创作的动力,多谢看官。

由于能力水平有限,文中的错误或不严谨的地方在所难免,还请批评指正。

swr_convert是 FFmpeg 中libswresample库的核心函数,用于执行音频重采样操作。它能够将音频流的‌采样率‌、‌采样格式‌(如从浮点转为整型)或‌声道布局‌(如从单声道转为立体声)进行转换,且不会改变音频的播放时长。

做音频播放 / 录音 / 转码的人,迟早都会撞上这一句:

swr_convert(swr_ctx, out_buf, out_samples, in_buf, in_samples);

抄能跑,但一问:为什么返回值是输出帧数?in_samples 怎么给?planar 怎么摆?残留数据在哪?

今天把swr_convert拆干净,不绕术语。


一、先给一句话定性

swr_convert 不是“格式转换器”,是音频流水线工人:

负责 采样率 / 声道布局 / 样本格式 / 位深 全部打包干完。

核心任务只有三个:

重采样(SRC) 声道重排(channel layout) packed ↔ planar

二、swr_convert 函数原型

int swr_convert(struct SwrContext *s, uint8_t *const out[], int out_count, const uint8_t *const in[], int in_count);

看着简单,其实 4 组语义:

上下文 输出地址 / 想要多少样本 输入数据 / 实际多少样本

三、参数逐个拆(重点在“样本不是字节”)


SwrContext *s

一次初始化,反复用:

swr_alloc_set_opts(nullptr, AV_CH_LAYOUT_STEREO, // out layout AV_SAMPLE_FMT_S16, // out fmt 48000, // out rate AV_CH_LAYOUT_5POINT1_BACK, // in layout AV_SAMPLE_FMT_FLTP, // in fmt 44100, 0, nullptr);

layout + rate + fmt 缺一不可


out[]/in[]—— 不是 void*

packed(S16 / S32 / U8)
uint8_t* out[1] = { (uint8_t*)pcm16 }; swr_convert(s, out, ...);
planar(FLTP / S16P)
uint8_t* out[2]; out[0] = left; out[1] = right;

规则:

  • planar = data[i] 每声道一块

  • packed = data[0] 全挤一起

AVFrame::data 原样传就行


in_count/out_count单位是什么?

单声道样本数(per channel sample count)

参数

意思

in_count

输入每个声道多少帧

out_count

我最多能吃多少帧

不是字节

不是 packet size

例:1024 帧立体声:

in_count = 1024; // FLTP: data[0][1024], data[1][1024]

四、返回值到底什么意思?

int ret = swr_convert(...);

ret = 本次输出的 per-channel sample 数

ret

含义

>0

输出样本数

0

FIFO 里攒着呢

<0

出错

常见误解:

“我给了 1024,为啥返回 882?”

因为:

48000 → 44100 ratio = 44100/48000 ≈ 0.91875

五、最经典的坑:残留 FIFO(90%人踩)

现象

  • 最后几秒声音没了

  • 每次 flush 都有一小截

原因

swr 内部有 FIFO,不够一帧不吐

正确 flush 姿势

while ((ret = swr_convert(swr, out, out_max, nullptr, 0)) > 0) { write_pcm(out, ret); }

口诀:

in=nullptr, in_count=0 = 冲 FIFO


六、AVFrame 流派的“标准模板”

解码 → swr → SDL / D3D

AVFrame* dec = got_frame; uint8_t* out[1] = { audio_buf }; int out_nb = swr_get_out_samples(swr, dec->nb_samples); int ret = swr_convert(swr, out, out_nb, (const uint8_t**)dec->data, dec->nb_samples); // ret = 实际可播放样本数

swr_get_out_samples()先问大小,避免 alloc 太小


七、S16 packed → SDL 最小完整例子

int dst_nb = swr_get_out_samples(swr_ctx, frame->nb_samples); uint8_t* dst = (uint8_t*)malloc(dst_nb * 2 * 2); uint8_t* out[1] = { dst }; swr_convert(swr_ctx, out, dst_nb, (const uint8_t**)frame->data, frame->nb_samples); SDL_QueueAudio(dev, dst, dst_nb * 4); free(dst);

八、常见翻车表(血泪)

症状

真凶

声音加速

in/out rate 反了

爆音

planar 当 packed

声道左右反

layout 没设

最后没声

没 flush

返回负

out_count 太小


九、swr_convert 内部在干嘛

[in frame] ↓ delay / compensation ↓ 重采样(polyphase filter) ↓ 声道混合(downmix / upmix) ↓ planar ↔ packed ↓ [FIFO] → out

不是一帧进一帧出


十、一句话总结

swr_convert = 给样本数,吃样本数,返回输出样本数;

结束必须 nullptr/0 flush;planar 用 data[],永远别碰字节数。

http://www.jsqmd.com/news/1361054/

相关文章:

  • Pickerview vs Android-PickerView:为什么这款选择器更优秀?
  • 抖音无货源店群规模化运营方案:抖掌柜一键铺货+多店互搬+AI违规检测完整提效实操 - 抖掌柜—键铺货
  • Unity Mathf性能优化指南:从三角函数到Shader的避坑与实战技巧
  • DiffusionFastForward Colab教程:浏览器中运行扩散模型生成高质量图像
  • 高吞吐缓存系统架构设计与性能优化实战
  • 维性力网学:星体顺旋演化与晶态终局推演011
  • 为什么手里盒马卡越攒越多,最后只能找盒马卡回收处理 - 沃卡回收
  • 如何实现千牛极速自动改价自动化?isTrusted事件注入,浏览器视为真人操作
  • 永兴黄金回收:郴奢汇门店资质与变现流程解析 - 小仙贝贝
  • Steam挂刀行情站终极指南:24小时自动追踪四大平台饰品价格,轻松找到最佳交易时机!
  • Java基本数据类型详解与最佳实践
  • 名包回收13393032100 2026保定首饰回收指南 小何收的顶 - 小何收的顶
  • 迪奥名包回收13393032100 2026保定迪奥包回收指南 小何收的顶 - 小何收的顶
  • SwarmForge协作效率:减少AI代理之间的冲突与重复工作
  • 终极Anima-LLLite姿势控制指南:10个技巧实现AI人物姿态精准生成
  • 如何用打字练习软件同时提升英语词汇量和键盘输入速度?
  • UE5蓝图与C++高效混合开发:架构设计与实战避坑指南
  • 抖掌柜实操|抖音多店矩阵管理核心逻辑,选品一键铺货多店互搬AI违规检测完整店群玩法 - 抖掌柜—键铺货
  • Fabric-Bedrock-Miner常见问题解答:解决你的所有困惑
  • Less安全防护全攻略:如何在多用户环境中安全使用文本查看器
  • Windows终极优化神器:如何用WinUtil一键解决90%系统问题
  • 用AutoRemesher实现3D模型自动重拓扑:革命性的四边形网格优化解决方案
  • A-47模块90dB AEC有效性与房间混响的物理边界分析
  • 3分钟学会《命运2》单人模式工具:告别强制匹配,享受纯粹游戏体验
  • 郭秋成《好好的时光》演技解析与角色塑造艺术
  • 如何用自然语言控制电脑:UI-TARS桌面版完整实战指南
  • 2026年粗粮面条选购指南:从食堂供应链看品质真相 - 万相科技
  • Agent Governance Toolkit安全认证资源库:汇集所有认证相关资源
  • 5种方法解决Rufus制作启动盘后USB设备无法识别的终极指南
  • 3步获取B站直播推流码:专业第三方推流工具终极指南