音频重采样,采样格式转换和混合库。
与lswr的交互是通过SwrContext完成的,SwrContext被分配给swr_alloc()或swr_alloc_set_opts()。 它是不透明的,所以所有参数必须使用AVOptions API设置。
为了使用lswr,你需要做的第一件事就是分配SwrContext。 这可以使用swr_alloc()或swr_alloc_set_opts()来完成。 如果您使用前者,则必须通过AVOptions API设置选项。 后一个函数提供了相同的功能,但它允许您在同一语句中设置一些常用选项。
例如,以下代码将设置从平面浮动样本格式到交织的带符号16位整数的转换,从48kHz到44.1kHz的下采样,以及从5.1声道到立体声的下混合(使用默认混合矩阵)。 这是使用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
一旦设置了所有值,它必须用swr_init()初始化。 如果需要更改转换参数,可以使用AVOptions来更改参数,如上面第一个例子所述; 或者使用swr_alloc_set_opts(),但是第一个参数是分配的上下文。 您必须再次调用swr_init()。
转换本身通过重复调用swr_convert()来完成。 请注意,如果提供的输出空间不足或采样率转换完成后,样本可能会在swr中缓冲,这需要“未来”样本。 可以随时通过使用swr_convert()(in_count可以设置为0)来检索不需要将来输入的样本。 在转换结束时,可以通过调用具有NULL in和in incount的swr_convert()来刷新重采样缓冲区。
在转换过程中使用的样本可以使用libavutil示例操作API进行管理,包括以下示例中使用的av_samples_alloc()函数。
输入和输出之间的延迟可以随时通过使用swr_get_delay()找到。
以下代码演示了假设上面的参数和调用者定义的函数get_input()和handle_output())的转换循环:
uint8_t **input;
int in_samples;
while (get_input(&input, &in_samples)) {
uint8_t *output;
int out_samples = av_rescale_rnd(swr_get_delay(swr, 48000) +
in_samples, 44100, 48000, AV_ROUND_UP);
av_samples_alloc(&output, NULL, 2, out_samples,
AV_SAMPLE_FMT_S16, 0);
out_samples = swr_convert(swr, &output, out_samples,
input, in_samples);
handle_output(output, out_samples);
av_freep(&output);
}
转换完成后,必须使用swr_free()释放转换上下文和与之相关的所有内容。 也可以使用swr_close()函数,但它主要是为了与libavresample兼容,不需要调用。
如果在swr_free()之前没有完全刷新数据,则不会有内存泄漏。
一、函数
const AVClass * | swr_get_class (void) |
它可以与AV_OPT_SEARCH_FAKE_OBJ结合使用来检查选项。
查看:av_opt_find().
返回:SwrContext的AVClass
二、选项常数
这些常量用于lswr的AVOptions接口。
enum | SwrEngine { SWR_ENGINE_SWR, SWR_ENGINE_SOXR, SWR_ENGINE_NB } |
enum | SwrFilterType { SWR_FILTER_TYPE_CUBIC, SWR_FILTER_TYPE_BLACKMAN_NUTTALL, SWR_FILTER_TYPE_KAISER } |
#define | SWR_FLAG_RESAMPLE 1 |
struct SwrContext * | swr_alloc (void) |
int | swr_init (struct SwrContext *s) |
int | swr_is_initialized (struct SwrContext *s) |
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) |
void | swr_free (struct SwrContext **s) |
void | swr_close (struct SwrContext *s) |
int | swr_convert (struct SwrContext *s, uint8_t **out, int out_count, const uint8_t **in, int in_count) |
int64_t | swr_next_pts (struct SwrContext *s, int64_t pts) |
int | swr_set_compensation (struct SwrContext *s, int sample_delta, int compensation_distance) |
int | swr_set_channel_mapping (struct SwrContext *s, const int *channel_map) |
int | swr_build_matrix (uint64_t in_layout, uint64_t out_layout, double center_mix_level, double surround_mix_level, double lfe_mix_level, double rematrix_maxval, double rematrix_volume, double *matrix, int stride, enum AVMatrixEncoding matrix_encoding, void *log_ctx) |
int | swr_set_matrix (struct SwrContext *s, const double *matrix, int stride) |
int | swr_drop_output (struct SwrContext *s, int count) |
int | swr_inject_silence (struct SwrContext *s, int count) |
int64_t | swr_get_delay (struct SwrContext *s, int64_t base) |
int | swr_get_out_samples (struct SwrContext *s, int in_samples) |
unsigned | swresample_version (void) |
const char * | swresample_configuration (void) |
const char * | swresample_license (void) |
int | swr_convert_frame (SwrContext *swr, AVFrame *output, const AVFrame *input) |
int | swr_config_frame (SwrContext *swr, const AVFrame *out, const AVFrame *in) |