在FFmpeg中进行音频的格式转换主要有三个步骤
- 实例化SwrContext,并设置转换所需的参数:通道数量、channel layout、sample rate
有以下两种方式来实例SwrContext,并设置参数:
使用swr_alloc
SwrContext *swr = swr_alloc(); av_opt_set_channel_layout(swr, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0); av_opt_set_channel_layout(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(swr, "in_sample_rate", 48000, 0); av_opt_set_int(swr, "out_sample_rate", 44100, 0); av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0); av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
使用 swr_alloc_set_opts SwrContext *swr = swr_alloc_set_opts(NULL, // we're allocating a new context AV_CH_LAYOUT_STEREO, // out_ch_layout AV_SAMPLE_FMT_S16, // out_sample_fmt 44100, // out_sample_rate AV_CH_LAYOUT_5POINT1, // in_ch_layout AV_SAMPLE_FMT_FLTP, // in_sample_fmt 48000, // in_sample_rate 0, // log_offset NULL); // log_ctx
上述两种方法设置那个的参数是将5.1声道,channel layout为AV_CH_LAYOUT_5POINT1,采样率为48KHz转换为2声道,channel_layout为AV_SAMPLE_FMT_S16,采样率为44.1KHz。
- 计算转换后的sample个数 转后后的sample个数的计算公式为:src_nb_samples * dst_sample_rate / src_sample_rate,其计算如下:
int dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, frame->sample_rate) + frame->nb_samples, frame->sample_rate, frame->sample_rate, AVRounding(1)); 函数av_rescale_rnd是按照指定的舍入方式计算a * b / c 。 函数swr_get_delay得到输入sample和输出sample之间的延迟,并且其返回值的根据传入的第二个参数不同而不同。如果是输入的采样率,则返回值是输入sample个数;如果输入的是输出采样率,则返回值是输出sample个数。
int nb = swr_convert(swr_ctx, &audio_buf, dst_nb_samples, (const uint8_t**)frame->data, frame->nb_samples); 调用 swr_convert进行转换