1. 程式人生 > >H.264碼流解析 一個SPS的nalu及獲取視訊的解析度

H.264碼流解析 一個SPS的nalu及獲取視訊的解析度

00 00 00 01 67 42 00 28 E9 00  
A0 0B 77 FE 00 02 00 03 C4 80  
00 00 03 00 80 00 00 1A 4D 88  
10 94 00 00 00 01

00 00 00 01為NALu頭,‍其餘碼流由十六進位制轉為二進位制 

67 0110 0111
42 0100 0010
00 0000 0000
28 0010 1000
E9 1110 1001
00 0000 0000
A0 1010 0000
0B 0000 1011
77 0111 01/11
……

94 1001 01//00

說明:

"/"後的碼流要對照標準中AnnexE的句法表,是VUI(VideoUsabilityInformation?)的內容,

不懂,不寫了,只寫SPS部分先。

"//"後面兩個0是補齊用的。

NAL層句法:碼,值
forbidden_zero_bit(f(1)):0,0
nal_ref_idc(u(2)):11, 3
nal_unit_type(u(5)): 0 0111,  7,  SPS

SPS序列引數集的句法:碼,值
profile_idc(u(8)) = 0100 0010,66 , baseline profile基礎檔次

constraint_set0_flag(u(1)):0,0
constraint_set1_flag(u(1)):0,0
constraint_set2_flag(u(1)):0,0
constraint_set3_flag(u(1)):0,0
reserved_zero_4bits(u(4)):0000,0

level_idc(u(8)) :00101000,40 ,級別

seq_parameter_set_id(ue(v)): 1, 0

log2_max_frame_num_minus4(ue(v): 1, 0
         MaxFrameNum = 2^(0+4) = 16

pic_order_cnt_type(ue(v)):1, 0

log2_max_pic_order_cnt_lsb_minus4(ue(v)):010 ,1
        MaxPicOrderCntLsb = 2^(1+4) = 32

num_ref_frames(ue(v)):010, 1

gaps_in_frame_num_value_allowed_flag(u(1)):0,0

pic_width_in_mbs_minus1(ue(v)): 0000001010000, 2^6-1+16 = 79
       PicWidthInMbs = pic_width_in_mbs_minus1 + 1 = 80

pic_height_in_map_units_minus1(ue(v)): 00000101101 ,2^5-1+13 = 44
       PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1 =45

frame_mbs_only_flag(u(1)):1,1

direct_8x8_inference_flag(u(1)): 1,1
frame_cropping_flag(u(1)):0,0
vui_parameters_present_flag(u(1)):1 ,1
這個引數為1,說明下面的句法存在

vui_parameters( )
aspect_ratio_info_present_flag(u(1)):1

其中:
pic_width_in_mbs_minus1 : 79
pic_height_in_map_units_minus1 : 44
說的很清楚:
(79+1)x16=1280
(44+1)x16=720
果然是 1280x720 !

================================================================================================

摘 要:H.264是新一代視訊編碼標準,具有廣泛的應用前景。本文主要研究了H.264碼流的問題。首先,介紹了H.264的簡單框架;其次,對碼流結構進行了分析,並概括出了碼流結構圖;最後,結合一個簡單試驗,給出了從H.264碼流中取得影象寬度和高度的方法。 關鍵詞:H.264;NAL;碼流結構 Analysis on the structure of coding streaming in H.264 GAO Qing, WANG Zhigang ( School of Computer Science & Technology, Soochow University,SuZhou 215006;) Abstract: H.264 is the newest video coding standard, and it will be widely used. In this article, the problem of the structure of coding streaming in H.264 is discussed. Firstly, the simple profile of H.264 video is introduced. Secondly, the structure of coding streaming is discussed , and then give the graph on it. Finally, by a simple experiment, give the method of getting picture’s width and height from the coding stream. Keywords: H.264;NAL;structure of coding streaming 引言 H.264是新一代視訊編碼標準,具有廣泛的應用前景,是ITU-T的視訊編碼專家組(VCEG)和 ISO/IEC的活動影象編碼專家組(MPEG)的聯合視訊組開發的一個新的數字視訊編碼標準,它既是ITU -T的H.264,又是ISO/IEC的MPEG-4的第10部分。H.264和以前的標準一樣,也是DPCM加變換編碼的混合編碼模式。它的應用目標廣泛,可滿足各種不同速率、不同場合的視訊應用,具有較好的抗誤碼和抗丟包的處理能力。H.264的基本系統無需使用版權,具有開放的性質,能很好地適應IP和無線網路的使用,這對目前因特網傳輸多媒體資訊、移動網中傳輸寬頻資訊等都具有重要意義。 1 H.264框架介紹   H.264中定義了3個框架[2],每個框架都支援一系列的編解碼功能,相應的有一系列的應用。下面作下簡單的介紹: (1) 基線框架(Baseline Profile):它作為H.264的一個簡單版本,應用面很廣。它支援幀間和幀內編碼,支援I幀和P幀,支援CAVLC等,其主要應用是可視電話視訊會議,無線通訊等。 (2) 主框架(Main Profile):包括支援交錯視訊,支援B幀,主要是在幀間編碼時使用,權重預測,熵編碼使用,支援CABAC等。它的主要應用是視訊儲存和電視廣播。採用了多項提高影象質量和增加壓縮比的技術措施,可用於SDTV,HDTV,DVD等。 (3) 擴充套件框架(Extended Profile):不支援交錯視訊和CABAC,但增加了一些在進行位元流切換時有效的幀模式,SI Switching I幀和SP Switching P幀,能夠有效的提高從錯誤中恢復的能力。它的主要應用是各種網路的視訊流傳輸應用。 2 H264碼流結構 2.1 H264分層結構 H.263定義的碼流結構是分級結構,共四層。自上而下分別為:影象層(picturelayer)、塊組層(GOB layer)、巨集塊層(macroblock layer)和塊層(block layer)。而與H.263相比,H.264的碼流結構和H.263的有很大的區別,它採用的不再是嚴格的分級結構。 H.264的功能分為兩層,視訊編碼層(VCL)和網路提取層(NALVCL資料即被壓縮編碼後的視訊資料序列。在VCL資料要封裝到NAL單元中之後,才可以用來傳輸或儲存。 NAL單元格式[2] 表1所示:
表1 NAL單元格式
NAL頭 RBSP NAL頭 RBSP
RBSP:封裝於網路抽象單元的資料稱之為原始位元組序列載荷RBSP,它是NAL的基本傳輸單元。其中,RBSP又分為視訊編碼資料和控制資料。其基本結構是:在原始編碼資料的後面填加了結尾位元。一個bit“1”若干位元“0”,以便位元組對齊。 2.2 H.264碼流結構圖 通過相關知識的查閱,概括出H.264的碼流結構圖[2]如圖1所示:

圖1 H.264的碼流結構

3 H.264碼流分析的應用 在有些時候,需要從H.264碼流中直接取得相關資訊(如:影象的寬度和影象的高度等等資訊)。下面介紹下取得相關資訊的方法: 影象的相關資訊儲存在網路提取層(NAL)的RBSP結構中,要取得影象的相關資訊,既要獲得影象的相關位。需依據RBSP結構,獲得pic_width_in_mbs_minus1和pic_height_in_map_units_minus1兩個值,那麼寬度為(pic_width_in_mbs_minus1+1)*16,高度為(pic_height_in_map_units_minus1+1)*16,但是有些情況還得考慮nNum_Ref_Frames的值,一般為1。 3.1獲得試驗資料 裝置:SUNNIC IP Cam 名字:ST100factory Firmware版本:p8b8 視訊格式:H.264 (1) 將裝置解析度設成176*144,使用Ethereal等抓包工具抓得一組資料,並去掉相應的RTP頭後,該資料為0x00,0x00,0x00,0x01,0x67,0x42,0x00,0x1E,0x99,0xA0,0xB1,0x31 (2) 將裝置解析度設成720*240,使用Ethereal等抓包工具抓得一組資料,並去掉相應的RTP頭後,該資料為0x00,0x00,0x00,0x01,0x67,0x42,0xE0,0x1E,0xDA,0x82,0xD1,0xF1 (3) 將裝置解析度設成720*480,使用Ethereal等抓包工具抓得一組資料,並去掉相應的RTP頭後,該資料為0x00,0x00,0x00,0x01,0x67,0x42,0xE0,0x1E,0xDB,0x82,0xD1,0xF1 3.2 相關程式的書寫 程式的關鍵程式碼如下: void GetH264Resolution(BYTE*pInBuf,int&nHeight,int&nWidth,int&nNum_Ref_Frames) {        ……              UE_V(nIndex,nShiftCount,nShiftBuffer,nNum_Ref_Frames,pFrameHead);                     DWORD gaps_in_frame_num_value_allowed_flag=0;               MyShift(1,nIndex,nShiftCount,nShiftBuffer,gaps_in_frame_num_value_allowed_flag,pFrameHead); DWORD pic_width_in_mbs_minus1=0; UE_V(nIndex,nShiftCount,nShiftBuffer,pic_width_in_mbs_minus1,pFrameHead);        DWORD pic_height_in_map_units_minus1=0;                  UE_V(nIndex,nShiftCount,nShiftBuffer,pic_height_in_map_units_minus1,pFrameHead);        UE_V(nIndex,nShiftCount,nShiftBuffer,pic_height_in_map_units_minus1,pFrameHead);        nWidth=(pic_width_in_mbs_minus1+1)*16; //影象的寬度        nHeight=(pic_height_in_map_units_minus1+1)*16;     //影象的高度 } voidMyShift(intnCount,int&nIndex,int&nShiftCount,BYTE&nShiftBuffer,DWORD&nRecv,BYTE*pInBuf) {//從資料流取得相應位的值。        while (nCount!=0)        {               if(nCount>nShiftCount)               {     nRecv=nRecv<<nShiftCount;                      nRecv|=nShiftBuffer>>(8-nShiftCount);                      nShiftBuffer=pInBuf[++nIndex];                      nCount-=nShiftCount;                      nShiftCount=8;                    }else               {     nRecv=nRecv<<nCount;                      nRecv|=nShiftBuffer>>(8-nCount);                                         nShiftCount-=nCount;                      nShiftBuffer<<=nCount;                      nCount=0;        }} } 3.3 試驗結果與結論 (1)將資料流0x00,0x00,0x00,0x01,0x67,0x42,0x00,0x1E,0x99,0xA0,0xB1,0x31放入GetH264Resolution,取得nWidth為176, nHeight為144,nNum_Ref_Frames為1。跟原資料比對,結果正確。 (2)將資料流0x00,0x00,0x00,0x01,0x67,0x42,0xE0,0x1E,0xDA,0x82,0xD1,0xF1放入GetH264Resolution,取得nWidth為720, nHeight為240,nNum_Ref_Frames為1。跟原資料比對,結果正確。 (3)將資料流0x00,0x00,0x00,0x01,0x67,0x42,0xE0,0x1E,0xDB,0x82,0xD1,0xF1放入GetH264Resolution,取得nWidth為720, nHeight為240,nNum_Ref_Frames為2。跟原資料比對,240正好是480的一半,而這裡的nNum_Ref_Frames正好是2。查閱相關資料發現,這裡為了讓資料能夠正常顯示,需要將2幀資料進行Interleave操作後,方能正常顯示。 H.264是新一代視訊編碼標準,具有廣泛的應用前景。應用此種方法,在解碼前,取得影象的高度和寬度,在某些需要知道影象的寬度和高度的場合,特別是在一些播放H264視訊的應用程式中,會有很大幫助。 參考文獻: [1] ITU-TRec.H.264/ISO/IEC 14496-10:2005,H.264 Advanced video coding for generic audiovisual services[S]. [2] 嚴曉飛. H.264碼流結構的分析及其實現的優化[D]. 西安電子科技大學西安電子科技大學,2007. [3]RICHARDSONI. H. 2 6 4 andMPEG-4Videocompression [M ].London: JohnW iley& Sons, 2003. 作者簡介: 高慶 (1985-),男,江蘇蘇州人,工程碩士,主要研究方向為視訊處理技術,嵌入式應用。E-mail:[email protected] 王志剛 (1984-),男,河南禹州人,工程碩士,主要研究方向為流媒體技術,嵌入式應用。E-mail:[email protected]