ffmpeg入門--YUV格式
YUV
YUV(亦稱YCrCb)是三個分量,Y是亮度資訊,U,V是色度訊號。如果只有Y,那麼電視播放出來的是黑白,Y加上U,V後就是彩色電視。
這樣解決黑白電視也能播放彩色電視的訊號的問題。
-
ffmpeg中是如何管理這個yuv的資料的呢?
核心就是AVFrame這個結構體,成員data是個指標陣列,每個成員所指向的就是yuv三個分量的實體資料了,成員linesize是指對應於每一行的大小,為什麼需要這個變數,是因為在YUV格式和RGB格式時,每行的大小不一定等於影象的寬度.
===============================================================================
YUV格式
1. YUV 4:4:4取樣,每一個Y對應一組UV分量8+8+8 = 24bits,3個位元組。
2. YUV 4:2:2取樣,每兩個Y共用一組UV分量,一個YUV佔8+4+4 = 16bits 2個位元組。
3. YUV 4:2:0取樣,每四個Y共用一組UV分量一個YUV佔8+2+2 = 12bits 1.5個位元組。
-
我就先說說YUV420格式吧。
YUV 4:2:0取樣,即每4個Y公用一組UV分量。如下圖:
因為一個Y分量對應一個畫素點,所以若該圖片的寬為width, 高為height,那麼Y就等於(width * height),同理U就等於(Y / 4), V也等於(Y / 4)。那麼這個YUV圖片在記憶體中的長度就為:Y + Y/4 + Y/4 = (Y * 3) / 2 = (width * height*3) / 2
-
FFmpeg視訊解碼後,一般儲存為AV_PIX_FMT_YUV420P 的format,而解碼後的資料儲存在結構體 AVFrame 中。YUV420P在記憶體中的排布如下:
YYYYYYYYYY UUUU VVVV
-
yuv420p在AVFrame中的儲存格式:
planar YUV 4:2:0, (1 Cr & Cb sample per 2x2 Y samples)
即儲存在結構體 AVFrame 的data[ ]陣列中 ,
data[0]——-Y分量
data[1]——-U分量
data[2]——-V分量linesize[]陣列中儲存的是對應通道的資料寬度
linesize[0]——-Y分量的寬度
linesize[1]——-U分量的寬度
linesize[2]——-V分量的寬度 -
YUV格式有兩大類:planar和packed。
對於packed的YUV格式,每個畫素點的Y,U,V是連續交叉儲存的。
對於planar的YUV格式,先連續儲存所有畫素點的Y,緊接著儲存所有畫素點的U,隨後是所有畫素點的V。
特別注意,linesize[0]的值並不一定等於圖片的寬度,有時候為了對齊各解碼器的CPU,實際尺寸會大於圖片的寬度,這點在我們程式設計時(比如OpengGL硬體轉換/渲染)要特別注意,否則解碼出來的影象會異常。