1. 程式人生 > >H264碼流打包分析

H264碼流打包分析

1.引言

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單元以前傳送,並且重複傳送,大大提高糾錯能力。序列和影象引數集可以在“帶內”,也可以用更為可靠的其他“帶外”通道傳送。

相關推薦

H264編碼器8( H264打包分析(精華))

來自:https://www.cnblogs.com/lidabo/p/4602422.html H264碼流打包分析 SODB 資料位元串-->最原始的編碼資料 RBSP 原始位元組序列載荷-->在SODB的後面填加了結尾位元(RBSP trailing bits 一個bit“1”)若

H264打包分析

1.引言 H.264的主要目標: 1.高的視訊壓縮比 2.良好的網路親和性 解決方案: VCL   video coding layer    視訊編碼層 NAL   network abstraction layer   網路提取層 VCL:核心演算法引擎,塊,巨集塊及片的語法級別的定義 NAL:片級以上的

H264打包分析(zz)

SODB 資料位元串-->最原始的編碼資料 RBSP 原始位元組序列載荷-->在SODB的後面填加了結尾位元(RBSP trailing bits 一個bit“1”)若干位元“0”,以便位元組對齊。 EBSP 擴充套件位元組序列載荷-- >在RBSP基礎上填加了仿校

H264結構分析和rtp打包結構詳解

網路抽象層單元型別 (NALU): NALU頭由一個位元組組成,它的語法如下:       +---------------+       |0|1|2|3|4|5|6|7|       +-+-+-+-+-+-+-+-+       |F|NRI|  Type   |       +---------

H264打包成RTP包

H264碼流打包成RTP包的程式碼如下:#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h> #incl

h264rtp打包(一)

  一幀image編碼完的資料儲存在h264buffer中,編碼後的h264碼流的大小為nH264Size      因為對於NALU,並不是一幀對應一個NALU,而是對於SLICE而言,一個slice就封裝層一個nal,所以一幀可以有多個slice,即一幀有多個nal。

H264打包傳送(以live555為例)

H.264 視訊 RTP 負載格式 1. 網路抽象層單元型別 (NALU) NALU 頭由一個位元組組成, 它的語法如下:       +---------------+       |0|1|2|3|4|5|6|7|       +-+-+-+-+-+-+-+-+    

關於對H264的PS的封裝的相關代實現

真心 clip gef 但是 占用 udp 大致 結果 方法 轉自:http://www.cnblogs.com/lidabo/p/6604988.html 1、寫在開始之前: 最近因為新工作要維護別人留下的GB模塊代碼,先熟悉了流程,然後也試著封裝

關於對H264的TS的封裝的相關代實現

有效 當前 完成 read ble tco and mark comm 轉自:http://www.cnblogs.com/lidabo/p/6604998.html 1 寫在開始之前 在前段時間有分享一個H264封裝ps流到相關文章的,這次和

H264中SPS PPS詳解<轉>

擴展 vlc 地址 逗號 部分 級別 軟件 第一個 bottom 轉載地址:https://zhuanlan.zhihu.com/p/27896239 1 SPS和PPS從何處而來? 2 SPS和PPS中的每個參數起什麽作用? 3 如何解析SDP中

FFmpeg In Android - H264解碼/OpenGL ES渲染

主要思路是FFmpeg解碼H264得到一張yuv420p圖片後,傳遞給opengl es在著色器內部做圖片轉換yuv->rgb,然後通過紋理貼圖的方式渲染出來.這種方式的效率更高.核心程式碼如下: #include "common.h" #include "gl_util.h"

FFmpeg In Android - H264解碼/儲存Yuv

本節例子原始碼_NativeH264Android,修改自ffmpeg原始碼目錄/doc/examples/decode_video.c H264的碼流結構 H.264原始碼流(又稱為“裸流”)是由一個一個的NALU組成的,包括I幀,B幀,P幀等等,他們的結構如下圖所示: 其中每個

H265結構分析

文章目錄 1 準備工作 1.1 H265視訊檔案 1.2 參考文件 1.3 參考博文 2 分析 2.1 NALU type 2.1.1 H264 2.1.2 H265

H.264---格式分析

1、H.264的基本流結構 H.264 的基本流(elementary stream,ES)的結構分為兩層,包括視訊編碼層(VCL)和網路適配層(NAL)。視訊編碼層負責高效的視訊內容表示,而網路適配層負責以網路所要求的恰當的方式對資料進行打包和傳送。引入NAL並使之與VCL分離帶來的好處包括兩方面:1、使

H264中SPS PPS詳解

轉載地址:https://zhuanlan.zhihu.com/p/27896239 1 SPS和PPS從何處而來? 2 SPS和PPS中的每個引數起什麼作用? 3 如何解析SDP中包含的H.264的SPS和PPS串? 1 客戶端抓包 在做客戶端視訊解碼時,一

gstreamer將H264轉為avi視訊檔案示例

是時候記錄怎麼使用gstreamer庫將h264碼流轉為avi、mp4、flv等視訊檔案了。 下圖是本片示例視訊合成的流程圖,其中H264 採集與佇列實現部分程式碼未貼上。 總體思想是,“視訊合成主執行緒”根據視訊資料通道建立gstreamer視訊合成pipe

H.264打包為RTP

H264碼流打包成RTP包的程式碼如下: #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h&g

H264編碼器11( H.264 探索 第二部分 H264格式)

來自:https://segmentfault.com/a/1190000006698552 表1中描述了所有可能的資料包型別。 Type Definition 0 Undefined

Wireshark提取RTP包中的H264

1-- Dump RTP h.264 payload to raw h.264 file (*.264) 2-- According to RFC3984 to dissector H264 payload of RTP to NALU, and write it 3--

RTP協議全解析(H264和PS

寫在前面:RTP的解析,網上找了很多資料,但是都不全,所以我力圖整理出一個比較全面的解析, 其中借鑑了很多文章,我都列在了文章最後,在此表示感謝。 網際網路的發展離不開大家的無私奉獻,我決定從我做起,希望大家支援。 1、RTP Header解析