博客訪問量日漸減少,于是我決定丟一點技術東東上去,吸引爬蟲光顧一下。
先談談 h.264 的編解碼問題。
個人建議做視頻、音頻的孩子們,一定要抓住 RFC 和 standard ,然后多看開源編解碼程序。
近來抽空看了兩個 decoder ,一個是從 ffmpeg 里面抽取出來的 h.264 部分,還有從 JM 。
解碼器生成最后結果是 yuv420 格式(后面會提到)。
關于 yuv ,看到論壇里不少人都急于找工具去看自己解得一幀圖像是否正確,更有不少人提供 yuv420 2 rgb24 和 yuv422 2 rgb24 等代碼。
這里建議使用 強大的 ps 的 .raw 文件的功能。
.raw 文件可用來查看 純 rgb 圖片 和 純 yuv 圖片,很適合做圖像。
yuv 格式:
YUV是指亮度參量和色度參量分開表示的像素格式,而這樣分開的好處就是不但可以避免相互干擾,還可以降低色度的采樣率而不會對圖像質量影響太大。YUV 是一個比較籠統地說法,針對它的具體排列方式,可以分為很多種具體的格式。
YUV格式通常有兩大類:打包(packed)格式和平面(planar)格式。前者將YUV分量存放在同一個數組中,通常是幾個相鄰的像素組成一個宏像 素(macro-pixel);而后者使用三個數組分開存放YUV三個分量,就像是一個三維平面一樣。
YUY2到Y211都是打包格式,而IF09到YVU9都是平面格式。
(注意:在介紹各種具體格式時,YUV各分量都會帶有下標,如Y0、 U0、V0表示第一個像素的YUV分量,Y1、U1、V1表示第二個像素的YUV分量,以此類推。)
yuv采樣:
? | 4:4:4 表示色度頻道沒有下采樣。每像素 24 位 |
? | 4:2:2 表示 2:1 的水平下采樣,沒有垂直下采樣。對于每兩個 U 樣例或 V 樣例,每個掃描行都包含四個 Y 樣例。每像素 16 位 |
? | 4:2:0 表示 2:1 的水平下采樣,2:1 的垂直下采樣。每像素 16 位 |
? | 4:1:1 表示 4:1 的水平下采樣,沒有垂直下采樣。對于每個 U 樣例或 V 樣例,每個掃描行都包含四個 Y 樣例。與其他格式相比,4:1:1 采樣不太常用,本文不對其進行詳細討論。每像素 16 位 |
在我做的 h264 中,支 持4:2:0的連續或隔行視頻的編碼和解碼。
其中“Y”表示明亮度(Luminance或Luma),也就是灰階值;而“U”和“V”表示的則是色度(Chrominance或Chroma),作用 是描述影像色彩及飽和度,用于指定像素的顏色。“亮度”是通過RGB輸入信號來創建的,方法是將RGB信號的特定部分疊加到一起。“色度”則定義了顏色的 兩個方面—色調與飽和度,分別用Cr和CB來表示。其中,Cr反映了GB輸入信號紅色部分與RGB信號亮度值之間的差異。而CB反映的是RGB輸入信號藍 色部分與RGB信號亮度值之同的差異。?
常見H264測試的YUV序列:
CIF圖像大小的YUV序列(352*288),在文件 開始并沒有文件頭,直接就是YUV數據,先存第一幀的Y信息,長度為352*288個byte, 然后是第一幀U信息長度是352*288/4個byte, 最后是第一幀的V信息,長度是352*288/4個byte, 因此可以算出第一幀數據總長度是352*288*1.5,即152064個byte, 如果這個序列是300幀的話, 那么序列總長度即為152064*300=44550KB,這也就是為什么常見的300幀CIF序列總是44M的原因.
IYUV格式(planar)為每個像素都提取Y分量,而在UV分量的提取時,首先將 圖像分成若干個2 x 2的宏塊,然后每個宏塊提取一個U分量和一個V分量。YV12格式與 IYUV類似,但仍然是平面模式。
YUV411、YUV420格式多見于DV數據中。
YUV411用于NTSC制。為每個像素都提取Y分量,而UV分量在水平方向上每4個像素采樣一次。
YUV420用于 PAL制。并非V分量采樣為0,而是跟YUV411相比, 在水平方向上提高一倍色差采樣頻率,在垂直方向上以U/V間隔的方式減小一半色差采樣。
各種格式的具體使用位數的需求(使用4:2:0采樣,對于每個元素用8個位大小表示):
格式: Sub-QCIF 亮度分辨率: 128*96?? 每幀使用的位: 147456
格式: QCIF?? 亮度分辨率: 176*144?? 每幀使用的位: 304128
格式: CIF?? 亮度分辨率: 352*288?? 每幀使用的位: 1216512
格 式: 4CIF?? 亮度分辨率: 704*576?? 每幀使用的位: 4866048