SwrContext重采样结构体

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011003120/article/details/81542347

SwrContext重采样结构体使用说明

在了解FFMPEG音频解码过程中,看到SwrContext重采样这个结构体,于是便详细了解下这个结构体相关的一些概念,记录下笔记。。。。

一、重采样

1)什么是重采样

所谓的重采样,就是改变音频的采样率、sample format、声道数等参数,使之按照我们期望的参数输出。

2)为什么要重采样

为什么要重采样?当然是原有的音频参数不满足我们的需求,比如在FFMPEG解码音频的时候,不同的音源有不同的格式,采样率等,在解码后的数据中的这些参数也会不一致(最新FFMPEG 16 解码音频后,音频格式为AV_SAMPLE_FMT_FLTP,这个参数应该是一致的),如果我们接下来需要使用解码后的音频数据做其他操作,而这些参数的不一致导致会有很多额外工作,此时直接对其进行重采样,获取我们制定的音频参数,这样就会方便很多。
再比如在将音频进行SDL播放时候,因为当前的SDL2.0不支持planar格式,也不支持浮点型的,而最新的FFMPEG 16年会将音频解码为AV_SAMPLE_FMT_FLTP格式,因此此时就需要我们对其重采样,使之可以在SDL2.0上进行播放。

3)可调节的参数

通过重采样,我们可以对 sample rate(采样率)、sample format(采样格式)、channel layout(通道布局,可以通过此参数获取声道数)。

二、SwrContext常用函数

1)swr_alloc

函数原型:struct SwrContext *swr_alloc(void);
此函数用于申请一个SwrContext结构体

2)swr_init

函数原型:int swr_init(struct SwrContext *s);
当设置好相关的参数后,使用此函数来初始化SwrContext结构体

3)swr_alloc_set_opts

函数原型: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);

此函数是比较重要的函数,分配SwrContext并设置/重置常用的参数。
相关参数解释如下:

 * @param s               Swr context, can be NULL
 * @param out_ch_layout   output channel layout (AV_CH_LAYOUT_*)
 * @param out_sample_fmt  output sample format (AV_SAMPLE_FMT_*).
 * @param out_sample_rate output sample rate (frequency in Hz)
 * @param in_ch_layout    input channel layout (AV_CH_LAYOUT_*)
 * @param in_sample_fmt   input sample format (AV_SAMPLE_FMT_*).
 * @param in_sample_rate  input sample rate (frequency in Hz)
 * @param log_offset      logging level offset
 * @param log_ctx         parent logging context, can be NULL

上面的参数即包含了输入输出参数中sample rate(采样率)、sample format(采样格式)、channel layout等参数。

4)swr_convert

函数原型:int swr_convert(struct SwrContext *s, uint8_t **out, int out_count,
                                const uint8_t **in , int in_count);

此函数便是将输入的音频按照定义的参数进行转换,并输出

5)swr_free

函数原型:void swr_free(struct SwrContext **s);
释放掉SwrContext结构体并将此结构体置为NULL;

三、基本用法

此结构体比较简单,参考FFMPEG中头文件 swresample.h中说明,基本用法如下:
申请结构体—>设置相关参数—>初始化—>转换—->释放结构体

申请结构体和设置相关参数有两种方法:
方法1:

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

方法2:

 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声道 48K采样率 AV_SAMPLE_FMT_FLTP格式转换为 双声道 44.1k采样率 AV_SAMPLE_FMT_S16格式

猜你喜欢

转载自blog.csdn.net/u011003120/article/details/81542347