1. 程式人生 > >SwrContext重取樣結構體

SwrContext重取樣結構體

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格式