音頻幀、視頻幀及其同步

PS: 本周的關(guān)鍵詞「習(xí)慣」
上一篇中介紹了音視頻開發(fā)中的基礎(chǔ)知識,今天介紹下音頻幀、視頻幀的主要參數(shù)和分析方法,以及音視頻的同步等,主要內(nèi)容如下:
音頻幀
視頻幀
PTS與DTS
音視頻同步
音頻幀
音頻幀的概念沒有視頻幀那么清晰,幾乎所有視頻編碼格式都可以簡單的認(rèn)為一幀就是編碼后的一副圖像,而音頻幀會因編碼格式的不同而不同,如 PCM 音頻流可以直接進(jìn)行播放,下面以 MPEG 音頻幀格式為例介紹音頻幀。
幀大小
幀大小指每幀的采樣數(shù),這個值的恒定的,具體如下:

FrameSize
幀長度
幀長度指壓縮時每一幀的長度,包括幀頭及填充位,因為有填充和比特率變換,所以幀長度不是恒定的,這個填充位具體從幀頭中第 9 位獲取,如果是 0 則無填充位,如果是 1 則有填充位,來看下關(guān)于填充位的說明:
Padding is used to fit the bit rates exactly. For an example: 128k 44.1kHz layer II uses a lot of 418 bytes and some of 417 bytes long frames to get the exact 128k bitrate. For Layer I slot is 32 bits long, for Layer II and Layer III slot is 8 bits long.
可知,Layer Ⅰ 的填充位是 4 字節(jié),Layer Ⅱ 和 Layer Ⅲ 的填充位是 1 字節(jié),當(dāng)讀取 MPEG 文件時必須計算該值以便找到相鄰的幀,幀長度的計算公式如下:
1// Layer I(SampleSize = 384)?單位:byte
2FrameLengthInBytes?=?SampleSize?/?8?*?BitRate?/?SampleRate?+?Padding?*?4
3FrameLengthInBytes?=?48?*?BitRate?/?SampleRate?+?Padding?*?4
4// Layer II & III(SampleSize = 1152)?單位:byte
5FrameLengthInBytes?=?SampleSize?/?8?/?SampleRate?+?Padding
6FrameLengthInBytes?=?144?*?BitRate?/?SampleRate?+?Padding
其中 SampleSize表示每幀采樣數(shù),其值是固定的,可在幀大小小節(jié)中查看,Padding 表示填充位,BitRate 表示比特率,SampleRate 表示采樣率,比特率和采樣率的值可在幀頭中獲取。

如果一個 MP3 音頻文件比特率為 320kbps、采樣率為 44.1KHz、無填充位,則該文件的幀長度為 144 x 320 / 44.1 ≈ 1044 字節(jié)。
比特率
可以從 MPEG 音頻幀頭 12~15 位獲取比特率,單位 kbps,參考如下:

Bitrate
針對表格中的說明:
V1:MPEG Version 1
V2:MPEG Version 2 and Version 2.5
L1:Layer Ⅰ
L2:Layer Ⅱ
L3:Layer Ⅲ
MPEG 文件可能具有可變的比特率,意味著比特率會發(fā)生變化,這里知道比特率的獲取即可。
采樣率
可以從 MPEG 音頻幀頭 10~11 位獲取采樣率,單位 Hz,參考如下:

SampleSize
每幀的持續(xù)時間
一幀持續(xù)時間計算公式如下:
1//?單位?ms
2FrameTime?=?SampleSize?/?SampleRate?*?1000
其中 SampleSize 表示采樣數(shù),也就是幀大小,SampleRate 表示采樣率。

如采樣率為 44.1KHz 的 MP3 ?音頻文件每幀的持續(xù)時間為 1152 / 44100 * 1000 ≈ 26 ms,這就是經(jīng)常聽到的 mp3 每幀播放時間固定為26ms的由來。
視頻幀
在視頻壓縮技術(shù)中,視頻幀采用不同的壓縮算法來減少數(shù)據(jù)量,通常只編碼圖像之間的差異之處,相同的元素信息則不必重復(fù)發(fā)送,視頻幀的不同算法一般稱之為圖片類型(picture types)或者幀類型(frame types),主要的三種圖片類型分別是 I、P 和 B,其特征如下:
I 幀:幀內(nèi)編碼幀,通常是每個 GOP(下文介紹) 的第一幀,可壓縮性最低,無需其他視頻幀即可解碼,可以說是一張完整的圖片,通常,I 幀用于隨機(jī)訪問,并用作其他圖片解碼的參考。
P 幀:前向預(yù)測幀,表示與前一幀(I 或 P 幀)之間的差別,需要參考前面的 I 幀或 P 幀才能生成完整的圖片,相較 I 幀更具壓縮性,節(jié)省了空間,所以 P 幀也成為增量幀。
B 幀:雙向預(yù)測編碼幀,表示與前后兩幀的差異,需要參考前面的 I 幀或 P 幀及后面的 P 幀來生成一張完成的圖片,壓縮性最大。
上面說的幀或圖片通常會分為幾個宏塊(Macroblock),宏塊是運(yùn)動預(yù)測的基本單位,一個完整的圖像通常被分為幾個宏塊,如 MPEG-2 和較早期的編解碼器定義宏塊都是 8×8 像素,以宏塊為基準(zhǔn)選擇特定的預(yù)測類型,而非整個圖像都使用相同的預(yù)測類型,具體如下:
I 幀:只包含節(jié)點宏塊。
P 幀:可含有節(jié)點宏區(qū)塊或預(yù)測宏區(qū)塊。
B 幀:可含有節(jié)點、預(yù)測和前后預(yù)測宏區(qū)塊。
下面來看下 I 幀、P 幀、B 幀的示意圖如下:

在 H.264 / MPEG-4 AVC 標(biāo)準(zhǔn)中,預(yù)測類型的粒度降低到切片(Slice)級別,切片是幀的空間上不同的區(qū)域,該區(qū)域與同一幀中的任何其他區(qū)域分開進(jìn)行編碼,I 切片,P 切片和 B 切片取代了 I、P 和 B 幀,這部分內(nèi)容暫時了解這么多。
前面提到了 GOP,它是 Group of pictures 的縮寫,可譯為圖片組,每個 GOP 都以 I 幀為起始點,其他為 P 幀和 B 幀,如下圖所示:

上圖中顯示的順序為:
1I1、B2、B3、B4、P5、B6、B7、B8、P9、B10、B11、B12、I13
編解碼順序為:
1I1、P5、B2、B3、B4、P9、B6、B7、B8、I13、B10、B11、B12
其中下標(biāo)數(shù)字表示在原始幀數(shù)據(jù)中 PTS,這里可以理解為 GOP 中的位置。
DTS與PTS
DTS(Decoding Time Stamp):解碼時間戳,表示壓縮幀的解碼時間,相當(dāng)于告訴播放器什么時候解碼這一幀的數(shù)據(jù)
PTS(Presentation Time Stamp):顯示時間戳,表示將壓縮幀解碼后得到的原始幀的顯示時間,相當(dāng)于告訴播放時什么時候顯示這一陣的數(shù)據(jù)。
對于音頻來說,DTS 和 PTS 是相同的,對于視頻來說,由于 B 幀是雙向預(yù)測幀,這就導(dǎo)致 DTS 與 PTS 不同,如果每個 GOP 沒有 B 幀,則 DTS 和 PTS 相同,反之則 DTS 與 PTS 不同,舉例如下:

DTS、PTS
當(dāng)接收端接收到碼流進(jìn)行解碼后的幀的順序顯然不是正確的順序,需要根據(jù) PTS 進(jìn)行重新排序再顯示。
音視頻同步
先大概介紹一下視頻播放的過程,麥克風(fēng)和攝像頭采集數(shù)據(jù)后,分別通過音頻、視頻編碼,再通過復(fù)用,也就是將音視頻進(jìn)行格式封裝生成媒體文件,當(dāng)收到一個媒體文件,需要解復(fù)用將音視頻分開,再分別通過音頻、視頻解碼,然后音視頻獨(dú)立播放,因為播放速率的差異就會出現(xiàn)音視頻不同的問題,音頻和視頻播放對應(yīng)的兩個指標(biāo)如下:
音頻:采樣率
視頻:幀率
聲卡和顯卡一般是按照每幀數(shù)據(jù)進(jìn)行播放的,所以要計算音頻和視頻每幀的播放時長,還是一樣,舉個例子:

從上文中已知采樣率為 44.1KHz 的 MP3 ?音頻文件的每幀持續(xù)時長為 26 ms,如果此時視頻的幀率為 30fps,則視頻幀的每幀持續(xù)時長為 1000 / 30 ≈ 33ms,如果在理想情況下能夠按照計算出了數(shù)值進(jìn)行播放,則音視頻可以看做是同步的。
實際情況是因為各種原因?qū)е乱粢曨l不同步,如每幀解碼和渲染的時長有差別,色彩豐富的視頻幀可能就比色彩單一的視頻幀解碼渲染更慢以及計算的誤差等,音視頻同步方式主要有三種:
視頻同步到音頻
音頻同步到視頻
音視頻同步到外部時鐘
