複製鏈接
請複製以下鏈接發送給好友

圖像幀

鎖定
圖像幀是組成視頻的最小單位。 [1] 
在H.264 中出現的一些概念從大到小排序依次是:序列、圖像、片組、片、NALU、宏塊、亞宏塊、塊、像素。
中文名
圖像幀
外文名
image frame
排    序
序列、圖像、片組
説    明
一幅圖像只有一個片組
概    念
IDR 幀
協    議
H.264

目錄

圖像幀定義

這裏有幾點值得説明:
(1)、在 H.264 協議中圖像是個集合概念,頂場、低場、幀都可以稱為圖像(本文後面內容用到圖像概念時都是集合概念,不再重複説明)。因此我們可以知道,對於 H.264 協議來説,我們平常所熟悉的那些稱呼,例如:I 幀、P 幀、B 幀等等,實際上都是我們把圖像這個概念具體化和細小化了。我們在 H.264 裏提到的“幀”通常就是指不分場的圖像;
(2)、如果不採用 FMO(靈活宏塊排序) 機制,則一幅圖像只有一個片組;
(3)、如果不使用多個片,則一個片組只有一個片;
(4)、如果不採用 DP(數據分割)機制,則一個片就是一個 NALU,一個 NALU 也就是一個片。否則,一個片由三個 NALU 組成(即標準“表7-1”中 nal_unit_type 值為 2、3、4 的三個 NALU 屬於一個片);
(5)、以上所述的片和 NALU 的大小關係並不是抽象概念上的從屬關係。從概念的從屬關係上來看,NALU其實又是片的一個集合概念,例如:標準“表7-1”中 nal_unit_type 值為 5 的 NALU 包括 I 片或者 SI 片。
一幅圖像根據組成它的片類型來分,可以分為標準“表7-5”中的 8 種類型。我們平常應用中所最常見到的其實是這些類型的特例。例如:我們平常所謂的“I 幀”和“IDR 幀”,其實是 primary_pic_type 值為 0 的圖像,我們平常所謂的“P幀”其實是 primary_pic_type 值為 1 的圖像的特例,我們平常所謂的“B幀”其實是 primary_pic_type 值為 2 的圖像的特例。
一幅圖像根據概念來分可以分為兩種:IDR 圖像和非 IDR 圖像。一幅圖像是否是 IDR 圖像是由組成該圖像的 NALU 決定的,如果組成該圖像的 NALU 為標準“表7-1”中 nal_unit_type 值為 5 的 NALU,則該圖像為 IDR 圖像,否則為非 IDR 圖像。

圖像幀説明

(1)、nal_unit_type 值為 5 的 NALU 只會出現在 IDR 圖像中,而 IDR 圖像中的所有 NALU 都是nal_unit_type 值為 5 的 NALU;
(2)、我們以組成一幅圖像的片的類型來區分該圖像是否是 IDR 圖像是錯誤的。例如:一幅圖像中的所有片都是 I 片並不代表這幅圖像就是 IDR 圖像。因為 I 片也可以從屬於 nal_unit_type 值為 1 的 NALU。只不過我們平常最常見到的形式是:所有片都是 I 片的圖像就是 IDR 圖像。其實這個時候 IDR 圖像的概念也被我們具體化和細小化了。
一幅圖像由 1~N 個片組組成,而每一個片組又由一個或若干個片組成。圖像解碼過程中總是按照片進行解碼,然後按照片組將解碼宏塊重組成圖像。從這種意義上講,片實際是最大的解碼單元。而一個片又包含哪些類型的宏塊呢?標準“表7-10”做了最好的説明。一個 I 宏塊又分為哪些類型呢?標準“表7-11”做了最好的説明。一個 P 宏塊又分為哪些類型呢?標準“表7-13”做了最好的説明。一個 B 宏塊又分為哪些類型呢?標準“表7-14”做了最好的説明。一個 P 宏塊的亞宏塊又分為哪些類型呢?標準“表7-17”做了最好的説明。一個 B 宏塊的亞宏塊又分為哪些類型呢?標準“表7-18”做了最好的説明。 [2] 

圖像幀frame

一個frame是可以分割成多個Slice來編碼的,而一個Slice編碼之後被打包進一個NAL單元,不過NAL單元除了容納Slice編碼的碼流外,還可以容納其他數據,比如序列參數集SPS。 [3] 
----------------------------------------------------------------------------------------------
// H.264 NAL type
enum H264NALTYPE{
H264NT_NAL = 0,
H264NT_SLICE,
H264NT_SLICE_DPA,
H264NT_SLICE_DPB,
H264NT_SLICE_DPC,
H264NT_SLICE_IDR,
H264NT_SEI,
H264NT_SPS,
H264NT_PPS,
};
int H264GetNALType(LPVOID pBSBuf, const LONG nBSLen)
{
if ( nBSLen < 5 ) // 不完整的NAL單元
return H264NT_NAL;
UINT8* pBS = (UINT8 *)pBSBuf;
ULONG nType = pBS[4] & 0x1F; // NAL類型在固定的位置上:)
if ( nType <= H264NT_PPS )
return nType;
return 0;
}
------------------------------------------------------------------------------------------------
其中 H264NT_SLICE_IDR 是關鍵幀,H264NT_SLICE 是P幀

圖像幀常見問題

1、NAL、Slice與frame意思及相互關係
NAL指網絡提取層,裏面放一些與網絡相關的信息
Slice是片的意思,264中把圖像分成一幀(frame)或兩場(field),而幀又可以分成一個或幾個片(Slilce);片由宏塊(MB)組成。宏塊是編碼處理的基本單元。 [3] 
2、NALnal_unit_type中的SEI、SPS、PPS
NAL nal_unit_type為序列參數集(SPS)、圖像參數集(PPS)、增強信息(SEI)不屬於啥幀的概念。表示後面的數據信息為序列參數集(SPS)、圖像參數集(PPS)、增強信息(SEI)。
h.264解碼中首先過濾碼流獲得參數集,參數集是H.264標準的一個新概念,是一種通過改進視頻碼流結構增強錯誤恢復能力的方法。眾所周知,一些關鍵信息比特的丟失(如序列和圖像的頭信息)會造成解碼的嚴重負面效應,而H.264把這些關鍵信息分離出來,憑藉參數集的設計,確保在易出錯的環境中能正確地傳輸。這種碼流結構的設計無疑增強了碼流傳輸的錯誤恢復能力。
H.264的參數集又分為序列參數集(Sequence parameter set)和圖像參數集(Pictureparameterset)。其中,序列參數集包括一個圖像序列的所有信息,即兩個IDR圖像間的所有圖像信息。圖像參數集包括一個圖像的所有分片的所有相關信息,包括圖像類型、序列號等,解碼時某些序列號的丟失可用來檢驗信息包的丟失與否。多個不同的序列和圖像參數集存儲在解碼器中,編碼器依據每個編碼分片的頭部的存儲位置來選擇適當的參數集,圖像參數集本身也包括使用的序列參數集參考信息。
參數集具體實現的方法也是多樣化的:(1)通過帶外傳輸,這種方式要求參數集通過可靠的協議,在首個片編碼到達之前傳輸到解碼器;(2)通過帶內傳輸,這需要為參數集提供更高級別的保護,例如發送複製包來保證至少有一個到達目標;(3)在編碼器和解碼器採用硬件處理參數集。
序列參數集以及圖像參數集要在解碼前傳輸,在解碼的過程中被激活。一旦被激活,則上一個序列參數集或者圖象參數集就失效了。圖象參數集是被使用它的slice data或者使用它的A分割的Nalu激活的。而序列參數集是被使用它的圖象參數集或者包括緩衝期消息的SEInalu所激活。同一個IDR圖象的序列參數集有相同的seq_parameter_set_id,直到一個圖象的最後一個accessunit或者包括緩衝期消息的SEI Nalu,這時需要出現下一個圖象的序列參數集。下一個圖象的序列參數集被SEInalu激活。如果序列參數集和圖象參數集是通過其他傳輸管道發送的,則要保證以上的傳輸順序。 [3] 
參考資料