顏色編碼
視頻轻专,本質(zhì)上就是一連串的靜態(tài)圖片的播放過程忆矛。因此我們對(duì)于視頻的的討論都可以回到圖片中去察蹲。
對(duì)于圖片而言,可以分為兩種顏色編碼方法來表示圖片:RGB和YUV催训。
RGB
現(xiàn)如今我們使用的屏幕設(shè)備都是RGB屏幕洽议,主要有紅,綠漫拭,藍(lán)三種原色組成亚兄,其他的所有顏色都是這三種顏色通過比例組合而成。
由于RGB設(shè)備的普及采驻,所以圖片/視頻的展示都是使用RGB的顏色編碼方法來展示的审胚。
但是我們都知道一張RGB圖片占用的磁盤空間有多大,假如1920x1080的圖片礼旅,單個(gè)像素格式為RGB_888膳叨,就是一個(gè)像素占位24bit,那么一張圖片的大小則是:
size = 1920x1080x3 byte = 5.93M
YUV顏色編碼的圖片則可以實(shí)現(xiàn)RGB近似的效果占用空間卻明顯小于后者,它也是視頻在存儲(chǔ)時(shí)的主要顏色編碼形式痘系。
YUV
不同于RGB的顏色分類方法菲嘴,YUV則是把顏色分為亮度和色度。
Y指的是亮度(luma,Luminance),U汰翠,V則指的是色度龄坪,這種編碼方法在不同的領(lǐng)域名稱上會(huì)有細(xì)微的差別:比如YCbCr,Y'UV,YPbPr,這些都可以統(tǒng)稱為YUV复唤,一般YUV/Y‘UV都用于編碼電視信號(hào)(模擬信號(hào))健田,而YCbCr則用于編碼數(shù)字圖像。在本文中我們說到Y(jié)UV時(shí)佛纫,主要指的是YCbCr抄课。
Y:亮度分量唱星,(可以理解為圖像的黑白部分)
Cb:色度的藍(lán)色分量,(照片藍(lán)色部分去掉亮度Y)
Cr:色度的紅色分量跟磨,(照片紅色部分去掉亮度Y)
一張圖片通過YUV編碼方式進(jìn)行分離后的效果如下:
關(guān)于YUV,如果對(duì)于YUV取值范圍進(jìn)行細(xì)分還可以分為兩種類型:
- TV range(Limit range):Y∈[16,235]间聊,Cb∈[16-240] ,Cr∈[16-240] 抵拘,主要是廣播電視采用的數(shù)字標(biāo)準(zhǔn)哎榴。
- Full range:Y、Cb僵蛛、Cr∈[0-255] 尚蝌,主要是PC端采用的標(biāo)準(zhǔn),所以也稱PC range充尉。
YUV與RGB的轉(zhuǎn)換
YUV和RGB這兩種顏色編碼方法是可以相互轉(zhuǎn)換的飘言,也就是知道其中一個(gè)就可以求取另一個(gè),而而且這個(gè)轉(zhuǎn)換方法是由國際相關(guān)組織提供的一些固定的公式(當(dāng)然不同版本不同類型的協(xié)議公式有所不同):
以根據(jù)ITU-R BT.601 標(biāo)準(zhǔn)為例
在TV Range的的范圍下
// TV Range
RGB to YUV:
Y = 0.299R+0.587G+0.114B // Y本質(zhì)上就是從原圖得到的一張灰度圖
Cr = V = 0.713(R?Y)=0.500R?0.419G?0.081B
Cb = U = 0.564(B?Y)=?0.169R?0.331G+0.500B
YUV to RGB:
R = 1.164(Y?16)+1.596(V?128)
G = 1.164(Y?16)?0.813(V?128)?0.391(U?128)
B = 1.164(Y?16)+2.018(U?128)
//RGB的范圍是[0,255],Y的范圍是[16,235],UV的范圍是[16,239]
同樣的標(biāo)準(zhǔn)下驼侠,F(xiàn)ull range的公式則有所不同用:
RGB to YUV:
Y = 0.299 * R + 0.587 * G + 0.114 * B
Cr = V = -0.169 * R - 0.331 * G + 0.500 * B
Cb = U = 0.500 * R - 0.439 * G - 0.081 * B
YUV to RGB:
R = Y + 1.400V - 0.7
G = Y - 0.343U - 0.711V + 0.526
B = Y + 1.765U - 0.883
// RGB的范圍是[0,255],Y的范圍是[0,255],UV的范圍是[0,255]
YUV采樣方法
經(jīng)過大量研究實(shí)驗(yàn)表明姿鸿,視覺系統(tǒng)對(duì)色度的敏感度遠(yuǎn)小于亮度,因此再編碼YUV圖片時(shí)倒源,常常會(huì)保證Y分量數(shù)據(jù)不變苛预,相應(yīng)比例減少U V分量的數(shù)據(jù),但是圖像的質(zhì)量基本不會(huì)改變笋熬。
- 4:4:4表示4個(gè)Y,對(duì)應(yīng)4個(gè)Cb以及4個(gè)Cr热某。
- 完全采樣,占用空間size=wh3 byte
- 4:2:2 表示4個(gè)Y,對(duì)應(yīng)2個(gè)Cb以及2個(gè)Cr胳螟。
- size=wh2 byte昔馋,節(jié)省1/3空間
- 4:2:0 表示4個(gè)Y,對(duì)應(yīng)1個(gè)Cb以及1個(gè)Cr。
- size=wh1.5 byte 節(jié)省1/2的空間
- 4:1:1 表示4個(gè)Y,對(duì)應(yīng)1個(gè)Cb以及1個(gè)Cr糖耸。
- size = wh1.5 byte 節(jié)省1/2的空間
以上幾種采樣方法秘遏,YUV420是視頻圖片幀中最常用的采樣比例,在這個(gè)比例下蔬捷,存儲(chǔ)空間節(jié)省一半垄提,但是圖片質(zhì)量變化不大。
YUV存儲(chǔ)方式
對(duì)于YUV數(shù)據(jù)周拐,有兩種存儲(chǔ)方式:
- packed format
- 緊縮格式是把數(shù)據(jù)混合在一起铡俐,交錯(cuò)存儲(chǔ)。比如yuv422 packed可能是這樣的
- Planar format(主要的)
- 平面格式則是把不同的分量數(shù)據(jù)分開存儲(chǔ):先連續(xù)存儲(chǔ)所有的Y妥粟,在連續(xù)存儲(chǔ)所有的U审丘,然后V......(下面的例子主要以palanar為主)
YUV存儲(chǔ)格式
根據(jù)不同的采樣方式以及不同的存儲(chǔ)方式,可以生成不同的YUV存儲(chǔ)格式勾给。比如YV12/I420/YU12/NV12/NV21 都屬于 YUV420滩报。
YUV格式有YUY2锅知、YUYV、YVYU脓钾、UYVY售睹、AYUV、Y41P可训、Y411昌妹、Y211、IF09握截、IYUV飞崖、YV12、YVU9谨胞、YUV411固歪、YUV420等,其中比較常見的YUV420分為兩種:YUV420P和YUV420SP胯努。
YV12/I420/YU12
YV12與YV12都稱為YUV420P(Planar格式)牢裳,表示他們都是4:2:0,而且是Planar的存儲(chǔ)方式康聂。他倆的區(qū)別在于在分開存儲(chǔ)時(shí)贰健,u分量和v分量誰在前面(Y分量總是在最前面)胞四。
存儲(chǔ)示意圖
- YU12: YYYYYYYY UU VV
- YV12: YYYYYYYY VV UU
YU12格式在Android平臺(tái)中也稱作I420
YU12/I420存儲(chǔ)格式
YV12存儲(chǔ)格式
YV12的存儲(chǔ)方式就是把上圖中的U和V分量的存儲(chǔ)位置對(duì)調(diào)即可恬汁。
NV21/NV12格式
這兩種格式都屬于YUV420SP(Semi-Planar)格式,這種格式和planar類似,但是UV分量時(shí)交錯(cuò)存儲(chǔ)的辜伟。
因此NV21和NV12的區(qū)別主要在于UV分量交錯(cuò)存儲(chǔ)時(shí)氓侧,誰在前面:
- NV12: YYYYYYYY UVUV
- NV21: YYYYYYYY VUVU
NV12存儲(chǔ)格式
NV21存儲(chǔ)格式
在NV12的基礎(chǔ)上,把U和V的分量位置對(duì)調(diào)即可
雖然YUV的存儲(chǔ)格式繁多但是對(duì)于一般的開發(fā)者而言导狡,掌握了上述幾種基本可以滿足需要了约巷。
小結(jié)
顯示RGB
存儲(chǔ)YUV
視頻基本概念
復(fù)用(封裝)與解復(fù)用(解封裝)
-
muxer(復(fù)用)
- 把音頻,視頻旱捧,字幕合并到一個(gè)封裝格式中 .在Android中實(shí)現(xiàn)復(fù)用的是MediaMuxer
-
demuxer(解復(fù)用)
- 從媒體封裝格式把視頻独郎,音頻,字幕等拆分開來,在Android中枚赡,實(shí)現(xiàn)解復(fù)用的是MediaExtractor
幀率
即視頻在一秒鐘之內(nèi)的幀數(shù)氓癌,電影一般24,手機(jī)設(shè)備錄制一般30贫橙,60贪婉。
幀類型
視頻中存在三種幀,I幀卢肃,P幀疲迂,B幀:
- I幀: 也稱關(guān)鍵幀才顿,依靠自身的數(shù)據(jù)即可解碼出一幀圖像。編碼壓縮比例不高
- P幀:預(yù)測幀尤蒿,利用時(shí)間和空間的相關(guān)性郑气,依靠前一幀和自身來解碼處一幀數(shù)據(jù) 編碼壓縮比例較高
- B幀: 雙向預(yù)測幀,即需要利用前后兩幀的數(shù)據(jù)來解碼自身這一幀的數(shù)據(jù)腰池,編碼壓縮比例極高竣贪。
因?yàn)锽幀這種特殊的存在,所以未解碼的視頻流中巩螃,幀的解碼順序與播放順序是不一致的演怎。
假如正常幀播放順序是I B P,那么在視頻流中這三幀的順序應(yīng)該是I P B,因?yàn)锽幀的生成需要前后兩幀數(shù)據(jù)避乏,所以會(huì)出現(xiàn)先解碼P幀爷耀,再解碼B幀的情況。
一般視頻中I幀較少拍皮,P幀歹叮,B幀占大多數(shù),所以才能把一部電影壓縮到幾個(gè)G的大小铆帽。
PTS和DTS
- PTS 顯示時(shí)間戳咆耿。指示幀應(yīng)該在什么時(shí)間點(diǎn)被呈現(xiàn)給用戶。PTS 是在解碼后確定的時(shí)間戳爹橱,用于視頻幀或音頻幀的渲染或播放順序
- DTS 解碼時(shí)間戳萨螺。 指示解碼器應(yīng)該在什么時(shí)間點(diǎn)開始解碼該幀(解碼順序)。DTS 是在解碼之前確定的時(shí)間戳愧驱,由解碼器按正確的順序解碼幀慰技。(它是在編碼時(shí)由編碼器設(shè)置的)
有了解碼時(shí)間戳,就可以保證I/P/B幀的按照正確順序解碼组砚,有了PTS吻商,則可以保證I/P/B幀的按照正確順序播放
音視頻同步
由于我們說的視頻往往是指音頻+視頻,而這兩者又是獨(dú)立的數(shù)據(jù)糟红,分別由獨(dú)立的設(shè)備進(jìn)行播放艾帐,因此再播放時(shí),往往需要主要音視頻的同步盆偿。音視頻同步的基本原理就是管理音視頻的數(shù)據(jù)柒爸,按照PTS的時(shí)間順序播放。
實(shí)際操作來看陈肛,一般需要選取一個(gè)參考時(shí)間軸揍鸟,這個(gè)參考每次音頻或者視頻解碼完成之后,通過比對(duì)現(xiàn)實(shí)時(shí)間戳和參考時(shí)間軸時(shí)間來控制播放進(jìn)度。
而這個(gè)參考時(shí)間軸阳藻,可以選擇音頻時(shí)間軸晰奖,視頻時(shí)間軸,或獨(dú)立時(shí)間軸腥泥,一般選擇獨(dú)立時(shí)間軸匾南。
編碼標(biāo)準(zhǔn)
前面雖然講到,從RGB轉(zhuǎn)向YUV的過程是可以顯著節(jié)省視頻的存儲(chǔ)空間蛔外,但是這遠(yuǎn)遠(yuǎn)不夠蛆楞,最終視頻存儲(chǔ)空間還是要靠編碼來進(jìn)行壓縮。因此市面上有很多對(duì)視頻幀進(jìn)行編碼的編碼標(biāo)準(zhǔn):h263,h264(重點(diǎn)),h265,vp8,vp9...
其中,H.264是目前使用最廣泛夹厌,支持最廣泛的適配編碼器豹爹,而隨著4K/8K的逐步普及,視頻編碼器應(yīng)該會(huì)逐漸向H.265 過渡矛纹。
視頻編碼標(biāo)準(zhǔn)的算法一般是非常復(fù)雜的臂聋,對(duì)于一般開發(fā)者而言不需要深入接觸
封裝格式
對(duì)于視頻而言,一般指的是視頻+音頻或南。而這兩種數(shù)據(jù)本質(zhì)上是獨(dú)立的數(shù)據(jù)孩等,因此需要把他們按照特定的規(guī)則協(xié)議封裝成一個(gè)文件讓播放器播放。
目前市面上主要的封裝格式有:MP4(主要),MKV,AVI,FLV,TS...
這些封裝格式主要可以分為兩類:存儲(chǔ)類采够,流媒體類
- 存儲(chǔ)類: 面向存儲(chǔ)使用
- MP4,MKV,AVI
- 流媒體類: 面向流媒體使用
- FLV,TS
之所以會(huì)出現(xiàn)這樣的區(qū)別肄方,主要是看封裝格式是否能支持一遍下載,一邊解碼蹬癌,一邊播放权她。
資料參考
https://ibabyblue.github.io/2020/04/27/YUV%E4%B8%8ERGB%E6%A0%BC%E5%BC%8F%E8%BD%AC%E6%8D%A2/