最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

音視頻八股文(11)-- ffmpeg 音頻重采樣

2023-05-11 21:33 作者:福大大架構(gòu)師每日一題  | 我要投稿

1重采樣

1.1 什么是重采樣

所謂的重采樣,就是改變?頻的采樣率、sample format、聲道數(shù)等參數(shù),使之按照我們期望的參數(shù)輸出。

1.2 為什么要重采樣

為什么要重采樣?當(dāng)然是原有的?頻參數(shù)不滿?我們的需求,?如在FFmpeg解碼?頻的時候,不同的?源有不同的格式,采樣率等,在解碼后的數(shù)據(jù)中的這些參數(shù)也會不?致(最新FFmpeg 解碼?頻后,?頻格 式為AV_SAMPLE_FMT_FLTP,這個參數(shù)應(yīng)該是?致的),如果我們接下來需要使?解碼后的?頻數(shù)據(jù)做其他操作,?這些參數(shù)的不?致導(dǎo)致會有很多額外?作,此時直接對其進(jìn)?重采樣,獲取我們制定的?頻參數(shù),這樣就會?便很多。

再?如在將?頻進(jìn)?SDL播放時候,因為當(dāng)前的SDL2.0不?持planar格式,也不?持浮點(diǎn)型的,?最新的FFMPEG 16年會將?頻解碼為AV_SAMPLE_FMT_FLTP格式,因此此時就需要我們對其重采樣,使之可以在SDL2.0上進(jìn)?播放。

2 對應(yīng)參數(shù)解析

2.1 采樣率

采樣設(shè)備每秒抽取樣本的次數(shù)

2.2采樣格式及量化精度(位寬)

每種?頻格式有不同的量化精度(位寬),位數(shù)越多,表示值就越精確,聲?表現(xiàn)?然就越精準(zhǔn)。FFMpeg中?頻格式有以下?種,每種格式有其占?的字節(jié)數(shù)信息(libavutil/samplefmt.h):

enum?AVSampleFormat?{
????AV_SAMPLE_FMT_NONE?=?-1,
????AV_SAMPLE_FMT_U8,?///<?unsigned?8?bits
????AV_SAMPLE_FMT_S16,?///<?signed?16?bits
????AV_SAMPLE_FMT_S32,?///<?signed?32?bits
????AV_SAMPLE_FMT_FLT,?///<?float
????AV_SAMPLE_FMT_DBL,?///<?double
????AV_SAMPLE_FMT_U8P,?///<?unsigned?8?bits,?planar
????AV_SAMPLE_FMT_S16P,?///<?signed?16?bits,?planar
????AV_SAMPLE_FMT_S32P,?///<?signed?32?bits,?planar
????AV_SAMPLE_FMT_FLTP,?///<?float,?planar
????AV_SAMPLE_FMT_DBLP,?///<?double,?planar
????AV_SAMPLE_FMT_S64,?///<?signed?64?bits
????AV_SAMPLE_FMT_S64P,?///<?signed?64?bits,?planar
????AV_SAMPLE_FMT_NB?///<?Number?of?sample?formats.?DO?NOT?USE?if?linking?dynamically
};

2.3 分?(plane)和打包(packed)

以雙聲道為例,帶P(plane)的數(shù)據(jù)格式在存儲時,其左聲道和右聲道的數(shù)據(jù)是分開存儲的,左聲道的數(shù)據(jù)存儲在data[0],右聲道的數(shù)據(jù)存儲在data[1],每個聲道的所占?的字節(jié)數(shù)為linesize[0]和linesize[1];

不帶P(packed)的?頻數(shù)據(jù)在存儲時,是按照LRLRLR...的格式交替存儲在data[0]中,linesize[0]表示總的數(shù)據(jù)量。

2.4 聲道分布(channel_layout)

聲道分布在FFmpeg\libavutil\channel_layout.h中有定義,?般來說?的?較多的是AV_CH_LAYOUT_STEREO(雙聲道)和AV_CH_LAYOUT_SURROUND(三聲道),這兩者的定義如下:

#define?AV_CH_LAYOUT_STEREO?(AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT)
#define?AV_CH_LAYOUT_SURROUND?(AV_CH_LAYOUT_STEREO?|?AV_CH_FRONT_CENTER)

2.5 ?頻幀的數(shù)據(jù)量計算

?幀?頻的數(shù)據(jù)量(字節(jié))=channel數(shù) * nb_samples樣本數(shù) * 每個樣本占?的字節(jié)數(shù)

如果該?頻幀是FLTP格式的PCM數(shù)據(jù),包含1024個樣本,雙聲道,那么該?頻幀包含的?頻數(shù)據(jù)量是210244=8192字節(jié)。

AV_SAMPLE_FMT_DBL : 210248 = 16384

2.6 ?頻播放時間計算

以采樣率44100Hz來計算,每秒44100個sample,?正常?幀為1024個sample,可知每幀播放時間/1024=1000ms/44100,得到每幀播放時間=1024*1000/44100=23.2ms (更精確的是23.21995464852608)。

?幀播放時間(毫秒) = nb_samples樣本數(shù) *1000/采樣率 =

(1)1024*1000/44100=23.21995464852608ms ->約等于 23.2ms,精度損失了0.011995464852608ms,如果累計10萬幀,誤差>1199毫秒,如果有視頻?起的就會有?視頻同步的問題。 如果按著23.2去計算pts(0 23.2 46.4 )就會有累積誤差。

(2)1024*1000/48000=21.33333333333333ms

3 FFmpeg重采樣API

分配?頻重采樣的上下?

struct?SwrContext?*swr_alloc(void);

當(dāng)設(shè)置好相關(guān)的參數(shù)后,使?此函數(shù)來初始化SwrContext結(jié)構(gòu)體

int?swr_init(struct?SwrContext?*s);

分配SwrContext并設(shè)置/重置常?的參數(shù)。

struct?SwrContext*?swr_alloc_set_opts(struct?SwrContext*?s,?//??頻重采樣上下?
????int64_t?out_ch_layout,?//?輸出的layout,?如:5.1聲道
????enum?AVSampleFormat?out_sample_fmt,?//?輸出的采樣格式。Float,?S16,?般選?是s16?絕?部分聲卡?持
????int?out_sample_rate,?//輸出采樣率
????int64_t?in_ch_layout,?//?輸?的layout
????enum?AVSampleFormat?in_sample_fmt,?//?輸?的采樣格式
????int?in_sample_rate,?//?輸?的采樣率
????int?log_offset,?//??志相關(guān),不?管先,直接為0
????void*?log_ctx?//??志相關(guān),不?管先,直接為NULL
);

將輸?的?頻按照定義的參數(shù)進(jìn)?轉(zhuǎn)換并輸出

int?swr_convert(struct?SwrContext*?s,?//??頻重采樣的上下?
????uint8_t**?out,?//?輸出的指針。傳遞的輸出的數(shù)組
????int?out_count,?//輸出的樣本數(shù)量,不是字節(jié)數(shù)。單通道的樣本數(shù)量。
????const?uint8_t**?in,?//輸?的數(shù)組,AVFrame解碼出來的DATA
????int?in_count?//?輸?的單通道的樣本數(shù)量。
);

in和in_count可以設(shè)置為0,以最后刷新最后?個樣本。

釋放掉SwrContext結(jié)構(gòu)體并將此結(jié)構(gòu)體置為NULL;

void?swr_free(struct?SwrContext?**s);

?頻重采樣,采樣格式轉(zhuǎn)換和混合庫。與lswr的交互是通過SwrContext完成的,SwrContext被分配給swr_alloc()或 swr_alloc_set_opts()。 它是不透明的,所以所有參數(shù)必須使?AVOptions API設(shè)置。為了使?lswr,你需要做的第?件事就是分配SwrContext。 這可以使?swr_alloc()或 swr_alloc_set_opts()來完成。 如果您使?前者,則必須通過AVOptions API設(shè)置選項。 后?個函數(shù)提供了相同的功能,但它允許您在同?語句中設(shè)置?些常?選項。

例如,以下代碼將設(shè)置從平?浮動樣本格式到交織的帶符號16位整數(shù)的轉(zhuǎn)換,從48kHz到44.1kHz的下采 樣,以及從5.1聲道到?體聲的下混合(使?默認(rèn)混合矩陣)。 這是使?swr_alloc()函數(shù)。

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

?旦設(shè)置了所有值,它必須?swr_init()初始化。 如果需要更改轉(zhuǎn)換參數(shù),可以使?AVOptions來更改參數(shù),如上?第?個例?所述; 或者使?swr_alloc_set_opts(),但是第?個參數(shù)是分配的上下?。 您必須再次調(diào)?swr_init()。?旦設(shè)置了所有值,它必須?swr_init()初始化。 如果需要更改轉(zhuǎn)換參數(shù),可以使?AVOptions來更改參數(shù),如上?第?個例?所述; 或者使?swr_alloc_set_opts(),但是第?個參數(shù)是分配的上下?。 您必須再次調(diào)?swr_init()。 轉(zhuǎn)換本身通過重復(fù)調(diào)?swr_convert()來完成。 請注意,如果提供的輸出空間不?或采樣率轉(zhuǎn)換完成后,樣本可能會在swr中緩沖,這需要“未來”樣本。 可以隨時通過使?swr_convert()(in_count可以設(shè)置為0)來檢索不需要將來輸?的樣本。 在轉(zhuǎn)換結(jié)束時,可以通過調(diào)?具有NULL in和in incount的swr_convert()來刷新重采樣緩沖區(qū)。

4 go代碼

見?moonfdd/ffmpeg-go

圖片
在這里插入圖片描述

福大大架構(gòu)師每日一題

java當(dāng)死,golang當(dāng)立。最新面試題,涉及golang,rust,mysql,redis,云原生,算法,分布式,網(wǎng)絡(luò),操作系統(tǒng)。

502篇原創(chuàng)內(nèi)容

公眾號



音視頻八股文(11)-- ffmpeg 音頻重采樣的評論 (共 條)

分享到微博請遵守國家法律
宁明县| 紫阳县| 长岭县| 巨鹿县| 京山县| 房产| 正蓝旗| 涟水县| 五大连池市| 新津县| 肇源县| 凤城市| 红原县| 温泉县| 肇源县| 泸西县| 天全县| 隆回县| 兴安县| 斗六市| 阿图什市| 尉犁县| 上思县| 三明市| 乐亭县| 冷水江市| 新民市| 思南县| 长汀县| 泽库县| 南部县| 兴城市| 麦盖提县| 武清区| 桂阳县| 英超| 宜黄县| 镇康县| 临汾市| 潍坊市| 洪江市|