H264碼流解析及NALU


ffmpeg 從mp4上提取H264的nalu

http://blog.csdn.net/gavinr/article/details/7183499

639     /* bitstream filters */
640     REGISTER_BSF(AAC_ADTSTOASC,         aac_adtstoasc);
641     REGISTER_BSF(CHOMP,                 chomp);
642     REGISTER_BSF(DUMP_EXTRADATA,        dump_extradata);
643     REGISTER_BSF(H264_MP4TOANNEXB,      h264_mp4toannexb);
644     REGISTER_BSF(HEVC_MP4TOANNEXB,      hevc_mp4toannexb);
645     REGISTER_BSF(IMX_DUMP_HEADER,       imx_dump_header);
646     REGISTER_BSF(MJPEG2JPEG,            mjpeg2jpeg);
647     REGISTER_BSF(MJPEGA_DUMP_HEADER,    mjpega_dump_header);
648     REGISTER_BSF(MP3_HEADER_DECOMPRESS, mp3_header_decompress);
649     REGISTER_BSF(MPEG4_UNPACK_BFRAMES,  mpeg4_unpack_bframes);
650     REGISTER_BSF(MOV2TEXTSUB,           mov2textsub);
651     REGISTER_BSF(NOISE,                 noise);
652     REGISTER_BSF(REMOVE_EXTRADATA,      remove_extradata);
653     REGISTER_BSF(TEXT2MOVSUB,           text2movsub);

annex-b格式

 

http://blog.sina.com.cn/s/blog_5f435c1301015oxp.html

H264碼流的NAL起始字節分析

這是一段H264碼流,00 00 00 01這是對應forbidden_zero_bit的f(1),接着后面的nal_ref_idc的u(2),這個怎么解呀,有點暈。剛接觸不久,nal_unit_type的u(5),后面的profile_idc的u(8)指的是那幾個,是多少?

問題補充:

nal_ref_idc的u(2)對應67變成前兩位0 1也就是1,nal_unit_type取64接着的5位 10 01 1則組合成19 ,profile_idc的u(8)則是后面的64轉化為十進制則是100,level_idc則是0D是13,seq_parameter_set_id的ue(v),則指到AC了,這是哥倫布編碼,答案是0,這個是怎么算出來的?


 
2010-9-17 18:01

滿意回答

00 00 00 01是Start code后面的ox67為 0110 0111

forbidden_zero_bit 是禁止位,應該是第一位即f(1)=0,1為語法有錯誤

nal_ref_idc是參考級別,代表被其它幀參考情況,u(2)= 11 = 3最(0為無參考,詳見規范)

nal_unit_type是該幀的類型,為剩下的5位,u(5)= 0 0111 = 7

目前類型有:

//H264定義的類型 values for nal_unit_type

typedef enum {

 NALU_TYPE_SLICE    = 1,

 NALU_TYPE_DPA      = 2,

 NALU_TYPE_DPB      = 3,

 NALU_TYPE_DPC      = 4,

 NALU_TYPE_IDR      = 5,

 NALU_TYPE_SEI      = 6,

 NALU_TYPE_SPS      = 7,

 NALU_TYPE_PPS      = 8,

 NALU_TYPE_AUD      = 9,

 NALU_TYPE_EOSEQ    = 10,

 NALU_TYPE_EOSTREAM = 11,

 NALU_TYPE_FILL     = 12,

#if (MVC_EXTENSION_ENABLE)

 NALU_TYPE_PREFIX   = 14,

 NALU_TYPE_SUB_SPS  = 15,

 NALU_TYPE_SLC_EXT  = 20,

 NALU_TYPE_VDRD     = 24  // View and Dependency Representation Delimiter NAL Unit

#endif

} NaluType;

可以看出是NALU_TYPE_SPS  即sequence parameter sets

 

profile_idc的u(8)則是后面的64轉化為十進制則是100,

66 Baseline

77 Main

88 Extended

100 High (FRExt)

110 High 10 (FRExt)

122 High 4:2:2 (FRExt)

144 High 4:4:4 (FRExt)

 

100是High (FRExt)

 

“level_idc則是0D是13,seq_parameter_set_id的ue(v),則指到AC了,這是哥倫布編碼,答案是0,這個是怎么算出來的?“

就不太懂了。互相幫忙吧。

贊同

8

| 評論(1)

向TA求助

回答者: sindana 四級

擅長領域: 暫未定制

參加的活動: 暫時沒有參加的活動

提問者對於答案的評價:

還是蠻感謝的,挺詳細的!

以上內容來自鏈接 http://zhidao.baidu.com/question/184301276.html

最近在學習的h264視頻流的以.flv文件格式存盤。
在收到h264碼流的每個NAL數據(Buffer指針)時,對於如下代碼的理解:
 if((*(Buffer) == 0) && (*(Buffer+1) == 0) && (*(Buffer+2) == 0) && (*(Buffer+3) == 1)) //NAL頭的0x00 00 00 01起始碼
  {
   if(*(Buffer+4) == SPS_FRAME)
   { //ox67為 0110 0111(nal_unit_type為低5位,u(5)= 0 0111 = 7)
    frame_type = SPS_FRAME;
   }
   else if(*(Buffer+4) == PPS_FRAME)
   {  //ox68為 0110 1000 (nal_unit_type為低5位,u(5)= 0 1000 = 8)
    frame_type = PPS_FRAME;
   }
   else if(*(Buffer+4) == I_FRAME)
   { //ox65為 0110 0101 (nal_unit_type為低5位,u(5)= 0 0101 = 5)
    frame_type = I_FRAME;
   }
   else
   { //0x41為0100 00001 (nal_ref_idc是參考級別,代表被其它幀參考情況,u(2)= 10 = 2; nal_unit_type為低5位,u(5)= 0 0001 = 1)
    frame_type = P_FRAME;
   }
   if((*(Buffer+5) & 0x80) == 0x80)
   {
    start_frame = 1;
   }
  }

h264 圖像、幀、片、NALU

http://blog.csdn.net/zqnihao917/article/details/7760170

H.264 是一次概念的革新,它打破常規, 完全沒有 I 幀、P幀、B 幀的概念,也沒有 IDR幀的概念。對於 H.264中出現的一些概念從大到小排序依次是: 序列、圖像、片組、片、NALU、宏塊、亞宏塊、塊、像素。這里有幾點值得說明:
(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 屬於 一個片);  
   2編碼條帶數據分割塊A  slice_data_partition_a_layer_rbsp()

   3 編碼條帶數據分割塊Bslice_data_partition_b_layer_rbsp( )

   4 編碼條帶數據分割塊Cslice_data_partition_c_layer_rbsp( )
 
(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  也即非IDR圖像有可能全部包含I片。只不過我們平常最常見到的形式是:所有片都是 I片的圖像就是 IDR 圖像。其實這個時候 IDR 圖像的概念也被我們具體化和細小化了。但IDR圖像必定全部包含I片或SI片,不過只有用NALU的類型才能判斷是不是IDR圖像

一幅圖像由 1~N個片組組成,而每一個片組又由一個或若干個片組成一個片由一個NALU或三個NALU(假如有數據分割)組成。圖像解碼過程中總是按照片進行解碼,然后按照片組將解碼宏塊重組成圖像。從這種意義上講,片實際是最大的解碼單元
 
一個片又包含哪些類型的宏塊呢?
標准“表7-10”做了最好的說明。
 
一個 I 宏塊又分為哪些類型呢?
標准“表7-11”做了最好的說明。
 
一個 P 宏塊又分為哪些類型呢?
標准“表7-13”做了最好的說明。
 
一個 B 宏塊又分為哪些類型呢?
標准“表7-14”做了最好的說明。
 
一個 P 宏塊的亞宏塊又分為哪些類型呢?
標准“表7-17”做了最好的說明。
 
一個 B 宏塊的亞宏塊又分為哪些類型呢?

標准“表7-18”做了最好的說明。



  怎么區分H.264視頻流的I frame 和 Pframe? 收藏

怎么區分H.264視頻流的I frame 和 P frame?

 
我是新手,前些天自己看那H.264規范文檔及其他資料尋找答案時,
還有幾個概念的關系還沒能理解清楚,望達人指點一二:
NAL、Slice與frame意思及相互關系

NALnal_unit_type中的1(非IDR圖像的編碼條帶)、2(編碼條帶數據分割塊A)、3(編碼條帶數據分割塊B)、4(編碼條帶數據分割塊C)、5(IDR圖像的編碼條帶)種類型


Slice種的三種編碼模式:I_slice、P_slice、B_slice

還有frame的3種類型:I frame、P frame、 B frame之間有什么映射關系么?


最后,NAL nal_unit_type中的6(SEI)、7(SPS)、8(PPS)屬於什么幀呢?

---------------------------------------------------------------------------
1 frame的數據可以分為多個slice.
每個slice中的數據,在幀內預測只用到自己slice的數據, 與其他slice數據沒有依賴關系。 
NAL 是用來將編碼的數據進行大包的。 比如,每一個slice 數據可以放在NAL 包中。
I frame 是自己獨立編碼,不依賴於其他frame 數據。
P frame 依賴 I frame 數據。 
B frame 依賴 I frame, P frame 或其他 B frame 數據。

----------------------------------------------------------------------------
那NAL nal_unit_type中的哪幾種類型是Iframe,現在只能確定nal_unit_type==5(IDR圖像的編碼條帶)是I frame

sps、pps、SEI算不算I frame呢? 還有 屬於編碼條帶分割的DPA、DPB、DPC呢?

能給個從視頻流中提取I frame 和P frame的方法么?


-----------------------------------------------------------------------------------------------

一個frame是可以分割成多個Slice來編碼的,而一個Slice編碼之后被打包進一個NAL單元,不過NAL單元除了容納Slice編碼的碼流外,還可以容納其他數據,比如序列參數集SPS

------------------------------------------------------------------------------------------------

// H.264 NAL type
   enum H264NALTYPE
    {
        H264NT_NAL = 0,
        H264NT_SLICE, //P 幀
        H264NT_SLICE_DPA,
        H264NT_SLICE_DPB,
        H264NT_SLICE_DPC,
        H264NT_SLICE_IDR, // I 幀
        H264NT_SEI,
        H264NT_SPS,
        H264NT_PPS,
   };

//  0x00 0x00  0x00 0x01  0x65(0x45)   前四個字節為幀頭,0x65  是關鍵幀

//0x00  0x00 0x01  0x65(0x45)  也為關鍵幀


H264GetNALType(unsigned char * pBSBuf, const int nBSLen)
{
if ( nBSLen < 5 )  // 不完整的NAL單元
   return H264NT_NAL;


unsigned char * pBS = (unsigned char *)pBSBuf;

int nType = pBS[4] & 0x1F;  // NAL類型在固定的位置上 
if ( nType <= H264NT_PPS )
    return nType;// nTYPE  為5  表示關鍵幀


return 0;

------------------------------------------------------------------------------------------------

其中 H264NT_SLICE_IDR 是關鍵幀,H264NT_SLICE 是P幀

------------------------------------------------------------------------------------------------

一個frame是可以分割成多個Slice來編碼的,而一個Slice編碼之后被打包進一個NAL單元,不過NAL單元除了容納Slice編碼的碼流外,還可以容納其他數據,比如序列參數集SPS。

------------------------------------------------------------------------------------------------

1、NAL、Slice與frame意思及相互關系 

NAL指網絡提取層,里面放一些與網絡相關的信息
Slice是片的意思,264中把圖像分成一幀(frame)或兩場(field),而幀又可以分成一個或幾個片(Slilce);片由宏塊(MB)組成。宏塊是編碼處理的基本單元。

2、NALnal_unit_type中的1(非IDR圖像的編碼條帶)、2(編碼條帶數據分割塊A)、3(編碼條帶數據分割塊B)、4(編碼條帶數據分割塊C)、5(IDR圖像的編碼條帶)種類型 
與 Slice種的三種編碼模式:I_slice、P_slice、B_slice 
NAL nal_unit_type 里的五種類型,代表接下來數據是表示啥信息的和具體如何分塊。
I_slice、P_slice、B_slice表示I類型的片、P類型的片,B類型的片.其中I_slice為幀內預測模式編碼;P_slice為單向預測編碼或幀內模式;B_slice中為雙向預測或幀內模式。

3、還有frame的3種類型:I frame、P frame、 Bframe之間有什么映射關系么? 
I frame、P frame、 B frame關系同I_slice、P_slice、B_slice,slice和frame區別在問題1中已經講明白。

4、最后,NALnal_unit_type中的6(SEI)、7(SPS)、8(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激活。如果序列參數集和圖象參數集是通過其他傳輸管道發送的,則 要保證以上的傳輸順序。

------------------------------------------------------------------------------------------------

H.264視頻流是以NAL單元傳送的。。。但在一個NAL單元里面,可能既存放I-Slice(P-Slice或B-Slice),同事也可能存放圖像的其他信息
那么 是不是說 I frame, P frame,B frame是把收到的NAL單元中的VCL的信息先提取出,然后按內容進行I、P、Bframe分類?

而我們只能通過NAL nal_unit_type來判別NAL單元中數據的類型哈~~~

呵呵 不好意思 還沒有完全理解~~


NAL單元中首先會有一個H.264 NAL type,根據這個可以判斷是啥信息。如果是
H264NT_SLICE_DPA,H264NT_SLICE_DPB,H264NT_SLICE_DPC,H264NT_SLICE_IDR視頻數據相 關的,里面還會有Slicehead頭信息,根據這個頭信息,可以判斷屬於I-Slice(P-Slice或B-Slice),之后對於每個宏塊,都會有 MB head信息,根據宏塊頭信息可以判斷塊模式。

 

h264 Nalu 詳解

http://blog.csdn.net/d_l_u_f/article/details/7260772

 

H.264的主要目標:

1.高的視頻壓縮比

2.良好的網絡親和性

解決方案:

VCL  video coding layer       視頻編碼層

NAL  network abstraction layer  網絡提取層

VCL:核心算法引擎,塊,宏塊及片的語法級別的定義

NAL:片級以上的語法級別(如序列參數集和圖像參數集),同時支持以下功能:獨立片解碼,起始碼唯一保證,SEI以及流格式編碼數據傳送

VCL設計目標:盡可能地獨立於網絡的情況下進行高效的編解碼

NAL設計目標:根據不同的網絡把數據打包成相應的格式,將VCL產生的比特字符串適配到各種各樣的網絡和多元環境中。

NALU頭結構:NALU類型(5bit)、重要性指示位(2bit)、禁止位(1bit)。

NALU類型:1~12由H.264使用,24~31由H.264以外的應用使用。

重要性指示:標志該NAL單元用於重建時的重要性,值越大,越重要。

禁止位:網絡發現NAL單元有比特錯誤時可設置該比特為1,以便接收方丟掉該單元。

2.NAL語法語義

NAL層句法:

在編碼器輸出的碼流中,數據的基本單元是句法元素。

句法表征句法元素的組織結構。

語義闡述句法元素的具體含義。

分組都有頭部,解碼器可以很方便的檢測出NAL的分界,依次取出NAL進行解碼。

但為了節省碼流,H.264沒有另外在NAL的頭部設立表示起始位置的句法元素。

如果編碼數據是存儲在介質上的,由於NAL是依次緊密相連的,解碼器就無法在數據流中分辨出每個NAL的起始位置和終止位置。

解決方案:在每個NAL前添加起始碼:0X000001

在某些類型的介質上,為了尋址的方便,要求數據流在長度上對齊,或某個常數的整數倍。所以在起始碼前添加若干字節的0來填充。

檢測NAL的開始:

0X000001和0X000000

我們必須考慮當NAL內部出現了0X000001和0X000000

解決方案:

H.264提出了“防止競爭”機制:

0X000000——0X00000300

0X000001——0X00000301

0X000002——0X00000302

0X000003——0X00000303

為此,我們可以知道:

在NAL單元中,下面的三字節序列不應在任何字節對齊的位置出現

0X000000

0X000001

0X000002

Forbidden_zero_bit =0;

Nal_ref_idc:表示NAL的優先級。0~3,取值越大,表示當前NAL越重要,需要優先受到保護。如果當前NAL是屬於參考幀的片,或是序列參數集,或是圖像參數集這些重要的單位時,本句法元素必需大於0。

Nal_unit_type:當前NAL 單元的類型

3.H.264的NAL層處理

結構示意圖:

NAL以NALU(NAL unit)為單元來支持編碼數據在基於分組交換技術網絡中傳輸。

它定義了符合傳輸層或存儲介質要求的數據格式,同時給出頭信息,從而提供了視頻編碼和外部世界的接口。

NALU:定義了可用於基於分組和基於比特流系統的基本格式

RTP封裝:只針對基於NAL單元的本地NAL接口。

三種不同的數據形式:

SODB 數據比特串-->最原始的編碼數據

RBSP 原始字節序列載荷-->在SODB的后面填加了結尾比特(RBSP trailing bits 一個bit“1”)若干比特“0”,以便字節對齊

EBSP 擴展字節序列載荷-->在RBSP基礎上填加了仿校驗字節(0X03)它的原因是: 在NALU加到Annexb上時,需要添加每 組NALU之前的開始碼StartCodePrefix,如果該NALU對應的slice為一幀的開始則用4位字節表示,ox00000001,否則用3 位字節表示ox000001.為了使NALU主體中不包括與開始碼相沖突的,在編碼時,每遇到兩個字節連續為0,就插入一個字節的0x03。解碼時將 0x03去掉。也稱為脫殼操作

處理過程:

1.  將VCL層輸出的SODB封裝成nal_unit, Nal_unit是一個通用封裝格式,可以適用於有序字節流方式和IP包交換方式。

2.  針對不同的傳送網絡(電路交換|包交換),將nal_unit 封裝成針對不同網絡的封裝格      式。

 

第一步的具體過程:

VCL層輸出的比特流SODB(String Of Data Bits),到nal_unit之間,經過了以下三步處理:

1.SODB字節對齊處理后封裝成RBSP(Raw Byte Sequence Payload)。

2.為防止RBSP的字節流與有序字節流傳送方式下的SCP(start_code_prefix_one_3bytes,0x000001)出現 字節競爭情形,循環檢測RBSP前三個字節,在出現字節競爭時在第三字節前加入emulation_prevention_three_byte (0x03),具體方法:

nal_unit( NumBytesInNALunit ) {

forbidden_zero_bit

nal_ref_idc

nal_unit_type

NumBytesInRBSP = 0

for( i = 1; i < NumBytesInNALunit; i++ ) {

if( i + 2 < NumBytesInNALunit && next_bits( 24 ) = = 0x000003 ) {

rbsp_byte[ NumBytesInRBSP++ ]

rbsp_byte[ NumBytesInRBSP++ ]

i += 2

emulation_prevention_three_byte /* equal to 0x03 */

} else

rbsp_byte[ NumBytesInRBSP++ ]

}

}

3. 防字節競爭處理后的RBSP再加一個字節的header(forbidden_zero_bit+ nal_ref_idc+ nal_unit_type),封裝成nal_unit.

第二步的具體過程:

 

case1:有序字節流的封裝

 

byte_stream_nal_unit( NumBytesInNALunit ) {

while( next_bits( 24 ) != 0x000001 )

zero_byte /* equal to 0x00 */

if( more_data_in_byte_stream( ) ) {

start_code_prefix_one_3bytes /* equal to 0x000001 */ nal_unit( NumBytesInNALunit )

}

}

類似H.320和MPEG-2/H.222.0等傳輸系統,傳輸NAL作為有序連續字節或比特流,同時要依靠數據本身識別NAL單元邊界。在這樣的 應用系統中,H.264/AVC規范定義了字節流格式,每個NAL單元前面增加3個字節的前綴,即同步字節。在比特流應用中,每個圖像需要增加一個附加字 節作為邊界定位。還有一種可選特性,在字節流中增加附加數據,用做擴充發送數據量,能實現快速邊界定位,恢復同步

Case2:IP網絡的RTP打包封裝

分組打包的規則

    (1)額外開銷要少,使MTU尺寸在100~64k字節范圍都可以;

    (2)不用對分組內的數據解碼就可以判別該分組的重要性;

    (3)載荷規范應當保證不用解碼就可識別由於其他的比特丟失而造成的分組不可解碼;

    (4)支持將NALU分割成多個RTP分組;

   (5)支持將多個NALU匯集在一個RTP分組中。

    RTP的頭標可以是NALU的頭標,並可以實現以上的打包規則。

    一個RTP分組里放入一個NALU,將NALU(包括同時作為載荷頭標的NALU頭)放入RTP的載荷中,設置RTP頭標值。為了避免IP層對大分組的再 一次分割,片分組的大小一般都要小於MTU尺寸。由於包傳送的路徑不同,解碼端要重新對片分組排序,RTP包含的次序信息可以用來解決這一問題。

 NALU分割

    對於預先已經編碼的內容,NALU可能大於MTU尺寸的限制。雖然IP層的分割可以使數據塊小於64千字節,但無法在應用層實現保護,從而降低了非等重保 護方案的效果。由於UDP數據包小於64千字節,而且一個片的長度對某些應用場合來說太小,所以應用層打包是RTP打包方案的一部分。

    新的討論方案(IETF)應當符合以下特征:

    (1)NALU的分塊以按RTP次序號升序傳輸;

    (2)能夠標記第一個和最后一個NALU分塊;

    (3)可以檢測丟失的分塊。

 NALU合並

    一些NALU如SEI、參數集等非常小,將它們合並在一起有利於減少頭標開銷。已有兩種集合分組:

    (1)單一時間集合分組(STAP),按時間戳進行組合;

    (2)多時間集合分組(MTAP),不同時間戳也可以組合。

NAL規范視頻數據的格式,主要是提供頭部信息,以適合各種媒體的傳輸和存儲。NAL支持各種網絡,包括:

1.任何使用RTP/IP協議的實時有線和無線Internet 服務

2.作為MP4文件存儲和多媒體信息文件服務

3.MPEG-2系統

4.其它網

NAL規定一種通用的格式,既適合面向包傳輸,也適合流傳送。實際上,包傳輸和流傳輸的方式是相同的,不同之處是傳輸前面增加了一個起始碼前綴

在類似Internet/RTP面向包傳送協議系統中,包結構中包含包邊界識別字節,在這種情況下,不需要同步字節。

NAL單元分為VCL和非VCL兩種

VCL NAL單元包含視頻圖像采樣信息,

非VCL包含各種有關的附加信息,例如參數集(頭部信息,應用到大量的VCL NAL單元)、提高性能的附加信息、定時信息等

參數集:

參數集是很少變化的信息,用於大量VCL NAL單元的解碼,分為兩種類型:

1.序列參數集,作用於一串連續的視頻圖像,即視頻序列。

   兩個IDR圖像之間為序列參數集。IDR和I幀的區別見下面。

2.  圖像參數集,作用於視頻序列中的一個或多個個別的圖像

序列和圖像參數集機制,減少了重復參數的傳送,每個VCL NAL單元包含一個標識,指

向有關的圖像參數集,每個圖像參數集包含一個標識,指向有關的序列參數集的內容

因此,只用少數的指針信息,引用大量的參數,大大減少每個VCL NAL單元重復傳送的信息。

序列和圖像參數集可以在發送VCL NAL單元以前發送,並且重復傳送,大大提高糾錯能力。序列和圖像參數集可以在“帶內”,也可以用更為可靠的其他“帶外”通道傳送。

存儲單元:

一組指定格式的NAL單元稱為存儲單元,每個存儲單元對應一個圖像。每個存儲單元包含一組VCL NAL單元,組成一個主編碼圖像,VCL NAL單元由表示視頻圖像采樣的像條所組成。存儲單元前面可以加一個前綴,分界存儲單元,附加增強信息(SEI)(如圖像定時信息)也可以放在主編碼圖像 的前面。主編碼圖像后附加的VCL NAL單元,包含同一圖像的冗余表示,稱為冗余編碼圖像,當主編碼圖像數據丟失或損壞時,可用冗余編碼圖像解碼。

編碼視頻序列

一個編碼視頻序列由一串連續的存儲單元組成,使用同一序列參數集。每個視頻序列可獨立解碼。編碼序列的開始是即時刷新存儲單元(IDR)。IDR是一個I幀圖像,表示后面的圖像不用參考以前的圖像。一個NAL單元流可包含一個或更多的編碼視頻序列。

RTP協議:

實時傳輸協議(Real-time Transport Protocol,RTP)是在Internet上處理多媒體數據流的一種網絡協議,利用它能夠在一對一(單播)或者一對多(multicast,多播) 的網絡環境中實現傳流媒體數據的實時傳輸。RTP通常使用UDP來進行多媒體數據的傳輸,但如果需要的話可以使用TCP或者ATM等其它協議,整個RTP 協議由兩個密切相關的部分組成:RTP數據協議和RTP控制協議。實時流協議(Real Time Streaming Protocol, RTSP)最早由Real Networks和Netscape公司共同提出,它位於RTP和RTCP之上,其目的是希望通過IP網絡有效地傳輸多媒體數據。

RTP數據協議

RTP數據協議負責對流媒體數據進行封包並實現媒體流的實時傳輸,每一個RTP數據報都由頭部(Header)和負載(Payload)兩個部分組成,其中頭部前12個字節的含義是固定的,而負載則可以是音頻或者視頻數據。RTP數據報的頭部格式如圖1所示:

其中比較重要的幾個域及其意義如下:

CSRC記數(CC)  表示CSRC標識的數目。CSRC標識緊跟在RTP固定頭部之后,用來表示RTP數據報的來源,RTP協議允許在同一個會 話中存在多個數據源,它們可以通過RTP混合器合並為一個數據源。例如,可以產生一個CSRC列表來表示一個電話會議,該會議通過一個RTP混合器將所有 講話者的語音數據組合為一個RTP數據源。

 負載類型(PT)  標明RTP負載的格式,包括所采用的編碼算法、采樣頻率、承載通道等。例如,類型2表明該RTP數據包中承載的是用ITU G.721算法編碼的語音數據,采樣頻率為8000Hz,並且采用單聲道。

  序列號  用來為接收方提供探測數據丟失的方法,但如何處理丟失的數據則是應用程序自己的事情,RTP協議本身並不負責數據的重傳。

  時間戳 記錄了負載中第一個字節的采樣時間,接收方能夠時間戳能夠確定數據的到達是否受到了延遲抖動的影響,但具體如何來補償延遲抖動則是應用程序自己的 事情。從RTP數據報的格式不難看出,它包含了傳輸媒體的類型、格式、序列號、時間戳以及是否有附加數據等信息,這些都為實時的流媒體傳輸提供了相應的基 礎。RTP協議的目的是提供實時數據(如交互式的音頻和視頻)的端到端傳輸服務,因此在RTP中沒有連接的概念,它可以建立在底層的面向連接或面向非連接 的傳輸協議之上;RTP也不依賴於特別的網絡地址格式,而僅僅只需要底層傳輸協議支持組幀(Framing)和分段(Segmentation)就足夠 了;另外RTP本身還不提供任何可靠性機制,這些都要由傳輸協議或者應用程序自己來保證。在典型的應用場合下,RTP一般是在傳輸協議之上作為應用程序的 一部分加以實現的,如圖2所示:

RTCP控制協議

 RTCP控制協議需要與RTP數據協議一起配合使用,當應用程序啟動一個RTP會話時將同時占用兩個端口,分別供RTP和RTCP使用。RTP本 身並不能為按序傳輸數據包提供可靠的保證,也不提供流量控制和擁塞控制,這些都由RTCP來負責完成。通常RTCP會采用與RTP相同的分發機制,向會話 中的所有成員周期性地發送控制信息,應用程序通過接收這些數據,從中獲取會話參與者的相關資料,以及網絡狀況、分組丟失概率等反饋信息,從而能夠對服務質 量進行控制或者對網絡狀況進行診斷。

RTCP協議的功能是通過不同的RTCP數據報來實現的,主要有如下幾種類型:

SR  發送端報告,所謂發送端是指發出RTP數據報的應用程序或者終端,發送端同時也可以是接收端。

RR  接收端報告,所謂接收端是指僅接收但不發送RTP數據報的應用程序或者終端。

SDES  源描述,主要功能是作為會話成員有關標識信息的載體,如用戶名、郵件地址、電話號碼等,此外還具有向會話成員傳達會話控制信息的功能。

BYE  通知離開,主要功能是指示某一個或者幾個源不再有效,即通知會話中的其他成員自己將退出會話。

APP  由應用程序自己定義,解決了RTCP的擴展性問題,並且為協議的實現者提供了很大的靈活性。

RTCP數據報攜帶有服務質量監控的必要信息,能夠對服務質量進行動態的調整,並能夠對網絡擁塞進行有效的控制。由於RTCP數據報采用的是多播方式,因此會話中的所有成員都可以通過RTCP數據報返回的控制信息,來了解其他參與者的當前情況。

在一個典型的應用場合下,發送媒體流的應用程序將周期性地產生發送端報告SR,該RTCP數據報含有不同媒體流間的同步信息,以及已經發送的數據報 和字節的計數,接收端根據這些信息可以估計出實際的數據傳輸速率。另一方面,接收端會向所有已知的發送端發送接收端報告RR,該RTCP數據報含有已接收 數據報的最大序列號、丟失的數據報數目、延時抖動和時間戳等重要信息,發送端應用根據這些信息可以估計出往返時延,並且可以根據數據報丟失概率和時延抖動 情況動態調整發送速率,以改善網絡擁塞狀況,或者根據網絡狀況平滑地調整應用程序的服務質量。

RTSP實時流協議

作為一個應用層協議,RTSP提供了一個可供擴展的框架,它的意義在於使得實時流媒體數據的受控和點播變得可能。總的說來,RTSP是一個流媒體表 示協議,主要用來控制具有實時特性的數據發送,但它本身並不傳輸數據,而是必須依賴於下層傳輸協議所提供的某些服務。RTSP可以對流媒體提供諸如播放、 暫停、快進等操作,它負責定義具體的控制消息、操作方法、狀態碼等,此外還描述了與RTP間的交互操作。

RTSP在制定時較多地參考了HTTP/1.1協議,甚至許多描述與HTTP/1.1完全相同。RTSP之所以特意使用與HTTP/1.1類似的語 法和操作,在很大程度上是為了兼容現有的Web基礎結構,正因如此,HTTP/1.1的擴展機制大都可以直接引入到RTSP中。

由RTSP控制的媒體流集合可以用表示描述(Presentation Description)來定義,所謂表示是指流媒體服務器提供給客戶機的一個或者多個媒體流的集合,而表示描述則包含了一個表示中各個媒體流的相關信 息,如數據編碼/解碼算法、網絡地址、媒體流的內容等。

雖然RTSP服務器同樣也使用標識符來區別每一流連接會話(Session),但RTSP連接並沒有被綁定到傳輸層連接(如TCP等),也就是說在 整個RTSP連接期間,RTSP用戶可打開或者關閉多個對RTSP服務器的可靠傳輸連接以發出RTSP 請求。此外,RTSP連接也可以基於面向無連接的傳輸協議(如UDP等)。

RTSP協議目前支持以下操作:

檢索媒體  允許用戶通過HTTP或者其它方法向媒體服務器提交一個表示描述。如表示是組播的,則表示描述就包含用於該媒體流的組播地址和端口號;如果表示是單播的,              為了安全在表示描述中應該只提供目的地址。

邀請加入  媒體服務器可以被邀請參加正在進行的會議,或者在表示中回放媒體,或者在表示中錄制全部媒體或其子集,非常適合於分布式教學。

添加媒體  通知用戶新加入的可利用媒體流,這對現場講座來講顯得尤其有用。與HTTP/1.1類似,RTSP請求也可以交由代理、通道或者緩存來進行處理。

3. JM86中的處理

涉及的函數:

流程圖:

 

I幀和IDR幀的區別:

1.  在 H.264 中 I 幀並不具有隨機訪問的能力,這個功能由 IDR 承擔。以前的標准中由 I 幀承擔。

2.  IDR 會導致 DPB (參考幀列表——這是關鍵所在)清空,而 I 不會。

3.  I和IDR幀其實都是I幀,都是使用幀內預測的。但是IDR幀的作用是立刻刷新,使錯誤不致傳播,從IDR幀開始,重新算一個新的序列開始編碼。

4.  IDR圖像一定是I圖像,但I圖像不一定是IDR圖像。一個序列中可以有很多的I圖像,I圖像之后的圖像可以引用I圖像之間的圖像做運動參考。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM