H264的PS封裝
一個完整的ps包封裝:
PSheader + PS system header + PS system Map + PES header + h264 data
因為一般視頻數(shù)據(jù)都是采用rtp打包發(fā)送疲吸,所以這里我就把ps封裝和rtp封裝放在一起講
視頻關(guān)鍵幀的封裝
RTP + PSheader + PS system header + PS system Map + PES header +h264 data視頻非關(guān)鍵幀的封裝
RTP +PS header + PES header + h264 data音頻幀的封裝:
RTP + PES header + G711
基于RTP的PS封裝首先按照ISO/IEC 13818-1將視音頻流封裝成PS包再將PS包以負(fù)載的方式封裝成RTP包
由于rtp包最大的負(fù)載長度是1400摘悴,所以大于1400的視頻數(shù)據(jù)都是需要分包處理的舰绘,這里我們就拿 I 幀數(shù)據(jù)來分析捂寿。
具體的分片方法:
當(dāng)我們獲取到一幀h264的關(guān)鍵幀數(shù)據(jù)時,先進(jìn)行PS封裝蔓彩,在視頻數(shù)據(jù)前加上 PS header + PS system header + PS system Map header ,當(dāng)前面的頭添加完畢后還需要再加一個 PES header,但是由于PES頭的負(fù)載長度類型是short赤嚼,最大為65536顺又,所以每65536字節(jié)的視頻數(shù)據(jù)后都得加一個PES頭稚照,如下:
| PS header | PS system header | PS system Map |PES | data | PES | data | PES | data|
這樣一個關(guān)鍵幀的PS封裝就完成了剩下的就是把封裝好的數(shù)據(jù)分包打RTP包了俯萌,每1300字節(jié)的數(shù)據(jù)前加一個RTP包頭咐熙,然后發(fā)送出去
PS封裝的幾個頭:
(1) PS header:14字節(jié)
pack_start_code : (32b) 起始碼字段 默認(rèn)0x000001BA 標(biāo)志一個包的開始
marker_bit :(2b) 標(biāo)記位字段2位字段姿骏,取值’01’分瘦。
system_clock_reference_base[32..30] :(3b)系統(tǒng)時鐘參考字段
marker_bit : (1b) 標(biāo)記位字段取值’1’
system_clock_reference_base[29..15] : (15b) 系統(tǒng)時鐘參考字段
marker_bit : (1b) 標(biāo)記位字段取值’1’
system_clock_reference_base[14..0] : (15b) 系統(tǒng)時鐘參考字段
marker_bit : (1b) 標(biāo)記位字段取值’1’
system_clock_reference_extension : (9b) 系統(tǒng)時鐘參考字段
marker_bit : (1b) 標(biāo)記位字段取值’1’
program_mux_rate : (22b) 節(jié)目復(fù)合速率字段
marker_bit : (1b) 標(biāo)記位字段取值’1’
marker_bit : (1b) 標(biāo)記位字段取值’1’
reserved : (5b) 填充字段
pack_stuffing_length : (3b) 包填充長度字段
節(jié)目復(fù)合速率字段 program_mux_rate (沒查到相關(guān)資料)
一個22位整數(shù)嘲玫,規(guī)定P-STD在包含該字段的包期間接收節(jié)目流的速率去团。其值以50字節(jié)/秒為單位。不允許取0值昼汗。該字段所表示的值用于在2.5.2中定義P-STD輸入端的字節(jié)到達(dá)時間鬼雀。該字段值在本標(biāo)準(zhǔn)中的節(jié)目多路復(fù)合流的不同包中取值可能不同源哩。
/12字節(jié)RTP頭/
80 60 00 00 00 00 00 00 0d 25 5a a5
/PS 頭/
00 00 01 ba 44 00 05 5f 94 01 00 60 1b f8
00 00 01 ba 開始碼
44 00 44 f5 84 01 系統(tǒng)時鐘參考字段励烦,二進(jìn)制如下
01 000 1 000000000000000 1 010101111110010 1 000000000 1
SCR = 90000/8 = 00000000 00000000 00101011 11110010 (SRC值是累加的,這個是第一幀數(shù)據(jù)的SRC值)
上面紅色的1都是marker_bit 標(biāo)記位
000 這三個位段的值是由SCR值的第30-32位填充赊锚,參考上述SRC值改抡,故填充3位0
000000000000000 這15位字段是由SRC值的第15-29位填充系瓢,故填充000000000000000
010101111110010 這15位字段是由SRC值的第0-14位填充夷陋,故填充 0101011 11110010
00 60 1b f8 二進(jìn)制如下:
00000000001100000000110 11 11111 000
00000000001100000000110 沒看懂用途胰锌,嘗試隨便取值不影響視頻和音頻资昧,不能取0荆忍,我這里用的是6150(1100000000110)
11111 5位填充字段 全部填1
00 3位擴(kuò)展長度填充字段 填0
(2) PS system header:18字節(jié)
system_header_start_code : (32b) 開始碼 0x000001BB
header_length : (16) 該字段后的系統(tǒng)標(biāo)題的字節(jié)長度
marker_bit : (1b) 標(biāo)記位字段取值’1’
rate_bound : (22b) 速率界限字段
marker_bit : (1b) 標(biāo)記位字段取值’1’
audio_bound : (6b) 音頻界限字段
fixed_flag : (1b) 固定標(biāo)志字段
CSPS_flag : (1b) CSPS標(biāo)志字段
system_audio_lock_flag : (1b) 系統(tǒng)音頻鎖定標(biāo)志字段
system_video_lock_flag : (1b) 系統(tǒng)視頻鎖定標(biāo)志字段
marker_bit : (1b) 標(biāo)記位字段取值’1’
vedio_bound : (5b) 視頻界限字段
packet_rate_restriction_flag: (1b) 分組速率限制標(biāo)志字段
reserved_bits : (7b) 保留位字段
stream_id : (8b) 流標(biāo)識字段
marker_bit : (2b) 取值’11’
P-STD_buffer_bound_scale : (1b) P-STD緩沖區(qū)界限比例字段
P-STD_buffer_size_bound : (13) P-STD緩沖區(qū)大小界限字段
System Header
00 00 01 bb 00 0c 80 1e ff fe e1 7f e0 e0 d8 c0 c0 20
00 00 01 bb : 四字節(jié)開始碼
00 0c : 當(dāng)前字段后該頭的長度 12
80 1e ff 轉(zhuǎn)成二進(jìn)制如下:
1 0000000000111101111111 1
111101111111 :rate_bound 該字段可被解碼器用于估計是否有能力對整個流解碼(沒查到如何填值)
fe e1 7f轉(zhuǎn)成二進(jìn)制如下:
111111 1 0 1 1 1 00001 0 1111111
111111: 音頻界限字段 audio_bound 6位字段叽唱,取值是在從0到32的閉區(qū)間中的整數(shù)棺亭,且不小于節(jié)目流中解碼過程同時活動的GB/T XXXX.3和GB/T AAAA.3音頻流的最大數(shù)目蟋软。在本小節(jié)中岳守,若STD緩沖區(qū)非空或展現(xiàn)單元正在P-STD模型中展現(xiàn)帜讲,則GB/T XXXX.3和GB/T AAAA.3音頻流的解碼過程是活動的。
1 : 固定標(biāo)志字段 fixed_flag 1位標(biāo)志位。置’1’時表示比特率恒定的操作嫩挤;置’0’時岂昭,表示操作的比特率可變。
0 : CSPS標(biāo)志字段 CSPS_flag 1位字段邑遏。
1: 系統(tǒng)音頻鎖定標(biāo)志字段 system_audio_lock_flag 置 ‘1’
1: 系統(tǒng)視頻鎖定標(biāo)志字段 system_video_lock_flag 置 ‘1’
00001: 視頻界限字段 video_bound
0: 分組速率限制標(biāo)志字段 packet_rate_restriction_flag 1位標(biāo)志位记盒。若CSPS標(biāo)識為’1’外傅,則該字段表示2.7.9中規(guī)定的哪個限制適用于分組速率。若CSPS標(biāo)識為’0’棚辽,則該字段的含義未定義冰肴。
1111111 : 7位字段熙尉。被保留供ISO/IEC將來使用。它的值應(yīng)為’111 1111’遣妥,除非ISO/IEC對它作出其它規(guī)定箫踩。
e0 e0 d8 c0 c0 20轉(zhuǎn)成二進(jìn)制如下:
11100000 11 1 0000011011000 11000000 11 0 0000000100000
11100000 : 流標(biāo)識字段 stream_id E0在gb28181中定義是視頻
11: 固定值
1: 1位字段。表示用于解釋后續(xù)P-STD_buffer_size_bound字段的比例系數(shù)谭贪。若前面的stream_id表示一個音頻流境钟,則該字段值為’0’。若表示一個視頻流俭识,則該字段值為’1’慨削。對于所有其它的流類型,該字段值可以為’0’也可以為’1’套媚。
0000011011000 : 音頻緩存區(qū)大小 216 單位是1024字節(jié)
11000000: 流標(biāo)識字段 stream_id C0在gb28181中定義是音頻
11: 固定值
0:
0000000100000: 視頻緩存區(qū)大小 32 單位 128字節(jié)
(3) PS Map Header:30字節(jié)
packet_start_code_prefix : (24b) 開始碼 0x000001
map_stream_id : (8) 映射流標(biāo)識字段 值為0xBC
program_stream_map_length: (16) 節(jié)目流映射長度字段
current_next_indicator : (1) 當(dāng)前下一個指示符字段
reserved : (2) 填充字段
program_stream_map_version: (5) 節(jié)目流映射版本字段
reserved : (7)
marker_bit : (1)
program_stream_info_length : (16) 節(jié)目流信息長度字段
elementary_stream_map_length: (16) 基本流映射長度字段
stream_type : (8) 流類型字段
elementary_stream_id : (8) 基本流標(biāo)識字段
elementary_stream_info_length : (16) 基本流信息長度字段
CRC_32 : (32) CRC 32字段
00 00 01 bc 00 18 e1 ff 00 00 00 08 1b e0 00 00 90 c0 00 00 23 b9 0f 3d
00 00 01 bc 開始碼加固定id
00 18 頭的長度
e1 ff 00 00 00 08二進(jìn)制如下:
11 00001 1111111 1 0000000000000000 0000000000001000
1: 當(dāng)前下一個指示符字段 current_next_indicator 1位字段缚态。置’1’時表示傳送的節(jié)目流映射當(dāng)前是可用的。置’0’時表示傳送的節(jié)目流映射還不可用堤瘤,但它將是下一個生效的表。
11: 填充字段 ‘11’
00001: 節(jié)目流映射版本字段 program_stream_map_version 5位字段本辐,表示整個節(jié)目流映射的版本號桥帆。一旦節(jié)目流映射的定義發(fā)生變化,該字段將遞增1慎皱,并對32取模老虫。在current_next_indicator為’1’時,該字段應(yīng)該是當(dāng)前適用的節(jié)目流映射的版本號茫多;在current_next_indicator為’0’時祈匙,該字段應(yīng)該是下一個適用的節(jié)目流映射的版本號。
1111111: 填充字段
0000000000000000: 節(jié)目流信息長度字段 program_stream_info_length 16位字段地梨,指出緊跟在該字段后的描述符的總長度
0000000000001000: 基本流映射長度字段 elementary_stream_map_length 16位字段菊卷,指出在該節(jié)目流映射中的所有基本流信息的字節(jié)長度缔恳。它只包括stream_type、elementary_stream_id和elementary_stream_info_length字段洁闰。(這里注意一下歉甚,這里的基本流映射長度,他只包括他后面的指定的那幾個定義字段的總和扑眉,即從從這個長度纸泄,我們可以知道后面他根了幾種類型的流定義,因為一種流的這個定義字段:stream_type(1BYTE)腰素、elementary_stream_id(1byte)和elementary_stream_info_length(2byte)字段總和為4個字節(jié)聘裁,所以用elementary_stream_map_length/4可以得到后面定義了幾個流類型信息。)
1b e0 00 00: 1b是H264視頻流 e0 :指視頻
00 00指后面跟著0個字節(jié)的視頻描述字節(jié)
90 c0 00 00: 90是G.711 音頻流:0x90 ,c0指音頻
00 00:0個字節(jié)描述符
23 b9 0f 3d : 32位字段弓千,它包含CRC值以在處理完整個節(jié)目流映射后在附錄A中定義的解碼器寄存器產(chǎn)生0輸出值衡便。/crc (23 b9 0f 3d)/
(4) PS PES Header:14字節(jié)
packet_start_code_prefix : (24b) 分組起始碼前綴字段 packet_start_code_prefix 0x000001
stream_id : (8) 流標(biāo)識字段 stream_id 這個字段的定義,其中0x(C0DF)指音頻洋访,0x(E0EF)為視頻
PES_packet_length : (16) PES分組長度字段 PES_packet_length
‘10’ : (2)
PES_scrambling_control : (2) PES加擾控制字段 PES_scrambling_control
PES_priority : (1) PES優(yōu)先級字段 PES_priority
data_alignment_indicator : (1) 數(shù)據(jù)對齊指示符字段 data_alignment_indicator
copyright: (1) 版權(quán)字段 copyright
original_or_copy : (1) 原始或拷貝字段 original_or_copy
PTS_DTS_flags : (2) PTS DTS標(biāo)志字段 PTS_DTS_flags
ESCR_flag : (1) ESCR標(biāo)志字段 ESCR_flag
ES_rate_flag : (1) ES速率標(biāo)志字段 ES_rate_flag
DSM_trick_mode_flag : (1) DSM特技方式標(biāo)志字段 DSM_trick_mode_flag
additional_copy_info_flag : (1) 附加版權(quán)信息標(biāo)志字段 additional_copy_info_flag
PES_CRC_flag : (1) PES CRC標(biāo)志字段 PES_CRC_flag
PES_extension_flag: (1) PES擴(kuò)展標(biāo)志字段 PES_extension_flag
PES_header_data_length: (8) PES標(biāo)題數(shù)據(jù)長度字段 PES_header_data_length
‘0011’ : (4)
PTS[32..30] : (3) 展現(xiàn)時間戳字段 PTS
marker_bit: (1)
PTS[29..15] : (15)
marker_bit : (1)
PTS[14..0] : (15)
marker_bit : (1)
/PES header/
00 00 01 e0 49 e6 88 80 05 31 00 01 57 e5
00 00 01: 開始碼
e0 : 視頻
49 e6: 視頻數(shù)據(jù)長度
88 80 05 :二進(jìn)制數(shù)據(jù)如下
10 00 1 0 0 0 10 0 0 0 0 0 0 00000101
10 : 固定值
00: PES加擾控制字段 PES_scrambling_control
1: PES優(yōu)先級字段 PES_priority ‘1’表示PES分組中有效負(fù)載的優(yōu)先級高于該字段為’0’的PES分組有效負(fù)載
0: 數(shù)據(jù)對齊指示符字段 data_alignment_indicator 當(dāng)值為’0’時镣陕,沒有定義是否有任何此種的對齊。
0: 版權(quán)字段 copyright當(dāng)值為’0’時姻政,沒有定義該材料是否受到版權(quán)保護(hù)
0: 原始或拷貝字段 original_or_copy 1位字段呆抑。置’1’時表示相關(guān)PES分組有效負(fù)載的內(nèi)容是原始的;值為’0’表示相關(guān)PES分組有效負(fù)載的內(nèi)容是一份拷貝
10: PTS DTS標(biāo)志字段 PTS_DTS_flags
2位字段汁展。當(dāng)值為’10’時鹊碍,PTS字段應(yīng)出現(xiàn)在PES分組標(biāo)題中;當(dāng)值為’11’時食绿,PTS字段和DTS字段都應(yīng)出現(xiàn)在PES分組標(biāo)題中侈咕;當(dāng)值為’00’時,PTS字段和DTS字段都不出現(xiàn)在PES分組標(biāo)題中器紧。值’01’是不允許的乎完。
0 0 0 0 0 0 六個擴(kuò)展標(biāo)志位 置0
00000101 : PES標(biāo)題數(shù)據(jù)長度字段 5 標(biāo)明后續(xù)還有五個字節(jié)
31 00 01 57 e5:二進(jìn)制如下
11 000 1 000000000000000 1 010101111110010 1
0011: 固定值
PTS = 90000/8 = 11250 二進(jìn)制:
10101111110010
000: PTS第30 -32位填充
000000000000000: PTS第15 -29位填充
010101111110010: PTS第0 -14位填充