1. 程式人生 > >ffmpeg入門--YUV格式

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硬體轉換/渲染)要特別注意,否則解碼出來的影象會異常。

視訊儲存格式YUV420 NV12 NV21 i420