ffmpeg重采样中swr_convert和swr_get_out_samples的用法

ffmpeg重采样中swr_convert和swr_get_out_samples的用法

在做mux的时候关于重采样可以用fifo,或者audiofifo做缓存处理,当做demux的时候关于重采样就可以用到上面的swr_convert和swr_get_out_samples做配合处理。先看下这两个函数的注释:

/** 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);

/**
 * Find an upper bound on the number of samples that the next swr_convert
 * call will output, if called with in_samples of input samples. This
 * depends on the internal state, and anything changing the internal state
 * (like further swr_convert() calls) will may change the number of samples
 * swr_get_out_samples() returns for the same number of input samples.
 *
 * @param in_samples    number of input samples.
 * @note any call to swr_inject_silence(), swr_convert(), swr_next_pts()
 *       or swr_set_compensation() invalidates this limit
 * @note it is recommended to pass the correct available buffer size
 *       to all functions like swr_convert() even if swr_get_out_samples()
 *       indicates that less would be used.
 * @returns an upper bound on the number of samples that the next swr_convert
 *          will output or a negative value to indicate an error
 */
int swr_get_out_samples(struct SwrContext *s, int in_samples);


就说如果传入的nb_samles大于了传出的nb_samplse则SwrContext中会有缓存,会导致内存一直暴涨,解决方法,可以看如下代码:

没有缓存的重采样这么处理:

ret = swr_convert(swrcontext, pOutputFrame->data,pOutputFrame->nb_samples,
		(const uint8_t**)pInputFrame->data,pInputFrame->nb_samples);

有缓存的代码这么处理:

//如果还有缓存在swrcontext中,第二个参数要填写0才能获取到,缓存数据
int fifo_size = swr_get_out_samples(swrcontext,0);
if ( fifo_size >= pOutputFrame->nb_samples)
{
	ret = swr_convert(swrcontext, pOutputFrame->data,pOutputFrame->nb_samples,
	NULL,0);
}

即如果有缓存则先判断是否有缓存在里面,如果有则传入数据为空取出缓存。


如有错误请指正:

交流请加QQ群:62054820
QQ:379969650.



  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
重采样是将音频数据从一个采样率转换为另一个采样率的过程。在ffmpeg,可以使用libswresample库来进行重采样操作。 要将44100Hz的音频数据重采样为48000Hz,你需要按照以下步骤进行操作: 1. 创建源和目标音频转换上下文:首先,你需要创建一个SwrContext结构体,并设置输入和输出的采样率、数据格式和通道数。对于输入的采样率为44100Hz,数据格式为S16le,通道数为2;而输出的采样率为48000Hz,数据格式为S16le,通道数为2。 2. 分配输入和输出音频缓冲区:根据输入和输出的采样数,你需要分配足够大小的输入和输出音频缓冲区。 3. 读取输入音频数据:从音频设备以适当的大小读取音频数据,并将其存储在输入音频缓冲区。 4. 进行重采样:使用swr_convert函数将输入音频数据重采样为输出音频数据。确保将输入音频数据的大小设置为输入音频缓冲区的采样数,并将输出音频数据的大小设置为输出音频缓冲区的采样数。 5. 使用重采样后的数据进行后续处理:你可以在获取到输出音频数据后进行进一步的处理,例如编码或保存到文件。 以下是示例代码片段,展示了如何在ffmpeg进行重采样操作: ```c++ // 创建音频转换上下文 SwrContext *swr_ctx = swr_alloc_set_opts(NULL, av_get_default_channel_layout(2), // 输出通道布局 AV_SAMPLE_FMT_S16, // 输出采样格式 48000, // 输出采样率 av_get_default_channel_layout(2), // 输入通道布局 AV_SAMPLE_FMT_S16, // 输入采样格式 44100, // 输入采样率 0, // 日志偏移量 NULL); // 初始化音频转换上下文 swr_init(swr_ctx); // 分配输入和输出音频缓冲区 uint8_t **input_buffer = (uint8_t **)av_malloc_array(2, sizeof(uint8_t *)); uint8_t **output_buffer = (uint8_t **)av_malloc_array(2, sizeof(uint8_t *)); int input_samples = 1024; // 输入采样数 int output_samples = av_rescale_rnd(input_samples, 48000, 44100, AV_ROUND_UP); // 输出采样数 av_samples_alloc(input_buffer, NULL, 2, input_samples, AV_SAMPLE_FMT_S16, 0); av_samples_alloc(output_buffer, NULL, 2, output_samples, AV_SAMPLE_FMT_S16, 0); // 读取输入音频数据并进行重采样 while (read_input_audio(input_buffer, input_samples)) { swr_convert(swr_ctx, output_buffer, output_samples, (const uint8_t **)input_buffer, input_samples); // 对重采样后的数据进行进一步处理,例如编码或保存到文件 // ... av_frame_unref(frame); } // 释放资源 av_freep(&input_buffer[0]); av_freep(&output_buffer[0]); av_free(input_buffer); av_free(output_buffer); swr_free(&swr_ctx); ``` 请注意,这只是一个基本的示例,你还可以根据自己的需求进行进一步的处理和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值