音頻轉換主要API
swr_alloc_set_opts
設置轉換的參數
/**
如果需要,分配SwrContext并設置/重置公共參數。
此函數不需要使用swr_alloc()分配。 另一方面,swr_alloc()可以使用swr_alloc_set_opts()在分配的上下文上設置參數。
* 初始化resampler
* @param s 現有的Swr上下文(如果可用),否則為NULL
* @param out_ch_layout 輸出通道布局(AV_CH_LAYOUT_ *)
* @param out_sample_fmt 輸出樣本格式(AV_SAMPLE_FMT_ *)
* @param out_sample_rate 輸出采樣率(頻率,單位:Hz)
* @param in_ch_layout 輸入通道布局(AV_CH_LAYOUT_ *)
* @param in_sample_fmt 輸入樣本格式(AV_SAMPLE_FMT_ *)
* @param in_sample_rate 輸入采樣率(頻率,Hz)
* @param log_offset logging level offset
* @param log_ctx 父日志記錄上下文,可以為NULL
返回 錯誤時為NULL,否則分配上下文
*/
truct 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);
swr_convert
在上面轉換參數設置后,進行音頻轉換
/**
swr_convert 音頻數據轉換 (使用avcodec_decode_audio4函數來解碼音頻,但解碼得到的數據類型為float 4bit,而播放器播放的格式一般為S16(signed 16bit),就需要對解碼得到的數據進行轉換) in和in_count可以設置為0,以清除最后幾個樣本
如果提供的輸入多于輸出空間,則將緩沖輸入。 您可以通過使用swr_get_out_samples()檢索給定數量的輸入樣本的所需數量的輸出樣本的上限來避免這種緩沖。 轉換將直接運行而無需復制。
參數1 s: 分配的Swr上下文,并設置了參數
參數2 out: 輸出緩沖區,如果打包了音頻,則僅需要設置第一個
參數3 out_count: 每通道樣本中可用于輸出的空間量
參數4 in: 輸入緩沖區,在打包音頻的情況下僅需要設置第一個
參數5 in_count: 一個通道中可用的輸入樣本數
返回每個通道輸出的樣本數,錯誤時為負值
*/
int swr_convert(
struct SwrContext *s,
uint8_t **out,
int out_count,
const uint8_t **in ,
int in_count);
音頻轉換的原則是時長不變,不管轉換成何種格式,音頻總時長一樣
影響音頻播放時長的因素是每幀的采樣數和采樣率。
現在有mp3 每幀1152, 采樣率48000
aac 每幀1024, 采樣率44100
44100的aac每幀的播放時長=1024/44100.每秒有44100/1024幀,每個aac采樣的播放時長是1/44100秒
48000的mp3,每幀的播放時長=1152/48000,每秒有48000/1152幀。每個mp3采樣的播放時長是1/48000秒
這里我們就能看出,不可能一個aac幀轉出一個mp3幀,比例不可能1:1 。具體能轉多少,需要計算。這就是上面的轉換在干的事,到底在轉換什么,實質就是轉換一個每幀aac里面有1024個采樣,看能轉出多個mp3性質的采樣。
把一幀aac變成一幀mp3,能從每幀aac的1024個采樣身上重采樣出多少個mp3幀的采樣,這個值記作K,就是上面的dst_nb_samples
根據我們的音頻總時長不變原則,
(44100/1024) * K * (1/48000)=1秒 (src_rate/src_nb_samples =dst_rate/K)
即1秒鐘的aac總幀數每個aac幀能轉換的mp3采樣數 每個mp3采樣的播放時長=轉換出來的mp3也是1s
計算得K=1114.57
1114.57是不夠一幀mp3幀的,這個數也是一個計算出來的理論值,實際采樣個數肯定也不可能是一個小數,實際到底轉了多少,sws_convert函數的返回值告訴你,實際編碼過程中,我們也是通過累計的方式,夠了1152個采樣,我們才組裝出一個mp3幀
swr_convert
返回的輸出樣本數,可以根據輸入樣本數計算出來
條件1:
首先需要滿足: out_count(輸出通道可以接收的樣本空間)> in_count (輸入樣本數)
否則輸入的數據過大,輸出接收空間不足以接收所有的輸入數據
滿足條件1
后,可計算swr_convert
返回的輸出樣本數。
例如
1幀數據,
采樣數 pAudioFrame->nb_samples = 1024
輸入采樣率為 in_sample_rate = 44100
輸出采樣率 out_sample_rate = 44100 * 2
那么經過swr_convert
轉換出來的結果就近似 2048 (具體數值以swr_convert返回值為準)
也滿足上面的公式
(44100/1024) * K * (1/44100 * 2)=1秒
swr_alloc_set_opts
設置的輸出采樣頻率越高,swr_convert轉換的采樣數越大,才能保證時間一致