1)YUV簡(jiǎn)介
YUV格式有兩大類:planar和packed饭望。
對(duì)于planar的YUV格式悔政,先連續(xù)存儲(chǔ)所有像素點(diǎn)的Y翁涤,緊接著存儲(chǔ)所有像素點(diǎn)的U桥言,隨后是所有像素點(diǎn)的V。
對(duì)于packed的YUV格式葵礼,每個(gè)像素點(diǎn)的Y,U,V是連續(xù)交*存儲(chǔ)的号阿。
YUV,分為三個(gè)分量鸳粉,“Y”表示明亮度(Luminance或Luma)扔涧,也就是灰度值;而“U”和“V” 表示的則是色度(Chrominance或Chroma)届谈,作用是描述影像色彩及飽和度枯夜,用于指定像素的顏色。
與我們熟知的RGB類似艰山,YUV也是一種顏色編碼方法湖雹,主要用于電視系統(tǒng)以及模擬視頻領(lǐng)域,它將亮度信息(Y)與色彩信息(UV)分離曙搬,沒(méi)有UV信息一樣可以顯示完整的圖像摔吏,只不過(guò)是黑白的鸽嫂,這樣的設(shè)計(jì)很好地解決了彩色電視機(jī)與黑白電視的兼容問(wèn)題。并且征讲,YUV不像RGB那樣要求三個(gè)獨(dú)立的視頻信號(hào)同時(shí)傳輸据某,所以用YUV方式傳送占用極少的頻寬。
2)YUV存儲(chǔ)格式
YUV碼流的存儲(chǔ)格式其實(shí)與其采樣的方式密切相關(guān)稳诚,主流的采樣方式有三種哗脖,YUV4:4:4瀑踢,YUV4:2:2扳还,YUV4:2:0,關(guān)于其詳細(xì)原理橱夭,可以通過(guò)網(wǎng)上其它文章了解氨距,這里我想強(qiáng)調(diào)的是如何根據(jù)其采樣格式來(lái)從碼流中還原每個(gè)像素點(diǎn)的YUV值,因?yàn)橹挥姓_地還原了每個(gè)像素點(diǎn)的YUV值棘劣,才能通過(guò)YUV與RGB的轉(zhuǎn)換公式提取出每個(gè)像素點(diǎn)的RGB值俏让,然后顯示出來(lái)。
用三個(gè)圖來(lái)直觀地表示采集的方式吧茬暇,以黑點(diǎn)表示采樣該像素點(diǎn)的Y分量首昔,以空心圓圈表示采用該像素點(diǎn)的UV分量。
先記住下面這段話糙俗,以后提取每個(gè)像素的YUV分量會(huì)用到勒奇。
1. YUV?4:4:4采樣,每一個(gè)Y對(duì)應(yīng)一組UV分量8+8+8 = 24bits,3個(gè)字節(jié)巧骚。
2. YUV?4:2:2采樣赊颠,每?jī)蓚€(gè)Y共用一組UV分量,一個(gè)YUV占8+4+4 = 16bits 2個(gè)字節(jié)。
3. YUV?4:2:0采樣劈彪,每四個(gè)Y共用一組UV分量一個(gè)YUV占8+2+2 = 12bits? 1.5個(gè)字節(jié)竣蹦。
3)YUV420類型
3.1) YUV420p和YUV420sp區(qū)別
因?yàn)閅UV420比較常用, 在這里就重點(diǎn)介紹YUV420沧奴。YUV420分為兩種:YUV420p和YUV420sp痘括。
YUV420sp格式如下圖:
YUV420p數(shù)據(jù)格式如下圖:
3.2) YUV420p和YUV420sp具體分類和詳情
YUV420p:又叫planer平面模式,Y 滔吠,U纲菌,V分別再不同平面,也就是有三個(gè)平面屠凶。
YUV420p又分為:他們的區(qū)別只是存儲(chǔ)UV的順序不一樣而已驰后。
I420:又叫YU12,安卓的模式矗愧。存儲(chǔ)順序是先存Y灶芝,再存U郑原,最后存V。YYYYUUUVVV
YV12:存儲(chǔ)順序是先存Y夜涕,再存V犯犁,最后存U。YYYVVVUUU
YUV420sp:又叫bi-planer或two-planer雙平面女器,Y一個(gè)平面酸役,UV在同一個(gè)平面交叉存儲(chǔ)。
YUV420sp又分為:他們的區(qū)別只是存儲(chǔ)UV的順序不一樣而已驾胆。
NV12:IOS只有這一種模式涣澡。存儲(chǔ)順序是先存Y,再UV交替存儲(chǔ)丧诺。YYYYUVUVUV
NV21:安卓的模式入桂。存儲(chǔ)順序是先存Y,再存U驳阎,再VU交替存儲(chǔ)抗愁。YYYYVUVUVU
官方文檔如下:
YV12
All of the Y samples appear first in memory as an array of unsigned char values. This array is followed immediately by all of the V (Cr) samples. The stride of the V plane is half the stride of the Y plane, and the V plane contains half as many lines as the Y plane. The V plane is followed immediately by all of the U (Cb) samples, with the same stride and number of lines as the V plane (Figure 12).
大致意思是:先存儲(chǔ)完所有的Y,后面緊跟著存V呵晚,V的步長(zhǎng)(也就是寬)是Y的步長(zhǎng)的一半蜘腌,V的行高是Y的一半。V存儲(chǔ)完后面緊跟著存U饵隙,所有的U撮珠,步長(zhǎng)河行高和V相同,也就是都是Y的一半癞季。
Figure 12:
NV12
All of the Y samples are found first in memory as an array of unsigned char values with an even number of lines. The Y plane is followed immediately by an array of unsigned char values that contains packed U (Cb) and V (Cr) samples, as shown in Figure 13. When the combined U-V array is addressed as an array of little-endian WORD values, the LSBs contain the U values, and the MSBs contain the V values. NV12 is the preferred 4:2:0 pixel format for DirectX VA. It is expected to be an intermediate-term requirement for DirectX VA accelerators supporting 4:2:0 video.
Figure 13:
3.3)YUV420的內(nèi)存計(jì)算
width * hight =Y(總和)
U = Y / 4 ? V = Y / 4
所以YUV420 數(shù)據(jù)在內(nèi)存中的長(zhǎng)度是 width * hight * 3 / 2(即一個(gè)YUV是1.5個(gè)字節(jié))劫瞳,所以計(jì)算采集的數(shù)據(jù)大小:width * hight * 1.5*frame*time
以720×488大小圖象YUV420 planar為例绷柒,
其存儲(chǔ)格式是: 共大小為720×480×3 × 1.5字節(jié)志于,
分為三個(gè)部分:Y,U和V
Y分量:????(720×480)個(gè)字節(jié)
U(Cb)分量:(720×480 × 1/4)個(gè)字節(jié)
V(Cr)分量:(720×480 × 1/4)個(gè)字節(jié)
三個(gè)部分內(nèi)部均是行優(yōu)先存儲(chǔ),三個(gè)部分之間是Y,U,V 順序存儲(chǔ)废睦。
即YUV數(shù)據(jù)的0--720×480字節(jié)是Y分量值伺绽,
720×480--720×480×5/4字節(jié)是U分量
720×480×5/4 --720×480×3/2字節(jié)是V分量。
一般來(lái)說(shuō)嗜湃,直接采集到的視頻數(shù)據(jù)是RGB24的格式奈应,RGB24一幀的大小size=width×heigth×3 Bit,RGB32的size=width×heigth×4购披,YUV標(biāo)準(zhǔn)格式4:2:0 的數(shù)據(jù)量是 size=width×heigth×1.5 Bit杖挣。
在采集到RGB24數(shù)據(jù)后,需要對(duì)這個(gè)格式的數(shù)據(jù)進(jìn)行第一次壓縮刚陡。即將圖像的顏色空間由RGB2YUV惩妇。因?yàn)橹旰海琗264在進(jìn)行編碼的時(shí)候需要標(biāo)準(zhǔn)的YUV(4:2:0)。
經(jīng)過(guò)第一次數(shù)據(jù)壓縮后RGB24->YUV(I420)歌殃。這樣乔妈,數(shù)據(jù)量將減少一半,經(jīng)過(guò)X264編碼后氓皱,數(shù)據(jù)量將大大減少路召。將編碼后的數(shù)據(jù)打包,通過(guò)RTP實(shí)時(shí)傳送波材。到達(dá)目的地后股淡,將數(shù)據(jù)取出,進(jìn)行解碼各聘。完成解碼后揣非,數(shù)據(jù)仍然是YUV格式的,所以躲因,還需要一次轉(zhuǎn)換,就是YUV2RGB24忌傻。
3.4)關(guān)于IOS
做過(guò)iOS硬解碼的都知道大脉,創(chuàng)建解碼器時(shí),需要指定PixelFormatType水孩。IOS只支持NV12也就是YUV420中的一種镰矿,你搜索420,發(fā)現(xiàn)有四個(gè)俘种,分別如下:
kCVPixelFormatType_420YpCbCr8Planar
kCVPixelFormatType_420YpCbCr8PlanarFullRange
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
根據(jù)表面意思秤标,可以看出,可以分為兩類:planar(平面420p)和 BiPlanar(雙平面)宙刘。
還有一個(gè)辦法區(qū)分苍姜,CVPixelBufferGetPlaneCount(pixel)獲取平面數(shù)量,發(fā)現(xiàn)kCVPixelFormatType_420YpCbCr8Planar和kCVPixelFormatType_420YpCbCr8PlanarFullRange是三個(gè)兩面悬包,屬于420p衙猪,iOS不支持。而kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange和kCVPixelFormatType_420YpCbCr8BiPlanarFullRange是兩個(gè)平面布近。這就糾結(jié)了垫释,到底用哪一個(gè)呢?
我查了官網(wǎng)資料撑瞧,解釋如下:
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange = '420v', /* Bi-Planar Component Y'CbCr 8-bit 4:2:0, video-range (luma=[16,235] chroma=[16,240]).? baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange? = '420f', /* Bi-Planar Component Y'CbCr 8-bit 4:2:0, full-range (luma=[0,255] chroma=[1,255]).? baseAddr points to a big-endian CVPlanarPixelBufferInfo_YCbCrBiPlanar struct */
感覺(jué)除了亮度和顏色的范圍不一樣棵譬,沒(méi)發(fā)現(xiàn)其它不一樣的。還是糾結(jié)预伺,后來(lái)查了神網(wǎng)订咸,有人說(shuō)WWDC視頻有琅束,網(wǎng)址:https://developer.apple.com/videos/play/wwdc2011/419/?time=1527(大概在25:30‘)
解釋如下:
但是我我還是不清楚,清楚的人請(qǐng)告知我一下算谈。
然后我創(chuàng)建的時(shí)候分辨使用了kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange和kCVPixelFormatType_420YpCbCr8BiPlanarFullRange涩禀,視頻播放出來(lái)沒(méi)發(fā)現(xiàn)什么不一樣,唯一不一樣是計(jì)算的步長(zhǎng)不一樣然眼。
比如:480*640
如果是:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
Y和UV的步長(zhǎng)是512(采用了64字節(jié)對(duì)齊 非對(duì)齊的補(bǔ)0) Y的行寬是640艾船,UV行寬是320
如果是:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
Y和UV的步長(zhǎng)是480(實(shí)際長(zhǎng)度,未補(bǔ)齊) Y的行寬是640高每,UV行寬是320
我采集的時(shí)候setPreset了屿岂,所以按照上面提示(但是我還是不是很理解),最后我項(xiàng)目里面還是選擇了kCVPixelFormatType_420YpCbCr8BiPlanarFullRange鲸匿。