1. 圖像基礎概念
- 像素:像素是一個圖片的基本單位,
pix
是英語單詞picture
,加上英語單詞“元素element
”,就得到了pixel
,簡稱px
。所以“像素”有“圖像元素”之意。 - 分辨率:指的是圖像的大小或者尺寸。比如 1920x1080 。
- 位深:指在記錄數字圖像的顏色時,計算機實際上是用每個像素需要的位深來表示的。比如紅色分量使用 8bit 。
- 幀率:在一秒鐘時間內傳輸圖片的幀數(張數),也可以理解為圖形處理器每秒鐘能夠刷新幾次。例如:25fps 表示一秒有 25 張圖片。
- 碼率:視頻文件在單位時間內使用的數據流量。例如 1Mbps 。
Stride
:指在內存中每行像素所占的空間。為了實現內存對齊,每行像素在內存中所占的空間并不一定是圖像的寬度。
1.1. 像素
像素是一個圖片的基本單位,pix
是英語單詞picture
,加上英語單詞“元素element
”,就得到了pixel
,簡稱px
。所以“像素”有“圖像元素”之意。
例如 2500x2000 的照片就是指橫向有 2500 個像素點,豎向有 2000 個像素點,總共是 500 萬個像素,也俗稱為 500 萬像素照片。
將這個圖片放大,可以發現是由一塊一塊的小方塊組成的,每一個小方塊就是一個像素點。
1.2. 分辨率
圖像(視頻)的分辨率指的是圖像的大小或尺寸。我們通常用像素來表示圖像的尺寸。
例如分辨率為 2500x2000 的照片就是指的 橫向(寬)有 2500 個像素點,豎向(高)有 2000 個像素點。
常見的分辨率:
360P(640x360)、720P(1280x720)、1080P(1920x1080)、4K(3840x2160)、8K(7680x4320)
常說的 1080P 和 720P 其實指的是分辨率的垂直像素,一般情況下我們都是按照 16:9 (寬:高)來計算分辨率。
那么 720P 的分辨率計算流程如下:
- 720P 代表垂直(高)像素有 720 個像素點
- 由于圖片的比例為 16:9 ,那么水平(寬)的像素點數量為 720 ÷ 9 × 16 = 1280
- 故 720P 的分辨率為 1280x720
像素越多視頻就越清晰,1080P 的像素點總共有 1920x1080 約等于 200 萬個像素,720p 的像素點總共有 1080x720 約等于 92 萬個像素。1080p 的像素點數量比 720p 的像素點數量多兩倍多,故 1080p 比 720p 更清晰。圖像的分辨率越高,圖像就越清晰。
低分辨率下只能看到一個大概的輪廓,而高分辨率能看到更多的細節,故更加清晰。
1.3. 位深
我們看到的彩色圖片,都有三個通道,分別為紅(R),綠(G),藍(B)通道。(如果需要透明度則還有 alpha
分量)。
通常每個通道用 8bit 表示,8bit 能表示 256 種顏色,所以可以組成 256*256*256=16,777,216=1677萬種顏色。這里的 8bit 就是我們講的位深。
每個通道的位深越大,能夠表示的顏色值也就越大。比如現在高端電視說的是 10bit 色彩,即每個通道用 10bit 表示,10bit 能表示 1024 種顏色,故可以組成 1024*1024*1024 約等于 10億種顏色,是 8bit 的 64 倍。
常見的顏色還是 8bit 居多。
1.4. 幀率
幀率即 FPS(每秒有多少幀畫面)。經常玩游戲的小伙伴應該很熟,我們玩游戲時,FPS 越高就代表游戲畫面越流暢,越低則越卡頓。
由于視覺圖像在視網膜的暫時停留,一般圖像幀率能達到 24 幀,我們就認為圖像是連續動態的。
- 電影幀率一般是 24fps
- 電視劇一般是 25fps
- 監控行業一般是 25fps
- 音視頻通話一般是 25fps
幀率越高,畫面越流暢,需要的設備性能也越高。
1.5. 碼率
- 碼率指的是視頻文件在單位時間內使用的數據流量。比如 1Mbps 。
- 大多數情況下碼率越高,分辨率越高,也就越清晰。但本身就模糊的視頻文件碼率也可以很大,分辨率小的視頻文件也可能比分辨率大的視頻文件清晰。【比如光線不好的時候錄制的視頻】
- 對于同一個原始圖像源的時候,同樣的編碼算法,碼率越高,圖像的失真就會越小,視頻畫面就會越清晰。【可見后面的h264編碼,當采用低碼率,那么在編碼的時候就會設置更高的QStep】
- 碼率是一個統計的指標,并不是一個實際的功能。
1.6. Stride
設計到計算機底層對于內存的利用,不影響理解,只是開發時使用,這里不做介紹。
2. RGB、YUV深入講解
- RGB:紅R、綠G、藍B三種基色。
- YUV:”Y“ 表示明亮度(Luma),也就是灰階值,”U“ 和 ”V“ 表示的是色度(Chroma)。
2.1. RGB
- 我們前面已經講過 RGB 色彩表示,這里我們重點講 RGB 的排列。通常的圖像像素是按 RGB 順序進行排列的,但有些圖像處理要轉換為轉成其他順序,比如 OpenCV 經常要轉換為 BGR 的排列方式
常見的一些排列方式:
2.2. YUV
2.2.1. 基礎介紹
- 與我們熟知的 RGB 類似,YUV 也是一種顏色編碼方法,它是指將亮度參量和色度參量分開進行表示的像素編碼格式。
- 這樣分開的好處就是不但可以避免互相干擾,沒有 UV 信息一樣可以顯示完整的圖像(因而解決了彩色電視與黑白電視的兼容問題),還可以降低色度的采樣率而不會對圖像質量影響太大,降低了視頻信號傳輸時對頻寬(寬度)的要求。
- YUV 是一個比較籠統的說法,針對它的具體排列方式,可以分為很多種具體的格式,但基礎兩個格式如下:
-
- 打包(packed)格式:將每個像素點的Y、U、V分量交叉排列并以像素點為單元連續的存放在同一個數組中,通常幾個相鄰的像素組成一個宏像素(macro-pixel)。
- 平面(planar)格式:使用三個數組分開連續的存放Y、U、V三個分量,即Y、U、V分別存放在各種的數組中。
2.2.2. 采樣表示法
- YUV 采用 A:B:C 表示法來描述 Y,U,V 采用頻率比例,下圖中黑點表示采樣像素 Y 分量,空心圓表示采用像素的 UV 分量。主要分為 YUV 4:4:4、YUV 4:2:2、YUV 4:2:0 這三種常用的類型
- 4:4:4 表示色度頻道沒有下采樣,即每一個 Y 分量對應 一個 UV 分量。
- 4:2:2 表示 2:1 的水平下采樣,沒有垂直下采樣,即每兩個 Y 分量共享 一個 UV 分量。
- 4:2:0 表示 2:1 的水平下采樣,2:1 的垂直下采樣,即每四個 Y 分量共享 一個 UV 分量。
YUV4:4 : 4,不是說4個Y,4個V,4個U,而是說 Y 和 UV的比例關系。
同理 YUV4:2:0,也不是說4個Y,2個Y,0個U,也是說的 Y 和 UV 的比例關系。
2.2.3. YUV數據存儲方式
下面以每個分量的采用數據為位深 8bit 為例描述YUV的數據存儲方式
- 4:4:4 格式
- 4:2:2 格式
- 4:2:0 格式
2.2.3.1. YUV 4:4:4 格式
比如 I444(YUV444P)格式
- 對應 FFmpeg 像素表示
AV_PIX_FMT_YUV444P
- 該類型為 平面(planar)格式
- 一個宏素塊 24bit,即 3 個字節
2.2.3.2. YUV 4:2:2 格式
比如 I422(YUV422P)格式
- 對應 FFmpeg 像素表示
AV_PIX_FMT_YUV422P
- 該類型為 平面(planar)格式
- 一個宏素塊 16bit,即 2 個字節
2.2.3.3. YUV 4:2:0 格式【最常用】
比如 I420(YUV420P)格式
- 對應 FFmpeg 像素表示
AV_PIX_FMT_YUV420P
- 該類型為 平面(planar)格式
- 一個宏素塊 12bit,即 1.5 個字節
2.2.3.4. YUV 4:2:0 格式 - NV12
比如 NV12 格式
- 對應 FFmpeg 像素表示
AV_PIX_FMT_NV12
- 該類型為 YUV420P 的變種,對 Y 分量采用平面模式,對 UV 采用打包模式
- 一個宏素塊 12bit,即 1.5 個字節
2.2.3.5. YUV 4:2:0 格式 - 各種變種格式參考
2.3. RGB和YUV的轉換
- 通常情況下 RGB 和 YUV 直接的互相轉換都是調用接口實現,比如 FFmpeg 的 swscale 或者 libyuv 等庫。
- 主要轉換標準是 BT601 和 BT709。
-
- TV range 的分量范圍: 16-235(Y)、16-240(UV),故叫做 Limited Range
- PC range 的分量范圍: 0-255(Y、UV),故叫做 Full Range
- 而對于 RGB 來說沒有分量范圍之分,全是 0-255
- BT601 TV Range 轉換公式
RGB 轉換為 YUV:
Y = 0.299 * R + 0.587 * G + 0.114 * B;
U = -0.169 * R - 0.331 * G + 0.5 * B;
V = 0.5 * R - 0.419 * G - 0.081 * B;
YUV 轉換為 RGB:
R = Y + 1.402 * (Y - 128)
G = Y +0.34414 * (U - 128) - 0.71414 * (U - 128)
B = Y + 1.772 * (V - 128)
- 從 YUV 轉換到 RGB ,如果值小于 0 要取 0,值大于 255 要取 255。
2.4. RGB和YUV的轉換——為什么解碼出錯會出現綠屏
當解碼時,從 packet 中解析 frame,由于解碼失敗,導致得到YUV的都為0,再根據公式轉換為 RGB
R = 1.402 * (-128) = -126.598
G = -0.34414 * (-128) - 0.71414 * (-128) = 135.45984
B = 1.722 * (-128) = -126.228
由于 RGB 值范圍是 [0,255],所以最終的值為:
R = 0
G = 135
B = 0
此時只有 G 分量有值,故全屏是綠色。
2.5. YUV Stride對齊問題
設計到計算機底層對于內存的利用,不影響理解,只是開發時使用,這里不做介紹。
3. 視頻的主要概念
3.1. 基礎名詞
3.2. I幀
3.3. P、B幀
3.4. 常用視頻壓縮算法
4. 補充知識點
4.1. 常用分辨率
標號 | 視頻類型 | 格式尺寸 | 類型 | 比例 |
1 | 4K | 4096*2160 | 4K | 16:9 |
2 | 2K | 2560*1440 | 2K | 16:9 |
3 | 全高清 | 1920*1080 | 1080p | 16:9 |
4 | 高清 | 1280*720 | 720p | 16:9 |
5 | 標清 | 720*480 | 480p | 3:2 |
6 | 標清 | 640*480 | 480p | 4:3 |
7 | 流暢 | 320*240 | 240p | 4:3 |
補充說明:
多數情況下4k特指4096 * 2160分辨率。而根據使用范圍的不同,4K分辨率也有各種各樣的衍生分辨率,例如Full Aperture 4K的4096 * 3112、Academy 4K的3656 * 2664以及UHDTV標準的3840 * 2160等,都屬于4K分辨率的范疇。
原文鏈接:4K、2K、1080p、720p、480p、240p常見視頻清晰度-CSDN博客
4.2. 位深
如果不是8bit,而是1bit,那么就只會有八種顏色了,全紅、全綠、全藍、全黑、全白...。因為每個通道只能顯示兩種顏色,紅、非紅;綠,非綠;藍,非藍。
4.3. 碼率
每一秒傳輸的幀數是固定的,比如一秒傳輸10幀,每幀大小1MB,那么碼率就是10MBps,但是如果降低碼率了,降低為5Mbps,由于每秒傳輸的幀數不應該發生變化,所以每幀的大小只能傳輸0.5MB了,所以就會造成數據丟失(壓縮的結果),回顯就會出現不清晰,或者馬賽克了。
4.3.1. 核心概念
- 幀率(FPS)與碼率的關系
-
- 幀率(FPS)是每秒顯示的幀數(如20FPS=20幀/秒),由視頻的時序特性決定,與碼率無關。
- 碼率(比特率)是每秒傳輸的數據量(如200Mbps),決定了每幀能分配到的平均數據量。
- 關鍵結論:
-
-
- 當幀率固定時(如20FPS),降低碼率會迫使編碼器壓縮每幀的數據量(減少每幀的比特數),而非減少幀數。
- 提高碼率則允許每幀保留更多數據,從而提升畫質。
-
- 為什么壓縮每幀會影響清晰度?
-
- 視頻編碼(如H.264/H.265)的本質是用盡可能少的數據表示圖像。編碼器會通過以下手段壓縮每幀:
-
-
- 空間壓縮:合并相似區域、舍棄高頻細節(如紋理)。
- 時間壓縮:通過運動預測(幀間編碼)減少冗余。
-
-
- 碼率降低時:編碼器必須更激進地壓縮每幀,導致:
-
-
- 量化步長增大 → 更多細節被丟棄 → 畫面模糊或出現塊效應。
- 運動預測精度下降 → 殘差數據更粗糙 → 動態畫面出現拖影。
-
4.3.2. 你的例子修正
- 假設條件:
-
- 原始視頻:10秒,20FPS → 共200幀,原始每幀1MB(未壓縮)。
- 編碼后目標碼率:
-
-
- 200Mbps(25MB/s):每秒分配25MB數據,平均每幀
25MB/20幀=1.25MB/幀
。 - 100Mbps(12.5MB/s):每秒分配12.5MB數據,平均每幀
12.5MB/20幀=0.625MB/幀
。
- 200Mbps(25MB/s):每秒分配25MB數據,平均每幀
-
- 關鍵區別:
-
- 高碼率(1.25MB/幀)時,編碼器可以保留更多細節(接近原始1MB/幀的未壓縮質量)。
- 低碼率(0.625MB/幀)時,編碼器必須將每幀壓縮到更小的體積,導致畫質下降。
4.3.3. 類比說明
- 把視頻想象成一本書:
-
- 幀率:每秒翻多少頁(固定20頁/秒)。
- 碼率:每頁允許寫的字數。
-
-
- 高碼率 → 每頁字數多(細節豐富,清晰)。
- 低碼率 → 每頁字數少(必須縮寫或刪減內容,信息丟失)。
-
4.3.4. 常見誤區澄清
- “碼率降低是否會導致丟幀?”
-
- 不會!幀率(FPS)是編碼前確定的參數(如20FPS),編碼器會優先保證幀數,轉而壓縮每幀質量。
- 只有極端情況下(如網絡傳輸擁塞),可能主動丟幀,但這屬于實時傳輸問題,而非編碼本身的特性。
- “為什么不能直接降低分辨率?”
-
- 降低分辨率(如1080p→720p)確實可以減少數據量,但這是另一種壓縮手段。
- 固定分辨率下,碼率降低是通過壓縮算法(如量化、預測)實現的,而非改變分辨率。
4.3.5. 總結
- 幀率(FPS):決定視頻的流暢度,編碼時固定不變。
- 碼率:決定每幀的畫質,碼率越低,每幀被壓縮得越狠,清晰度越低。
- 編碼器的任務:在固定幀率和目標碼率下,智能分配每幀的數據量,平衡壓縮率與畫質。
4.4. 像素排列
常規理解來說一個像素不是一個字節,可以理解為一個對象。【這里指的位深為 8bit 】
比如不是說 char a[1280*720], a[0]是一個像素,應該理解為:
struct pixel
{char r;char g;char b;
}
pixel a[1280*720];
a[0] 是一個像素。
當然,寫代碼肯定是按照char來理解的,那么就是 char a[1280*720*3],a[0]、a[1]、a[2] 三個組合是一個像素;a[3]、a[4]、a[5] 三個組合起來是一個像素。其中a[0]、a[1]、a[2]誰是R,誰是G,誰是B,就看排列規則了。
4.5. 花屏
- 如果頁面完全看不出來輪廓,代表分辨率選錯了
- 如果能看出來輪廓,但是花屏,那么分辨率沒問題,數據格式選錯了
4.6. YUV444和YUV420的命名
YUV444 代表4個Y,4個U,4個V。
YUV420 代表4個Y,1個U,一個V。
但是看名字不應該是4個Y,2個U,0個V嗎,按道理4個Y,1個U,一個V不應該叫做 YUV411 嗎?
但其實它的命名源于歷史約定和采樣網格的排列方式,而非嚴格的數學比例。下面詳細解釋:
4.6.1. 1. YUV 4:2:0 的采樣結構
YUV 4:2:0 的色度(UV)采樣方式如下:
- 每4個Y(亮度)像素共享1個U和1個V(色度)值。
- 但色度采樣在垂直方向也進行了減半,即每隔一行才保留一組UV值。
實際存儲示例(以2×2像素塊為例):
Y1 Y2 → 亮度(Y)全采樣
Y3 Y4U1 V1 → 色度(UV)在水平和垂直方向均減半
- 4個Y對應 1個U和1個V(水平和垂直方向均共享)。
4.6.2. 2. 為什么叫4:2:0而不是4:1:1?
- 4:2:0的命名邏輯:
-
- 第一個數字(4):參考基準(通常表示亮度的橫向采樣數)。
- 第二個數字(2):色度(U/V)在水平方向的采樣比例(相對于亮度的一半)。
- 第三個數字(0):色度在垂直方向的采樣比例(0表示垂直方向再減半)。
-
-
- 即色度在水平和垂直方向均為亮度的一半,最終等效于“4個Y對應1個UV”。
-
- 對比其他格式:
-
- 4:4:4:色度無降采樣(每個Y對應一個UV)。
- 4:2:2:色度水平減半,垂直全采樣(每行保留UV)。
- 4:1:1:色度水平降為1/4,垂直全采樣(常見于DV視頻)。
- 關鍵區別:
4:2:0的“0”強調垂直方向也減半,而4:1:1的色度在垂直方向未減半。
4.6.3. 3. 命名背后的歷史原因
- 4:2:0的“0”是約定俗成:
早期工程師用數字表示色度采樣相對于亮度的比例,垂直減半被標記為“0”(類似占位符),而非數學上的嚴格除法。 - 與4:1:1的對比:
4:1:1是水平方向更激進的降采樣(每4個Y共享1個UV,但垂直方向不降采樣),而4:2:0是水平和垂直均減半。
4.6.4. 4. 直觀圖示
以8×8像素塊為例:
- Y(亮度):全采樣(64個值)。
- U/V(色度):
-
- 水平方向:每隔1個像素采樣(4:2:0 → 水平減半 → 每行4個UV)。
- 垂直方向:每隔1行采樣(4:2:0 → 垂直減半 → 共4行UV)。
- 最終UV數據量:
4×4=16
個U和16個V,相當于64個Y對應16個UV → 4:1的比例。
4.6.5. 5. 為什么不是4:1:1?
- 4:1:1的色度采樣:
-
- 水平方向:每4個Y共享1個UV。
- 垂直方向:每行都保留UV(不降采樣)。
- 示例:8×8像素塊中,UV數據量為
2×8=16
個(每行2個UV,共8行)。 - 相當于64個Y對應16個UV → 4:1的比例,但垂直方向未減半。
- 4:2:0的色度采樣:
-
- 水平和垂直均減半 → 最終UV數據量是4:1:1的一半(更節省帶寬)。
4.6.6. 總結
- YUV 4:2:0的命名反映的是色度在水平和垂直方向的減半采樣(“0”代表垂直減半),而實際存儲比例是4個Y對應1個UV。
- 4:1:1則是水平方向更激進的降采樣,但垂直方向未減半。
- 這種命名是歷史慣例,數字更多表示“采樣網格的分布方式”,而非嚴格的數學比例。
如果需要記憶,可以簡單理解為:
- 4:2:0 = 色度在兩個方向都減半(最終4Y:1UV)。
- 4:1:1 = 色度僅在水平方向減半(垂直方向全采樣)。
4.7. 生成BMP圖片文件
#include <iostream>
#include <fstream>
#include <vector>// BMP 文件頭
#pragma pack(push, 1) // 確保結構體沒有字節填充
struct BMPFileHeader {uint16_t bfType; // 文件類型,必須是 'BM'uint32_t bfSize; // 文件大小uint16_t bfReserved1; // 保留,必須為 0uint16_t bfReserved2; // 保留,必須為 0uint32_t bfOffBits; // 從文件頭到像素數據的偏移
};// DIB 頭(BITMAPINFOHEADER)
struct BMPInfoHeader {uint32_t biSize; // 此結構的大小(40 字節)int32_t biWidth; // 圖像寬度int32_t biHeight; // 圖像高度uint16_t biPlanes; // 顏色平面數,必須為 1uint16_t biBitCount; // 每像素位數(24 表示 RGB)uint32_t biCompression; // 壓縮類型(0 表示不壓縮)uint32_t biSizeImage; // 圖像大小(可以為 0,如果不壓縮)int32_t biXPelsPerMeter; // 水平分辨率int32_t biYPelsPerMeter; // 垂直分辨率uint32_t biClrUsed; // 使用的顏色數(0 表示所有)uint32_t biClrImportant; // 重要顏色數(0 表示所有)
};
#pragma pack(pop)void createRedBMP(const char* filename) {int width = 640;int height = 480;/** 這里 width * 3,是因為一個像素點有RGB3個點,故實際上一個像素點有三個點,剛好與下面的 infoHeader.biBitCount 對應。* 而且也一定要和下面的 infoHeader.biBitCount 對應,因為這里是計算的是總字節大小,這里 *3,就代表一個像素點3字節,那么每個RGB對應1個字節,那么 infoHeader.biBitCount 就該是24位,即3個字節,* 否則圖形的總字節大小算下來就不對。 * +3 & (~3) 就是對齊四個字節的操作,先+3,向上填充直最近4的倍數,然后在 &(~3),把余數給去掉,(3 = 011, ~3 = 100,即最后兩位一定會被去掉)*/// 計算圖像數據大小int row_padded = (width * 3 + 3) & (~3); // 每行 4 字節對齊int dataSize = row_padded * height;// 創建文件頭和信息頭BMPFileHeader fileHeader = {};BMPInfoHeader infoHeader = {};fileHeader.bfType = 0x4D42; // 'BM'fileHeader.bfSize = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + dataSize;fileHeader.bfOffBits = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader);infoHeader.biSize = sizeof(BMPInfoHeader);infoHeader.biWidth = width;infoHeader.biHeight = height;infoHeader.biPlanes = 1;infoHeader.biBitCount = 24; // RGB。 24 / 3 = 8位 = 1個字節。0~255。為什么要除3,因為一個像素要包含RGB3個點,故一位像素點,要切分成三份來使用。與上面的row_padded對應infoHeader.biCompression = 0; // 不壓縮// 打開文件std::ofstream file(filename, std::ios::binary);if (!file) {std::cerr << "無法創建文件: " << filename << std::endl;return;}// 寫入文件頭和信息頭file.write(reinterpret_cast<const char*>(&fileHeader), sizeof(fileHeader));file.write(reinterpret_cast<const char*>(&infoHeader), sizeof(infoHeader));// 寫入像素數據(紅色)std::vector<uint8_t> row(row_padded, 0); // 用于存儲每行的數據for (int y = 0; y < height; ++y) {for (int x = 0; x < width; ++x) {row[x * 3 + 0] = 0; // Brow[x * 3 + 1] = 0; // Grow[x * 3 + 2] = 255; // R}file.write(reinterpret_cast<const char*>(row.data()), row_padded);}file.close();
}int main() {createRedBMP("red_image.bmp");std::cout << "紅色 BMP 圖像已創建: red_image.bmp" << std::endl;return 0;
}
4.8. 生成YUV圖片文件
#include <iostream>
#include <fstream>void generateRedYUVImage(const char* filename, int width, int height) {// 分配內存int size = width * height * 3; // YUV444: 每個像素3個字節unsigned char* yuvData = new unsigned char[size];// 填充數據(全紅)for (int y = 0; y < height; ++y) {for (int x = 0; x < width; ++x) {int index = (y * width + x) * 3;yuvData[index + 0] = 255; // YyuvData[index + 1] = 255; // UyuvData[index + 2] = 255; // V}}// 保存數據到文件std::ofstream outFile(filename, std::ios::binary);if (outFile.is_open()) {outFile.write(reinterpret_cast<const char*>(yuvData), size);outFile.close();std::cout << "Image saved to " << filename << std::endl;}else {std::cerr << "Unable to open file for writing" << std::endl;}// 釋放內存delete[] yuvData;
}int main() {int width = 640; // 圖像寬度int height = 480; // 圖像高度const char* filename = "red_image.yuv";generateRedYUVImage(filename, width, height);return 0;
}
使用ffplay播放:
ffplay -f rawvideo -pixel_format yuv444p -video_size 640x480 red_image.yuv