H264视频编码原理
一、為什么要對視頻編碼
視頻是由一幀幀的圖像組成,就像gif圖片一樣。一般視頻為了不會讓人感覺到卡頓,一秒鐘至少需要16幀畫面(一般30幀)。加入該視頻是一個1280x720的分辨率,那么不經過編碼一秒鐘傳輸的大小為1280x720x60~=843M。所以不經過編碼的視頻根本沒法保存和傳輸。現在市面上主要將編碼分為兩大類H.264和MPEG。后面一種主要用于DVD,機頂盒等設備。h264編碼是一種主流的編碼格式。另外H265也屬于其中的一種,比如我們電影院播放的電影,一些高清的電視采用的就是這種編碼技術。
二、H264編碼規則
- 在相鄰的幾幅畫面中,一般有差別的像素是10%以內的點,亮度差值變化不超過20%,而色度差值的變化只有不到1%,所以對于一段變化不大的畫面,我們可以先編碼成一個完整的圖片幀A
- 隨后的B幀就不編碼全部圖像,只寫入A幀的差別,這樣B幀的大小只有完整幀大小的10%或者更小!B幀之后的C幀如果變化不大,我們可以繼續以參考B幀的方式進行編碼,依次循環下去。
- 這段圖像我們稱之為一個序列:序列就是有相同特點的一段數據。當某個圖像與之前的圖像變化很大,無法根據前面的幀來生成,我們就結束上一段序列,開啟下一段序列,也就是對這個圖像生成完整的幀A1,隨后的幀將參考A1幀,只寫入與A1差別的內容。這個序列就是Gop序列,我們也可以把它當作一個場景,比如場景A和場景B,場景A的背景是紅色,場景B的背景是綠色,那么A和B就是兩個序列。每個序列是從I幀開始的,并且是唯一的,后面是B幀和P幀。兩個I幀之間就是一個序列
三、H264編碼
I幀、P幀、B幀是如何生成的呢?前面說過,當兩個場景差異很大的時候,就會重新開始一個序列,那么這個序列就是從I幀開始的,也稱關鍵幀。那么與I幀相似度極高,到達95%以上,則被編碼成B幀;相似度達到70%編碼為P幀。I、P、B幀的如何編碼不需要我們自己實現,x264工具就已經幫我們完成了。
前面已經說過編碼的目的就是為了方便傳輸(指文件傳輸,網絡流傳輸等)。但是我們并不能把一幀幀傳過去,一幀的內容幾十k也是太大了,還需要細分才能更好的傳輸,所以我們需要更小的傳輸單元,保證更高的壓縮性、容錯性以及實時觀看性。那么就引入了NALU單元
四、NALU單元
上圖可以看到,一幀數據(一張圖片)是由很多個NALU單元組成,一個NALU單元分為兩部分:NAL頭和RBSP
1、NAL頭:標識NAL單元中的RBSP數據類型,其中,nal_unit_type為1, 2, 3, 4, 5的NAL單元稱為VCL的NAL單元,其他類型的NAL單元為非VCL的NAL單元
- 0:未規定
- 1:非IDR圖像中不采用數據劃分的片段
- 2:非IDR圖像中A類數據劃分片段
- 3:非IDR圖像中B類數據劃分片段
- 4:非IDR圖像中C類數據劃分片段
- 5:IDR圖像的片段
- 6:補充增強信息(SEI)
- 7:序列參數集(SPS)
- 8:圖像參數集(PPS)
- 9:分割符
- 10:序列結束符
- 11:流結束符
- 12:填充數據
- 13:序列參數集擴展
- 14:帶前綴的NAL單元
- 15:子序列參數集
- 16 – 18:保留
- 19:不采用數據劃分的輔助編碼圖像片段
- 20:編碼片段擴展
- 21 – 23:保留
- 24 – 31:未規定
2、RBSP:又被成為切片,每個切片是由片頭和片數據組成,片數據是由若干個宏塊組成。包括序列參數集 SPS??和?圖像參數集 PPS?
3、SPS與PPS
概念:包含了初始化H.264編碼所需要的信息參數。包括編碼所用的profile,level,圖片的寬和高,deblock濾波器等
SPS:序列參數集,如標識符 seq_parameter_set_id、幀數及 POC 的約束、參考幀數目、解碼圖像尺寸和幀場編碼模式選擇標識 等等。
PPS:圖像參數集,其參數如標識符 pic_parameter_set_id、可選的 seq_parameter_set_id、熵編碼模式選擇標識、片組數目、初始量化參數和去方塊濾波系數調整標識等等。?
在H.264編碼中都是以"0x00 0x00 0x01"或者"0x00 0x00 0x00 0x01"為開始碼的,找到開始碼后,使用開始碼后的第一個字節的低5位判斷是否為7(sps)或8(pps),即data[4]&0x1f==7或data[4]&0x1f==8。然后對獲取的nal去掉開始碼之后進行base64編碼,得到的信息就可以用于sdp,sps,pps,需要用逗號隔開。
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的H264视频编码原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android GPS驱动
- 下一篇: [html] 如何让img自动适应di