FFmpeg⾳频重采样API(libswresample)
⽬录
1. 参考
2. lswr功能介绍
3. lswr使⽤说明
4. ⽰例代码
1. 参考
[1] FFmpeg/Libswresample Documentation
[2] FFmpeg/Libswresample Detailed Description
[3] FFmpeg/doc/examples/resampling_audio.c
2. lswr功能介绍
FFmpeg中重采样的功能由libswresample(后⾯简写为lswr)提供。
lswr提供了⾼度优化的转换⾳频的采样频率、声道格式或样本格式的功能。
功能说明:
采样频率转换:对⾳频的采样频率进⾏转换的处理,例如把⾳频从⼀个⾼的44100Hz的采样频率转换到8000Hz。从⾼采样频率到低采样频率的⾳频转换是⼀个有损的过程。API提供了多种的重采样选项和算法。
声道格式转换:对⾳频的声道格式进⾏转换的处理,例如⽴体声转换为单声道。当输⼊通道不能映射到输出流时,这个过程是有损的,因为它涉及不同的增益因素和混合。
样本格式转换:对⾳频的样本格式进⾏转换的处理,例如把s16的PCM数据转换为s8格式或者f32的PCM数据。此外提供了Packed和Planar 包装格式之间相互转换的功能,Packed和Planar的区别见FFmpeg中Packed和Planar的PCM数据区别。
此外,还提供了⼀些其他⾳频转换的功能如拉伸和填充,通过专门的设置来启⽤。
3. lswr使⽤说明
重采样的处理流程:
1. 创建上下⽂环境:重采样过程上下⽂环境为SwrContext数据结构。
2. 参数设置:转换的参数设置到SwrContext中。
3. SwrContext初始化:swr_init()。
4. 分配样本数据内存空间:使⽤av_samples_alloc_array_and_samples、av_samples_alloc等⼯具函数。
5. 开启重采样转换:通过重复地调⽤swr_convert来完成。
6. 重采样转换完成, 释放相关资源:通过swr_free()释放SwrContext。
下⾯是⽰例程序的⼀个流程图:
[3] ⽰例的代码。
/**
fprintf格式* @example resampling_audio.c
* libswresample API use example.
*/
#include <libavutil/opt.h>
#include <libavutil/channel_layout.h>
#include <libavutil/samplefmt.h>
#include <libswresample/swresample.h>
static int get_format_from_sample_fmt(const char **fmt,
enum AVSampleFormat sample_fmt)
{
int i;
struct sample_fmt_entry {
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
} sample_fmt_entries[] = {
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
};
*fmt = NULL;
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
if (sample_fmt == entry->sample_fmt) {
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
return 0;
}
}
fprintf(stderr,
"Sample format %s not supported as output format\n",
av_get_sample_fmt_name(sample_fmt));
return AVERROR(EINVAL);
}
/**
* Fill dst buffer with nb_samples, generated starting from t.
*/
static void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
{
int i, j;
double tincr = 1.0 / sample_rate, *dstp = dst;
const double c = 2 * M_PI * 440.0;
/* generate sin tone with 440Hz frequency and duplicated channels */
for (i = 0; i < nb_samples; i++) {
*dstp = sin(c * *t);
for (j = 1; j < nb_channels; j++)
dstp[j] = dstp[0];
dstp += nb_channels;
*t += tincr;
}
}
int main(int argc, char **argv)
{
int64_t src_ch_layout = AV_CH_LAYOUT_STEREO, dst_ch_layout = AV_CH_LAYOUT_SURROUND;
int src_rate = 48000, dst_rate = 44100;
uint8_t **src_data = NULL, **dst_data = NULL;
int src_nb_channels = 0, dst_nb_channels = 0;
int src_linesize, dst_linesize;
int src_nb_samples = 1024, dst_nb_samples, max_dst_nb_samples;
enum AVSampleFormat src_sample_fmt = AV_SAMPLE_FMT_DBL, dst_sample_fmt = AV_SAMPLE_FMT_S16; const char *dst_filename = NULL;
FILE *dst_file;
int dst_bufsize;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论