swr_convert音频重采样成AV_SAMPLE_FMT_FLTP

在网上很多的教程,利用swr_convert来进行音频的重采样,但有时候我们发现有些转换成AV_SAMPLE_FMT_S16是没有问题的,但一旦是AV_SAMPLE_FMT_FLTP 时候,程序直接崩溃,这是因为网上有些教程里那个buffer是自定义一个连续的片段,然后直接丢给swr_convert,但这样在s16上是没有问题,s16上只占用了frame->data[0],但一旦是AV_SAMPLE_FMT_FLTP时候,它需要的不仅仅是data[0],还有data[1],而网上的一般直接是一个buf =(uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE*2*sizeof(uint8_t) )这样的结果只能保证data[0],所以应该去参考ffmpeg 里demo的resampling_audio,那里提供一个正确的思路来进行重采样,或者你可以选择利用滤镜来进行重采样。

引用http://www.cnblogs.com/jianqifeihong/archive/2013/12/17/3477935.html里的话就是带不带p的问题。

注意到AVSampleFormat里面还有几种格式以P(Planar,平面)结尾,那它们与不带P的有什么区别呢?当有多个Channel的时候,就有区别了。不带P的只有一个buffer,buffer里面Sample的分布是像这样A1B1A2B2A3B3......其中大写字母代表一个Channel,数字代表每个采样在该Channel里的编号。可以看出所有采样被放到一起(即一个buffer),不同的Channel被均匀的分布在其中。而带P的是像这样A1A2A3......B1B2B3......不同Channel各占一个buffer,且每个buffer长度一样。

音频解码之后,需要发送到第三方的音频输出库进行播放。可是这些播放库不一定支持libav的所有格式,前面说过AAC编码只会输出float planar类型的采样,那要怎样在不支持float planar的音频输出设备(比如Windows的WaveOut)上输出呢?有两种方法(其实是一种,两种方法原理一样),一个是采用libav的resample API(我试了半天,程序老是会crash),另外一种就是自己根据上面说到的布局来手动解决了。

在这里还要说一下程序又是编写特定视频时候有时突然crash,万恶的Win开发,让我总是看不到崩溃的原因,一直怀疑是别的线程导致的,但最后还是没有。最后不得不换位思考,我将不同视频再来一次,发现只有特定的才会有概率触发。而且若果将采样高到低没问题,低到高却会。这是才将眼光注意回重采样这边,是的。原来又是这里的 锅。这里的buffer大小是个坑,你要实时地更新那个buffer。
`swr_convert` 是 FFmpeg 库中的一个函数,用于在不同的音频格式之间进行重采样转换。如果你想在 C++ 程序中调用 `swr_convert` 来处理 WAV 格式的音频并播放它,你需要首先确保你已经正确安装了 FFmpeg 库,并且配置了相应的编译环境。 在 C++ 中使用 `swr_convert` 处理并播放 WAV 格式的音频大致可以分为以下几个步骤: 1. 初始化源音频流和目标音频流的参数(比如采样率、通道数、采样格式等)。 2. 创建一个音频重采样上下文 `SwrContext`。 3. 使用 `swr_alloc_set_opts` 初始化重采样上下文,并设置源和目标的参数。 4. 打开源音频文件,读取源音频数据。 5. 使用 `swr_convert` 进行重采样转换。 6. 播放转换后的音频数据,这通常需要使用 FFmpeg 的其他音视频处理函数或集第三方库,如 ALSA、PulseAudio 等,或者将数据写入文件进行播放。 7. 清理资源,释放重采样上下文和关闭音频文件。 以下是使用 `swr_convert` 的一个简化的示例代码框架: ```cpp #include <libswresample/swresample.h> int main() { // 初始化源音频流和目标音频流参数 AVSampleFormat src_sample_fmt = AV_SAMPLE_FMT_S16; // 源音频采样格式 int src_sample_rate = 44100; // 源音频采样率 int src_channels = 2; // 源音频通道数 AVSampleFormat dst_sample_fmt = AV_SAMPLE_FMT_FLTP; // 目标音频采样格式 int dst_sample_rate = 44100; // 目标音频采样率 int dst_channels = 2; // 目标音频通道数 // 创建重采样上下文 SwrContext *swr_ctx = swr_alloc_set_opts(NULL, dst_channels, dst_sample_fmt, dst_sample_rate, src_channels, src_sample_fmt, src_sample_rate, 0, NULL); if (!swr_ctx) { // 错误处理 } // 初始化重采样上下文 swr_init(swr_ctx); // 读取源音频数据,进行重采样转换,并播放处理后的音频数据 // ... // 清理资源 swr_free(&swr_ctx); return 0; } ``` 请注意,这只是一个非常基础的示例,实际使用时你需要添加更多的代码来处理文件读取、错误检查、数据处理以及音频播放等。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值