swr_convert音频重采样介绍

这篇具有很好参考价值的文章主要介绍了swr_convert音频重采样介绍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

FFmpeg 的社群来了,想加入微信社群的朋友请购买《FFmpeg原理》VIP版 电子书,里有更高级的内容与答疑服务。


在做音频处理的时候,我们有时候需要调整音频流的采样率 或者 采样格式,可能是喇叭不支持 48000 采样率,所以需要降低到 44100 采样了.也可能因为各种业务原因,需要调整 采样率,采样格式,或者声道布局。

FFmpeg 提供了 swr_convert() 函数来实现上面的功能。

需要注意的是,调整采样率,是不会影响音频流的播放时长的,原来是 10 分钟的音频文件,你调高或者降低采样率,它还是 10 分钟的播放时长。

不过 swr_convert() 是支持调整播放时长的,这个后面说。


下面通过一个代码实例演示 swr_convert() 函数的用法,代码下载地址:GitHub,编译环境是 Qt 5.15.2 跟 MSVC2019_64bit 。

这个代码实例主要是把 音频流的 采样率 从 48000 降低到 44100,把音频格式 从 fltp 转成 s64,声道布局不变。

int tgt_fmt = AV_SAMPLE_FMT_S64;
int tgt_freq = 44100;

重点代码如下:

swr_convert音频重采样介绍

音频重采样库的API函数调用流程如下:

swr_convert音频重采样介绍


下面来介绍一下各个函数。

1,swr_alloc_set_opts(),定义如下:

struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
                                      int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
                                      int64_t  in_ch_layout, enum AVSampleFormat  in_sample_fmt, int  in_sample_rate,
                                      int log_offset, void *log_ctx);

参数解释如下:

  • struct SwrContext *s,如果传 NULL,他内部会申请一块内存,非NULL可以复用之前的内存,不用申请。
  • int64_t out_ch_layout,目标声道布局
  • enum AVSampleFormat out_sample_fmt,目标采样格式
  • int out_sample_rate,目标采样率
  • int64_t in_ch_layout,原始声道布局
  • enum AVSampleFormat in_sample_fmt,原始采样格式
  • int in_sample_rate,原始采样率
  • int log_offset,不知道做什么的,填 0 就行。
  • void *log_ctx,不知道做什么的,填 NULL 就行。

2,swr_init(),初始化重采样函数,如果你更改了重采样上下文的 options,也就是改了选项,例如改了采样率,必须调 swr_init() 才能生效。。

3,swr_convert(),转换函数,定义如下:

/** Convert audio.
 *
 * in and in_count can be set to 0 to flush the last few samples out at the
 * end.
 *
 * If more input is provided than output space, then the input will be buffered.
 * You can avoid this buffering by using swr_get_out_samples() to retrieve an
 * upper bound on the required number of output samples for the given number of
 * input samples. Conversion will run directly without copying whenever possible.
 *
 * @param s         allocated Swr context, with parameters set
 * @param out       output buffers, only the first one need be set in case of packed audio
 * @param out_count amount of space available for output in samples per channel
 * @param in        input buffers, only the first one need to be set in case of packed audio
 * @param in_count  number of input samples available in one channel
 *
 * @return number of samples output per channel, negative value on error
 */
int swr_convert(struct SwrContext *s, uint8_t **out, int out_count,
                                const uint8_t **in , int in_count);

参数解释如下:

  • struct SwrContext *s,重采样上下文,也叫重采样实例。
  • uint8_t **out,输出的内存地址。
  • int out_count,每声道有多少个样本,这个值通常建议设置得大一点,避免内存空间不够,不够空间写入,就会缓存在重采样实例里面,越积越多。
  • const uint8_t **in,输入的内存地址。
  • int in_count,输入的音频流,每声道有多少个样本。

swr_convert() 函数的返回值是实际的样本数。


项目代码的运行结果如下:

swr_convert音频重采样介绍

本文项目代码的重点是 out_count 的计算,如下:

out_count = (int64_t)frame->nb_samples * tgt_freq / frame->sample_rate + 256;

由于源文件 juren-30s.mp4 大部分音频帧是 1024 个样本数,从 48000 降低 44100,也就是说 1024个样本 会 变成 940 个样本。

但是从上图的运行结果可以看到,有时候是转换出 941 个样本的,比 940 多了一个。所以 out_count 通常会在本来的大小上 加上 256,让写空间大一点。

如果不够空间写入,就会缓存在重采样实例里面,越积越多。

+256 也是 ffplay 播放器的做法。


最后还有一个重点是,SwrContext 上下文里面可能会有残留数据,当没有数据输入的时候,需要再调 swr_convert() ,把残留的数据刷出来,如下:

swr_convert音频重采样介绍

swr_convert音频重采样介绍

可以看到,最后刷出来了 16 个残留样本


上面讲的是播放器的重采样场景,重采样之后,获取到了内存 out ,直接把 out 的内存丢给 SDL 即可播放。

但是有时候,我们是需要把转换之后的数据进行编码保存的,所以这种情况下,需要把 out 的内存挂在 AVFrame 里面,具体做法如下:

AVFrame frame;
frame->extended_data = out;
frame->data = out;
frame->nb_samples = out_nb_samples;

然后设置好 frame 的 pts 即可,这样应该是可以的,不过我没编码测试过,后面补充。

音频也可以用 av_samples_alloc() 来申请内存,但是由于本文要 +256 ,所以没有使用这个函数。


扩展知识:

音频与视频的转换函数,命名是类似的,例如:

av_samples_alloc()
av_image_alloc()
av_samples_fill_arrays()
av_image_fill_arrays()

而 av_frame_get_buffer() 函数可以同时用于音频,视频的申请内存,前提是设置好 AVFrame 的 格式,宽高,采样率,声道。


swr_convert() 函数使用起来,我个人觉得有点繁琐,其实音频的 aformat 格式滤镜也可以调整 采样率,采样格式,声道布局。

滤镜的语法比较统一,只是 aformat 滤镜不能调整播放时长,推荐阅读《FFmpeg的音频aformat滤镜介绍》

最后需要用swr_free() 释放调重采样实例。


一开始留的彩蛋,调整播放时长,是用 swr_set_compensation() 实现,推荐阅读《如何调整音频播放时长》文章来源地址https://www.toymoban.com/news/detail-402029.html

到了这里,关于swr_convert音频重采样介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用ffmpeg调整视频中音频采样率及声道

    通过ffmpeg -i命令查看视频基本信息 -r fps每秒传输帧数,默认为25 -s 分辨率 -ar 设定采样率 -ac 设定声音的Channel数 -acodec 设定声音编解码器,未设定时则使用与输入流相同的编解码器 FFmpeg项目由 Fabrice Bellard在2000年创立。到目前为止,FFmpeg项目的开发者仍然与VLC、MPV、dav1d、x

    2024年01月23日
    浏览(53)
  • 音视频八股文(11)-- ffmpeg 音频重采样

    所谓的重采样,就是改变⾳频的采样率、sample format、声道数等参数,使之按照我们期望的参数输出。 为什么要重采样?当然是原有的⾳频参数不满⾜我们的需求,⽐如在FFmpeg解码⾳频的时候,不同的⾳源有不同的格式,采样率等,在解码后的数据中的这些参数也会不⼀致(最

    2024年02月04日
    浏览(102)
  • 【FFmpeg】ffmpeg 命令行参数 ⑧ ( 使用 ffmpeg 转换封装格式 | 音视频编解码器参数设置 | 视频 帧率 / 码率 / 分辨率 设置 | 音频 码率 / 采样率 设置 )

    音视频 文件 从 采样 - 处理 - 得到原始数据帧队列 - 音视频编码 - 音视频包队列 - 格式封装 的过程如下 : 封装格式 参考 【音视频原理】音视频 “ 采样 - 编码 - 封装 过程 “ 和 “ 解封装 - 解码 - 播放 过程 “ 分析 ( 视频采集处理流程 | 音频采集处理流程 | 音视频文件解封装

    2024年04月17日
    浏览(85)
  • 2023-04-30:用go语言重写ffmpeg的resampling_audio.c示例,它实现了音频重采样的功能。

    2023-04-30:用go语言重写ffmpeg的resampling_audio.c示例,它实现了音频重采样的功能。 答案2023-04-30: resampling_audio.c 是 FFmpeg 中的一个源文件,其主要功能是实现音频重采样。 音频重采样是指将一段音频数据从一个采样率、声道数或样本格式转换为另一种采样率、声道数或样本格式

    2024年02月02日
    浏览(37)
  • FFmpeg aresample_swr_opts的解析

    aresample_swr_opts 是AVFilterGraph中的option。 因为是option,所以就想能不能将这个option配置到graph里面,分析代码发现, AVFilterGraph::aresample_swr_opts 在graph解析的时候不能当做filter的option解析。 因为graph load的在解析 graph 文本的过程,option来自filter的option, aresample_swr_opts 是AVFilterGr

    2024年02月15日
    浏览(36)
  • SOP文档撰写介绍(偏向运营类项目:用户运营/社群运营/新媒体运营)

    目录 SOP是什么? SOP有什么意义? 怎么撰写运营类项目SOP? 举例一 表格形式SOP 举例二 文档形式SOP 如何优化运营项目SOP? 所谓SOP,是 Standard Operating Procedure 三个单词的首字母 ,即标准作业程序,是 将某一事件的标准操作步骤和要求以统一的格式描述出来,用来指导和规范日

    2024年02月13日
    浏览(47)
  • 音频基础知识(一) 音频基础概念 | 采样 | 量化 | 编码 | 常见音频格式

    🚀 个人简介:CSDN「 博客新星 」TOP 10 , C/C++ 领域新星创作者 💟 作    者: 锡兰_CC ❣️ 📝 专    栏: 【音视频基础知识】 🌈 若有帮助,还请 关注➕点赞➕收藏 ,不行的话我再努努力💪💪💪   声音的三要素:频率、振幅、波形。 1、频率   声波的频率,也就是

    2024年03月22日
    浏览(48)
  • Android 音频(一) _ 采样量化编码 & AudioRecord 录制音频

    模拟信号 音频承载着声音信息,而声音是连续变化的信息。物理中把承载信息的载体称为 信号 ,把连续变化的信息称为 模拟信号 ,它在坐标轴中表现为如下形态: 计算机只能处理0和1,即离散值。音频这种模拟信号得转换成离散值才能被计算机处理。这个转化过程称为 模

    2023年04月09日
    浏览(45)
  • 音频采样率转换处理

    一、采样率转换 1、低采样率转换成高采样率 在音频处理中,插值法是一种常用的方法,用于将采样率较低的音频数据转换为采样率较高的音频数据。插值法的基本思想是,通过已知的采样点,推算出未知的采样点。常用的插值法有线性插值法、样条插值法等。 线性插值法:

    2024年02月09日
    浏览(35)
  • Android14实战:打破音频默认重采样的限制(五十二)

    简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏: Audio工程师进阶系列 【 原创干货持续更新中…… 】🚀 优质专栏: 多媒体系统工程师系列 【 原创干货持续更新中…… 】🚀 人生格言: 人生从来没有捷径

    2024年01月20日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包