首先咱們須要知道PS包流格式是怎麼樣的:ide
針對H264 作以下PS 封裝:每一個IDR NALU 前通常都會包含SPS、PPS 等NALU,所以將SPS、PPS、IDR 的NALU 封裝爲一個PS 包,包括ps 頭,而後加上PS system header,PS system map,PES header+h264 raw data。因此一個IDR NALU PS 包由外到內順序是:PSheader| PS system header | PS system Map | PES header | h264 raw data。對於其它非關鍵幀的PS 包,就簡單多了,直接加上PS頭和PES 頭就能夠了。順序爲:PS header | PES header | h264raw data。以上是對只有視頻video 的狀況,若是要把音頻Audio也打包進PS 封裝,也能夠。當有音頻數據時,將數據加上PES header 放到視頻PES 後就能夠了。順序以下:PS 包=PS頭|PES(video)|PES(audio),再用RTP 封裝發送就能夠了。post
上面這是對數據流的一個總體封裝格式,下面咱們來看看每一個封裝中的每一個部分:學習
(來自http://blog.csdn.net/wangjiannuaa/article/details/7679486)ui
首先是PSheader部分:(來自MPEG2標準中文文檔)編碼
語法spa |
位數.net |
助記符rest |
pack_header() {code |
|
|
pack_start_code |
32 |
bslbf |
'01' |
2 |
bslbf |
system_clock_reference_base[32..30] |
3 |
bslbf |
marker_bit |
1 |
bslbf |
system_clock_reference_base[29..15] |
15 |
bslbf |
marker_bit |
1 |
bslbf |
system_clock_reference_base[14..0] |
15 |
bslbf |
marker_bit |
1 |
bslbf |
system_clock_reference_extension |
9 |
uimsbf |
marker_bit |
1 |
bslbf |
program_mux_rate |
22 |
uimsbf |
marker_bit |
1 |
bslbf |
marker_bit |
1 |
bslbf |
reserved |
5 |
bslbf |
pack_stuffing_length |
3 |
uimsbf |
for (i=0;i<pack_stuffing_length;i++){ |
|
|
stuffing_byte |
8 |
bslbf |
} |
|
|
if (nextbits()==system_header_start_code) { |
|
|
system_header() |
|
|
} |
|
|
} |
|
|
節目流包(PS header)中各字段的語義定義:
包起始碼字段 pack_start_code
值爲'0000 0000 0000 0000 0000 0001 1011 1010' (0x000001BA)的位串,用來標誌一個包的開始。
系統時鐘參考字段 system_clock_reference_base,system_clock_reference_extenstion
系統時鐘參考(SCR)是一個分兩部分編碼的42位字段。第一部分system_clock_reference_base是一個長度爲33位的字段,其值SCR_base(i)由式2-19給出;第二部分system_clock_reference_extenstion是一個長度爲9位的字段,其值SCR_ext(i)由式2-20給出。SCR字段指出了基本流中包含ESCR_base最後一位的字節到達節目目標解碼器輸入端的指望時間。
SCR字段的編碼頻率要求見2.7.1。
標記位字段 marker_bit
1位字段,取值'1'。
節目複合速率字段 program_mux_rate
一個22位整數,規定P-STD在包含該字段的包期間接收節目流的速率。其值以50字節/秒爲單位。不容許取0值。該字段所表示的值用於在2.5.2中定義P-STD輸入端的字節到達時間。該字段值在本標準中的節目多路複合流的不一樣包中取值可能不一樣。
包填充長度字段 pack_stuffing_length
3位整數,規定該字段後填充字節的個數。
填充字節字段 stuffing_byte
8位字段,取值恆爲'1111 1111'。該字段能由編碼器插入,例如爲了知足通道的要求。它由解碼器丟棄。在每一個包標題中最多隻容許有7個填充字節。
它的定義字節順序,以下所示:
4B的包起始碼:
byte 0 |
byte 1 |
byte 2 |
byte 3 |
||||||||||||||||||||||||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
0000 0000 0000 0000 0000 0001 |
1011 1010 |
PACK identifier -- 0xBA
系統時鐘基準(SCR-System Clock Reference)的基本部分、SCR的擴展部分:
byte 4 |
byte 5 |
byte 6 |
byte 7 |
byte 8 |
byte 9 |
||||||||||||||||||||||||||||||||||||||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
01 |
SCR 32..30 |
1 |
SCR 29..15 |
1 |
SCR 14..00 |
1 |
SCR_ext |
1 |
PS複用速率:
byte 10 |
byte 11 |
byte 12 |
byte 13 |
||||||||||||||||||||||||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Program_Mux_Rate |
1 |
1 |
reserved |
pack_stuffing_length
|
==============================================================
接下來看看PS system header(即PS系統頭:節目流系統標題)部分的定義:(來自MPEG-2標準文檔)
表2-34 節目流系統標題
語 法 |
位數 |
助記符 |
system_header() { |
|
|
system_header_start_code |
32 |
bslbf |
header_length |
16 |
uimsbf |
marker_bit |
1 |
bslbf |
rate_bound |
22 |
uimsbf |
marker_bit |
1 |
bslbf |
audio_bound |
6 |
uimsbf |
fixed_flag |
1 |
bslbf |
CSPS_flag |
1 |
bslbf |
system_audio_lock_flag |
1 |
bslbf |
system_video_lock_flag |
1 |
bslbf |
marker_bit |
1 |
bslbf |
vedio_bound |
5 |
uimsbf |
packet_rate_restriction_flag |
1 |
bslbf |
reserved_bits |
7 |
bslbf |
while (nextbits()=='1') { |
|
|
stream_id |
8 |
uimsbf |
'11' |
2 |
bslbf |
P-STD_buffer_bound_scale |
1 |
bslbf |
P-STD_buffer_size_bound |
13 |
uimsbf |
} |
|
|
} |
|
|
系統標題中各字段的語義定義:
系統標題起始碼字段 system_header_start_code
取值'0000 0000 0000 0000 0000 0001 1011 1011' (0x000001BB)的位串,指出系統標題的開始。
標題長度字段 header_length
16位字段。指出該字段後的系統標題的字節長度。在本規範未來的擴充中可能擴展該字段。
速率界限字段 rate_bound
22位字段,取值不小於編碼在節目流的任何包中的program_mux_rate字段的最大值。該字段可被解碼器用於估計是否有能力對整個流解碼。
音頻界限字段 audio_bound
6位字段,取值是在從0到32的閉區間中的整數,且不小於節目流中解碼過程同時活動的GB/T XXXX.3和GB/T AAAA.3音頻流的最大數目。在本小節中,若STD緩衝區非空或展示單元正在P-STD模型中展示,則GB/T XXXX.3和GB/T AAAA.3音頻流的解碼過程是活動的。
固定標誌字段 fixed_flag
1位標誌位。置'1'時表示比特率恆定的操做;置'0'時,表示操做的比特率可變。在恆定比特率的操做期間,複合的GB/T XXXX.1流中的system_clock_reference字段值應聽從下面的線性公式:
SCR_base(i)=((c1×i+c2) DIV 300) % 233 (2-22)
SCR_ext(i)=((c1×i+c2) DIV 300) % 300 (2-23)
其中:
c1 對全部i均有效的實型常數;
c2 對全部i均有效的實型常數;
i 在GB/T XXXX.1複合流中包含任何system_clock_reference字段的最後一位的字節索引。
CSPS標誌字段 CSPS_flag
1位字段。置'1'時,節目流符合2.7.9中定義的限制。
系統音頻鎖定標誌字段 system_audio_lock_flag
1位字段。表示在系統目標解碼器的音頻採樣率和system_clock_frequency之間存在規定的比率。system_clock_frequency在2.5.2.1中定義而音頻採樣率由GB/T XXXX.3規定。若是對節目流中全部音頻基本流的全部展示單元,system_clock_frequency和實際音頻採樣率的比例SCASR是恆定的,且對音頻流中所指出的標準採樣率和下表中數值相等,則該字段只能爲'1'。
SCASR=(system_clock_frequency) / audio_sample_rate_in_the_P-STD (2-24)
記號X/Y表示實數除法。
標準音頻採樣頻率(kHz) |
16 |
32 |
22.05 |
44.1 |
24 |
48 |
SCASR |
27 000 000 -------- 16 000 |
27 000 000 ------- 32 000 |
27 000 000 ------ 22 050 |
27 000 000 ------ 44 100 |
27 000 000 ------ 24 000 |
27 000 000 -------- 48 000 |
系統視頻鎖定標誌字段 system_video_lock_flag
1位字段。表示在系統目標解碼器的視頻幀速率和system_clock_frequency之間存在規定的比率。system_clock_frequency在2.5.2.1中定義而視頻幀速率由GB/T XXXX.2規定。若是對GB/T XXXX.1中全部視頻基本流的全部展示單元,system_clock_frequency和實際視頻幀速率的比例SCFR是恆定的,且對視頻流中所指出的標準幀速率和下表中數值相等,則該字段只能爲'1'。
SCFR=system_clock_frequency / frame_rate_in_the_P-STD (2-25)
標準幀速率(Hz) |
23.976 |
24 |
25 |
29.97 |
30 |
50 |
59.94 |
60 |
SCFR |
1 126 125 |
1 125 000 |
1 080 000 |
900 900 |
900 000 |
540 000 |
450 450 |
450 000 |
比率SCFR的值是精確的。對於23.976,29.97或59.94幀/秒的標準速率,實際的幀速率與標準速率略有不一樣。
視頻界限字段 video_bound
5位字段,取值是在從0到16的閉區間中的整數且不小於節目流中解碼過程同時活動的GB/T XXXX.2和GB/T AAAA.2流的最大數目。在本小節中,若P-STD緩衝區非空或展示單元正在P-STD模型中展示,則GB/T XXXX.2和GB/T AAAA.2視頻流的解碼過程是活動的。
分組速率限制標誌字段 packet_rate_restriction_flag
1位標誌位。若CSPS標識爲'1',則該字段表示2.7.9中規定的哪一個限制適用於分組速率。若CSPS標識爲'0',則該字段的含義未定義。
保留位字段 reserved_bits
7位字段。被保留供ISO/IEC未來使用。它的值應爲'111 1111',除非ISO/IEC對它做出其它規定。
流標識字段 stream_id
8位字段。指示其後的P-STD_buffer_bound_scale和P-STD_buffer_size_bound字段所涉及的流的編碼和基本流號碼。
若取值'1011 1000',則其後的P-STD_buffer_bound_scale和P-STD_buffer_size_bound字段指節目流中全部的音頻流。
若取值'1011 1001',則其後的P-STD_buffer_bound_scale和P-STD_buffer_size_bound字段指節目流中全部的視頻流。
若stream_id取其它值,則應該是大於或等於'1011 1100'的一字節值且應根據表2-18解釋爲流的編碼和基本流號碼。
節目流中的每一個基本流應在每一個系統標題中經過這種機制精確地規定一次它的P-STD_buffer_bound_scale和P-STD_buffer_size_bound。
P-STD緩衝區界限比例字段 P-STD_buffer_bound_scale
1位字段。表示用於解釋後續P-STD_buffer_size_bound字段的比例係數。若前面的stream_id表示一個音頻流,則該字段值爲'0'。若表示一個視頻流,則該字段值爲'1'。對於全部其它的流類型,該字段值能夠爲'0'也能夠爲'1'。
P-STD緩衝區大小界限字段 P-STD_buffer_size_bound
13位無符號整數,取值不小於節目流中流n的全部分組的P-STD緩衝區大小BSn的最大值。若P-STD_buffer_bound_scale的值爲'0',則該字段以128字節爲單位來度量緩衝區大小的邊界。若P-STD_buffer_bound_scale的值爲'1',則該字段以1024字節爲單位來度量緩衝區大小的邊界。所以:
if (P-STD_buffer_bound_scale = = 0)
BSn≤P-STD_buffer_size_bound×128
else
BSn≤P-STD_buffer_size_bound×1024
因此對於系統頭部的解析,咱們通常只要先首先判斷是否存在系統頭(根據系統頭的起始碼0x000001BB),而後咱們讀取系統頭的頭部長度,即PS SYSTEM HEADER LENGTH部分,而後根據頭部的長度,跳過PS系統頭。進入下一個部分,即PS 節目流映射頭。
==========================================================
接着看看PS流的節目映射流部分(節目流映射)定義:(來自MPEG-2標準文檔)
表2-35 節目流映射
語 法 |
位數 |
助記符 |
program_stream_map() { |
|
|
packet_start_code_prefix |
24 |
bslbf |
map_stream_id |
8 |
uimsbf |
program_stream_map_length |
16 |
uimsbf |
current_next_indicator |
1 |
bslbf |
reserved |
2 |
bslbf |
program_stream_map_version |
5 |
uimsbf |
reserved |
7 |
bslbf |
marker_bit |
1 |
bslbf |
program_stream_info_length |
16 |
uimsbf |
for (i=0;i<N;i++){ |
|
|
descriptor() |
|
|
} |
|
|
elementary_stream_map_length |
16 |
uimsbf |
for (i=0;i<N1;i++){ |
|
|
stream_type |
8 |
uimsbf |
elementary_stream_id |
8 |
uimsbf |
elementary_stream_info_length |
16 |
uimsbf |
for (i=0;i<N2;i++) { |
|
|
descriptor() |
|
|
} |
|
|
} |
|
|
CRC_32 |
32 |
rpchof |
} |
|
|
節目流映射中各字段的語義定義:
分組起始碼前綴字段 packet_start_code_prefix
24位碼。它和跟隨其後的map_stream_id共同組成一個分組起始碼以標誌分組的開始。該字段是值爲'0000 0000 0000 0000 0000 0001' (0x000001)的位串。
映射流標識字段 map_stream_id
8位字段,值爲0xBC。
節目流映射長度字段 program_stream_map_length
16位字段。指示緊跟在該字段後的program_stream_map中的字節數。該字段的最大值爲1018(0x3FA)。
當前下一個指示符字段 current_next_indicator
1位字段。置'1'時表示傳送的節目流映射當前是可用的。置'0'時表示傳送的節目流映射還不可用,但它將是下一個生效的表。
節目流映射版本字段 program_stream_map_version
5位字段,表示整個節目流映射的版本號。一旦節目流映射的定義發生變化,該字段將遞增1,並對32取模。在current_next_indicator爲'1'時,該字段應該是當前適用的節目流映射的版本號;在current_next_indicator爲'0'時,該字段應該是下一個適用的節目流映射的版本號。
節目流信息長度字段 program_stream_info_length
16位字段,指出緊跟在該字段後的描述符的總長度。
標記位字段 marker_bit
1位字段,取值爲'1'。
基本流映射長度字段 elementary_stream_map_length
16位字段,指出在該節目流映射中的全部基本流信息的字節長度。它只包括stream_type、elementary_stream_id和elementary_stream_info_length字段。(這裏注意一下,這裏的基本流映射長度,他只包括他後面的指定的那幾個定義字段的總和,即從從這個長度,咱們能夠知道後面他根了幾種類型的流定義,由於一種流的這個定義字段:stream_type(1BYTE)、elementary_stream_id(1byte)和elementary_stream_info_length(2byte)字段總和爲4個字節,因此用elementary_stream_map_length/4能夠獲得後面定義了幾個流類型信息。)
流類型字段 stream_type
8位字段,根據表2-29規定了流的類型。該字段只能標誌包含在PES分組中的基本流且取值不能爲0x05。
(這裏咱們暫時根據國標GB28181中的定義能夠知道
一、MPEG-4 視頻流: 0x10;
二、H.264 視頻流: 0x1B;
三、SVAC 視頻流: 0x80;
四、G.711 音頻流: 0x90;
五、G.722.1 音頻流: 0x92;
六、G.723.1 音頻流: 0x93;
七、G.729 音頻流: 0x99;
八、SVAC音頻流: 0x9B。
由於節目映射流字段只有在關鍵幀打包的時候,纔會存在,因此若是要判斷PS打包的流編碼類型,就根據這個字段來判斷。)
基本流標識字段 elementary_stream_id
8位字段,指出該基本流所在PES分組的PES分組標題中stream_id字段的值。
(這個字段的定義,其中0x(C0~DF)指音頻,0x(E0~EF)爲視頻)
基本流信息長度字段 elmentary_stream_info_length
16位字段,指出緊跟在該字段後的描述符的字節長度。(即這個類型的流描述長度。這個後面的字段後面的指定長度不在elementary_stream_map_length指定的範圍類。)
CRC 32字段 CRC_32
32位字段,它包含CRC值以在處理完整個節目流映射後在附錄A中定義的解碼器寄存器產生0輸出值。
對於這個字段的解析,咱們須要取值0x000001BC的位串,指出節目流映射的開始,暫時不須要處理,讀取Header Length直接跳過便可,若是須要解析流編碼類型,必須詳細解析這個字段。
=================PES包=============================
接下來咱們來分析下PES包的內容:PES包=PES header+code raw data;
先看下PES header:(來自http://blog.csdn.net/chen495810242/article/details/39207305)
接着咱們來看看解析步驟:(來自MPEG-2標準文檔)
表2-17 PES分組
語 法 |
位數 |
助記符 |
PES_packet(){ |
|
|
packet_start_code_prefix |
24 |
bslbf |
stream_id |
8 |
uimsbf |
PES_packet_length |
16 |
uimsbf |
if(stream_id != program_stream_map |
|
|
&& stream_id !=padding_stream |
|
|
&& stream_id !=private_stream_2 |
|
|
&& stream_id !=ECM |
|
|
&& stream_id !=EMM |
|
|
&& stream_id !=program_stream_directory |
|
|
&& stream_id !=DSMCC_stream |
|
|
&& stream_id !=ITU-T Rec.H.222.1 type E stream){ |
|
|
'10' |
2 |
bslbf |
PES_scrambling_control |
2 |
bslbf |
PES_priority |
1 |
bslbf |
data_alignment_indicator |
1 |
bslbf |
copyright |
1 |
bslbf |
original_or_copy |
1 |
bslbf |
PTS_DTS_flags |
2 |
bslbf |
ESCR_flag |
1 |
bslbf |
ES_rate_flag |
1 |
bslbf |
DSM_trick_mode_flag |
1 |
bslbf |
additional_copy_info_flag |
1 |
bslbf |
PES_CRC_flag |
1 |
bslbf |
PES_extension_flag |
1 |
bslbf |
PES_header_data_length |
8 |
uimsbf |
if(PTS_DTS_flags =='10'){ |
|
|
'0010' |
4 |
bslbf |
PTS[32..30] |
3 |
bslbf |
marker_bit |
1 |
bslbf |
PTS[29..15] |
15 |
bslbf |
marker_bit |
1 |
bslbf |
PTS[14..0] |
15 |
bslbf |
marker_bit |
1 |
bslbf |
} |
|
|
if(PTS_DTS_flags =='11'){ |
|
|
'0011' |
4 |
bslbf |
PTS[32..30] |
3 |
bslbf |
marker_bit |
1 |
bslbf |
PTS[29..15] |
15 |
bslbf |
marker_bit |
1 |
bslbf |
PTS[14..0] |
15 |
bslbf |
marker_bit |
1 |
bslbf |
'0001' |
4 |
bslbf |
PTS[32..30] |
3 |
bslbf |
marker_bit |
1 |
bslbf |
PTS[29..15] |
15 |
bslbf |
marker_bit |
1 |
bslbf |
PTS[14..0] |
15 |
bslbf |
marker_bit |
1 |
bslbf |
} |
|
|
if(ESCR_flag =='1'){ |
|
|
reserved |
2 |
bslbf |
ESCR_base[32..30] |
3 |
bslbf |
marker_bit |
1 |
bslbf |
ESCR_base[29..15] |
15 |
bslbf |
marker_bit |
1 |
bslbf |
ESCR_base[14..0] |
15 |
bslbf |
marker_bit |
1 |
bslbf |
ESCR_extension |
9 |
uimsbf |
marker_bit |
1 |
bslbf |
} |
|
|
if(ES_rate_flag =='1'){ |
|
|
marker_bit |
1 |
bslbf |
ES_rate |
22 |
uimsbf |
marker_bit |
1 |
bslbf |
} |
|
|
if (DSM_trick_mode_flag =='1'){ |
|
|
trick_mode_control |
3 |
uimsbf |
if ( trick_mode_control = =fast_forward ) { |
|
|
field_id |
2 |
bslbf |
intra_slice_refresh |
1 |
bslbf |
frequency_truncation |
2 |
bslbf |
} |
|
|
else if ( trick_mode_control = = slow_motion ) { |
|
|
rep_cntrl |
5 |
uimsbf |
} |
|
|
else if ( trick_mode _control = = freeze_frame ) { |
|
|
field_id |
2 |
uimsbf |
reserved |
3 |
bslbf |
} |
|
|
else if ( trick_mode _control = = fast_reverse ) { |
|
|
field_id |
2 |
bslbf |
intra_slice_refresh |
1 |
bslbf |
frequency_truncation |
2 |
bslbf |
else if ( trick_mode_control = = slow_reverse ) { |
|
|
rep_cntrl |
5 |
uimsbf |
} |
|
|
else |
|
|
reserved |
5 |
bslbf |
} |
|
|
if ( additional_copy_info_flag = ='1'){ |
|
|
marker_bit |
1 |
bslbf |
additional_copy_info |
7 |
bslbf |
} |
|
|
if (PES_CRC_flag==‘1’){ |
|
|
previous_PES_packet_CRC |
16 |
bslbf |
} |
|
|
if ( PES_extension_flag =='1') { |
|
|
PES_private_data_flag |
1 |
bslbf |
pack_header_field_flag |
1 |
bslbf |
program_packet_sequence_counter_flag |
1 |
bslbf |
P-STD_buffer_flag |
1 |
bslbf |
reserved |
3 |
bslbf |
PES_extension_flag_2 |
1 |
bslbf |
if(PES_private_data_flag =='1'){ |
|
|
PES_private_data |
128 |
bslbf |
} |
|
|
if (pack_header_field_flag == '1'){ |
|
|
pack_field_length |
8 |
uimsbf |
pack_header() |
|
|
} |
|
|
if (program_packer_sequence_counter_flag == '1'){ |
|
|
marker_bit |
1 |
bslbf |
program_packet_sequence_counter |
7 |
uimsbf |
marker-bit |
1 |
bslbf |
MPEG1_MPEG2_indentifier |
1 |
bslbf |
original_stuff_length |
6 |
uimsbf |
} |
|
|
if (P-STD_buffer_flag = = '1'({ |
|
|
'01' |
2 |
bslbf |
P-STD_buffer_scale |
1 |
bslbf |
P-STD_buffer_size |
13 |
uimsbf |
} |
|
|
if (PES_extension_flag_2 == '1'{ |
|
|
marker_bit |
1 |
bslbf |
PES_extension_field_length |
7 |
uimsbf |
for(i=0;i<PES_extension_field_length;i++){ |
|
|
reserved |
8 |
bslbf |
} |
|
|
} |
|
|
} |
|
|
for (i=0;i<N1;i++)} |
|
|
stuffing_byte |
8 |
bslbf |
} |
|
|
for (i=0;i<N2;i++){ |
|
|
PES_packet_data_byte |
8 |
bslbf |
} |
|
|
} |
|
|
else if (stream_id = = program_stream_map |
|
|
|| stream_id = = private_stream_2 |
|
|
|| stream_id = = ECM |
|
|
|| stream_id = = EMM |
|
|
|| stream_id = = program_stream_directory |
|
|
|| stream_id = = DSMCC_stream |
|
|
|| stream_id = = ITU-T Rec. H.222.1 type E stream ){ |
|
|
for (i=0;i<PES_packet_length;i++){ |
|
|
PES_packet_data_byte |
8 |
bslbf |
} |
|
|
} |
|
|
else if (steam_id = = padding_stream){ |
|
|
for (i=0;i<PES_packet_length;i++){ |
|
|
padding_byte |
8 |
bslbf |
} |
|
|
} |
|
|
} |
|
|
其中:
表2-18 Stream_id賦值
stream_id |
注 |
流 編 碼 |
1011 1100 |
1 |
program_stream_map(0xBC) |
1011 1101 |
2 |
private_stream_1(0xBD) |
1011 1110 |
|
padding_stream(0xBE) |
1011 1111 |
3 |
private_stream-2(0xBF) |
110x xxxx |
|
GB/T XXXX.3或GB/T AAAA.3音頻流編號xxxx(0xC0~0xDF) |
1110 xxxx |
|
GB/T XXXX.2或GB/T AAAA.2視頻流編號xxxx(0xE0~0xEF) |
1111 0000 |
3 |
ECM_stream(0xF0) |
1111 0001 |
3 |
EMM_stream(0xF1) |
1111 0010 |
5 |
GB/T XXXX.1附錄B或GB/T XXXX.6_DSMCC_stream(0xF2) |
1111 0011 |
2 |
ISO/IEC_13522_stream(0xF3) |
1111 0100 |
6 |
ITU-T Rec. H.222.1類型A |
1111 0101 |
6 |
ITU-T Rec. H.222.1類型B |
1111 0110 |
6 |
ITU-T Rec. H.222.1類型C |
1111 0111 |
6 |
ITU-T Rec. H.222.1類型D |
1111 1000 |
6 |
ITU-T Rec. H.222.1類型E |
1111 1001 |
7 |
ancillary_stream(0xF9) |
1111 1010…1111 1110 |
|
保留數據流 |
1111 1111 |
4 |
program_stream_directory(0xFF) |
符號x表示值'0'或'1'均被容許且可產生相同的流類型。流號碼由x的取值決定。 注 1 類型爲program_stream_map的PES分組有惟一的語法,在2.5.4.1中做了規定。 2 類型爲private_stream_1和ISO/IEC_13352_stream的PES分組與GB/T XXXX.2及GB/T XXXX.3音頻流服從相同的PES分組語法。 3 類型爲private_stream_2,ECM_stream和EMM_stream的PES分組與private_stream_1類似,除了在PES_packet_length字段後未規定語法。 4 類型爲program_stream_directory的PES分組有惟一的語法,在2.5.5中做了規定。 5 類型爲DSM_CC_stream的PES分組有惟一的語法,在GB/T XXXX.6中做了規定。 6 stream_id與表2-29中的stream_type 0x09相關聯。 7 stream_id僅用於PES分組。PES分組在傳輸流中攜帶了來源於節目流或GB/T AAAA.1系統流的數據(參見2.4.3.7)。 |
PES分組中各字段的語義定義
分組起始碼前綴字段 packet_start_code_prefix
24位代碼,它和後面的stream_id構成了標識分組開始的分組起始碼。它是一個值爲'0000 0000 0000 0000 0000 0001' (0x000001)的位串。
流標識字段 stream_id
在節目流中,它規定了基本流的號碼和類型。定義參見表2-18。在傳輸流中,它能夠被設定爲正確描述表2-18中定義的基本流類型的任何有效值。在傳輸流中,基本流類型在2.4.4的節目特定信息中做了規定。
PES分組長度字段 PES_packet_length
16位字段,指出了PES分組中跟在該字段後的字節數目。值爲0表示PES分組長度要麼沒有規定要麼沒有限制。這種狀況只容許出如今有效負載包含來源於傳輸流分組中某個視頻基本流的字節的PES分組中。
PES加擾控制字段 PES_scrambling_control
2位字段,表示PES分組有效負載的加擾方式。當加擾發生在PES層,PES分組標題,若是有可選字段的話也包括在內,不該被加擾(參見2-19)。
PES優先級字段 PES_priority
1位字段,指示PES分組中有效負載的優先級。'1'表示PES分組中有效負載的優先級高於該字段爲'0'的PES分組有效負載。多路複合器能使用該字段來區分安排基本流中數據的優先級。傳輸機制不該改動該字段。
數據對齊指示符字段 data_alignment_indicator
1位標誌。置'1'時表示PES分組標題後緊跟着在2.6.10中的data_alignment_indicator所指出的視頻起始碼或音頻同步字,若是有data_alignment_indicator描述符的話。若其值爲'1'且無該描述符,則須要在表2-47和2-48中alignment_type '01'所表示的對齊。當值爲'0'時,沒有定義是否有任何此種的對齊。
版權字段 copyright
1位字段。置'1'時表示相關PES分組有效負載的材料受到版權保護。當值爲'0'時,沒有定義該材料是否受到版權保護。2.6.24中描述的版權描述符與包含PES分組的基本流相關。若描述符做用於包含PES分組的材料,則版權標誌被置爲'1'。
原始或拷貝字段 original_or_copy
1位字段。置'1'時表示相關PES分組有效負載的內容是原始的;值爲'0'表示相關PES分組有效負載的內容是一份拷貝。
PTS DTS標誌字段 PTS_DTS_flags
2位字段。當值爲'10'時,PTS字段應出如今PES分組標題中;當值爲'11'時,PTS字段和DTS字段都應出如今PES分組標題中;當值爲'00'時,PTS字段和DTS字段都不出如今PES分組標題中。值'01'是不容許的。
ESCR標誌字段 ESCR_flag
1位標誌。置'1'時表示ESCR基礎和擴展字段出如今PES分組標題中;值爲'0'表示沒有ESCR字段。
ES速率標誌字段 ES_rate_flag
1位標誌。置'1'時表示ES_rate字段出如今PES分組標題中;值爲'0'表示沒有ES_rate字段。
DSM特技方式標誌字段 DSM_trick_mode_flag
1位標誌。置'1'時表示有8位特技方式字段;值爲'0'表示沒有該字段。
附加版權信息標誌字段 additional_copy_info_flag
1位標誌。置'1'時表示有附加拷貝信息字段;值爲'0'表示沒有該字段。
PES CRC標誌字段 PES_CRC_flag
1位標誌。置'1'時表示CRC字段出如今PES分組標題中;值爲'0'表示沒有該字段。
PES擴展標誌字段 PES_extension_flag
1位標誌。置'1'時表示PES分組標題中有擴展字段;值爲'0'表示沒有該字段。
PES標題數據長度字段 PES_header_data_length
8位字段。指出包含在PES分組標題中的可選字段和任何填充字節所佔用的總字節數。該字段以前的字節指出了有無可選字段。
標記位字段 marker_bit
值爲'1'的1位字段。
展示時間戳字段 PTS
展示時間與解碼時間的關係以下:PTS是一個編碼在三個分離字段中的33位數字。它指出了基本流n的第k個展示單元在系統目標解碼器中的展示時間tpn(k)。PTS的值以系統時鐘頻率的1/300(即90 kHz)爲單位。展示時間由PTS根據式2-11計算而來。對編碼展示時間戳頻率的約束參見2.7.4。
PTS(k)=((system_clock_frequency×tpn(k)) DIV 300) % 233 (2-11)
其中,tpn(k)是展示單元Pn(k)的展示時間。
對音頻而言,若PES分組標題中有PTS,則它是指PES分組中開始的第一個存取單元。若PES分組中有音頻存取單元的首字節,則有一個音頻存取單元開始於該PES分組中。
對視頻而言,若PES分組標題中有PTS,則它是指包含PES分組中開始的第一個畫面起始碼的存取單元。若PES分組中有畫面起始碼的首字節,則有一個畫面起始碼開始於該PES分組中。
對音頻展示單元(PU),low_delay序列中的視頻PU以及B畫面,展示時間tpn(k)應等於tdn(k)。
對於非low_delay中的I畫面和P畫面,在存取單元(AU) k和k'之間無解碼不連續時,展示時間tpn(k)應等於下一個傳輸的I畫面或P畫面的解碼時間tdn(k) (參見2.7.5)。如有解碼不連續或流終止,則tpn(k)和tdn(k)之間的差異應與初始流一直延續,沒有不連續也沒有終止時徹底相同。
注1: low_delay序列是low_delay標誌被設置的視頻序列(參見GB/T XXXX.2中的6.2.2.3)。
若音頻中有濾波,則系統模型假定濾波不會致使延遲。所以,編碼時PTS所涉及的採樣與解碼時PTS所涉及的採樣是相同的。對於可伸縮編碼,參見2.7.6。
解碼時間戳字段 DTS
DTS是一個編碼在三個分離字段中的33位數字。它指出了基本流n的第j個展示單元在系統目標解碼器中的解碼時間tdn(j)。DTS的值以系統時鐘頻率的1/300 (即90 kHz)爲單位。解碼時間由DTS根據式2-12計算而來:
DTS(j)=((system_clock_frequency×tdn(j)) DIV 300) % 233 (2-12)
其中,tdn(j)是存取單元An(j)的解碼時間。
對視頻而言,若PES分組標題中有DTS,則它是指包含PES分組中開始的第一個畫面起始碼的存取單元。若PES分組中有畫面起始碼的首字節,則該畫面起始碼開始於該PES分組中。
對於可伸縮編碼,參見2.7.6。
ESCR字段 ESCR_base,ESCR_extension
42位字段,分兩部分編碼。第一部分是一個長度爲33位的字段,其值ESCR_base(i)由式2-14給出;第二部分是一個長度爲9位的字段,其值ESCR_ext(i)由式2-15給出。ESCR字段指出了基本流中包含ESCR_base最後一個比特的字節到達PES-STD輸出端的指望時間(參見2.5.2.4)。
特別地
ESCR(i)=ESCR_base(i)×300+ESCR_ext(i) (2-13)
其中:
ESCR_base(i)=((system_clock_frequency×t(i)) DIV 300) % 233 (2-14)
ESCR _ext(i)=((system_clock_frequency×t(i)) DIV 1) % 300 (2-15)
ESCR和ES_rate字段(參見下面緊接的語義)包含與PES流序列相關的時間信息。這些字段應知足2.7.3中定義的約束。
基本流速率字段 ES_rate
22位無符號整數。對於PES流而言,它指出了系統目標解碼器接收PES分組的速率。該字段在它所屬的PES分組以及同一個PES流的後續PES分組中一直有效,直到遇到一個新的ES_rate字段。該字段的值以50字節/秒爲單位,且不能爲0。該字段用於定義PES流的字節到達P-STD輸入端的時間(參見2.5.2.4中的定義)。在各個PES分組中,編碼在該字段中的值可能不一樣。
特技方式控制字段 trick_mode_control
3位字段。它表示做用於相關視頻流的特技方式。對其它類型的基本流,該字段及其後5位的含義沒有定義。trick_mode狀態的定義參見2.4.2.3的特技模式部分。
當trick_mode狀態爲假時,對GB/T XXXX.2視頻而言,解碼過程輸出漸進序列中每幅畫面的次數N由repeat_first_field和top_field_first字段來規定。對GB/T AAAA.2視頻而言,由序列標題決定。
對於隔行序列,當trick_mode狀態爲假時,對GB/T XXXX.2視頻而言,次數N由repeat_first_field和progressive_frame字段來規定。
當trick_mode狀態爲真時,畫面的播放次數依賴於值N。
表2-20 特技方式控制值
值 |
描 述 |
'000' |
快進 |
'001' |
慢動做 |
'010' |
凍結幀 |
'011' |
快倒 |
'100' |
慢倒 |
'101'-'111' |
保留 |
當該字段值發生變化或特技模式操做中止時,可能會出現下列狀況的任意組合:
l 時基不連續;
l 解碼不連續;
l 連續性計數器不連續;
在特技模式的狀況下,解碼和展示的非標準速度可能會致使視頻基本流數據中定義的某些字段值不正確。一樣,片斷結構的語義約束也可能無效。這些例外所涉及的視頻語法元素爲:
l bit_rate;
l vbv_delay;
l repeat_first_field;
l v_axis_positive;
l field_sequence;
l subcarrier;
l burst_amplitude;
l subcarrier_phase;
在特技模式中,解碼器不該該依賴於編碼在這些字段中的值。
標準並不要求解碼器能解碼trick_mode_control字段。可是,能解碼該字段的解碼器應能知足如下標準要求。
快進fast forword
trick_mode_control字段中的值'000'。當該值出現時,它表示一個快進視頻流並定義了PES分組標題中後續5位的含義。intra_slice_refresh位能夠被設定爲'1'以指出可能有丟失的宏塊。解碼器能夠用前一個解碼畫面中相同位置的宏塊來代替。表2-21中定義的field_id字段,表示應該顯示哪一個或哪些字段。frequency_truncation字段指出了可能包括的一個係數受限集合。該字段值的含義如表2-22所示。
慢動做 slow motion
trick_mode_control字段中的值'001'。當該值出現時,它表示一個慢動做視頻流,並定義了PES分組標題中後續5個比特的含義。對漸進序列而言,該畫面應被顯示N×rep_cntrl時間,其中N定義如上。
對GB/T AAAA.2視頻和GB/T XXXX.2視頻漸進序列而言,該畫面應被顯示N×rep_cntrl時間,其中N定義如上。
對GB/T XXXX.2隔行序列而言,該畫面應被顯示N×rep_cntrl時間。若該畫面是一個幀畫面,則待顯示的第一個字段在top_field_first爲1時應該是頂字段,在top_field_first爲0時,應該是底字段(參見GB/T XXXX.2)。該字段被顯示N×rep_cntrl / 2時間。該畫面的其它字段被顯示N-N×rep_cntrl / 2時間。
凍結幀 freeze frame
trick_mode_control字段中的值'010'。當該值出現時,它表示凍結幀視頻流,並定義了PES分組標題中後續5位的含義。表2-21中定義的field_id字段,表示應該顯示哪一個(些)字段。field_id字段指出了包含該字段的PES分組中開始的第一個視頻存取單元,除非該PES分組包含0個有效負載字節。在後一種狀況下,field_id字段指出了最近的前一個視頻存取單元。
快倒 fast reverse
trick_mode_control字段中的值'011'。當該值出現時,它表示一個快倒視頻流並定義了PES分組標題中後續5位的含義。intra_slice_refresh位能夠被設定爲'1'以指出可能有丟失的宏塊。解碼器能夠用前一個解碼畫面中相同位置的宏塊來代替。表2-21中定義的field_id字段,表示應該顯示哪一個或哪些字段。frequency_truncation字段指出了可能包括的一個係數受限集合。該字段值的含義如表2-22「係數選擇值」所示。
慢倒 slow reverse
trick_mode_control字段中的值'100'。當該值出現時,它表示一個慢倒視頻流並定義了PES分組標題中後續5位的含義。對GB/T AAAA.2視頻和GB/T XXXX.2視頻漸進序列而言,該畫面應被顯示N×rep_cntrl時間,其中N定義如上。
對GB/T XXXX.2隔行序列而言,該畫面應被顯示N×rep_cntrl時間。若該畫面是一個幀畫面,則待顯示的第一個字段在top_field_first爲1時應該是底字段,在top_field_first爲'0'時,應該是頂字段(參見GB/T XXXX.2)。該字段被顯示N×rep_cntrl/2時間。該畫面的其它字段被顯示N-N×rep_cntrl / 2時間。
字段標識字段 field_id
2位字段,表示應該顯示哪一個(些)字段。根據表2-21對其進行編碼。
表2-21 field_id字段控制值
值 |
描 述 |
'00' |
僅自頂向下播放 |
'01' |
僅自底向上播放 |
'10' |
播放全部幀 |
'11' |
保留 |
片內參考字段 intra_slice_refresh
1位標誌。置'1'時表示PES分組的視頻數據編碼片中可能有丟失的宏塊;置'0'時,表示上述狀況可能不出現。更多的信息可參見GB/T XXXX.2。解碼器能夠用前一個解碼畫面中同一個位置的宏塊來代替丟失的宏塊。
頻率截斷字段 frequency_truncation
2位字段。指出在對PES分組中數據進行編碼時可能用到受限係數集合。其值定義於表2-22。
表2-22 係數選擇值
值 |
描述 |
'00' |
僅DC係數非0 |
'01' |
僅前三個係數非0 |
'10' |
僅前六個係數非0 |
'11' |
全部係數都可能非0 |
顯示次數控制字段 rep_cntrl
5位字段,指出隔行畫面中每一字段的顯示次數或漸進畫面顯示次數。對隔行畫面而言,頂字段或底字段是否應首先顯示是視頻序列標題中trick_mode_control字段和top_field_first字段的功能。該字段值不能爲'0'。
附加版權信息字段 additional_copy_info
7位字段,包含與版權信息有關的專用數據。
前PES分組CRC字段 previous_PES_packet_CRC
16位字段。在對前一個PES分組(不包括該PES分組的標題)進行處理後,該字段包含一個在解碼器的16個寄存器中生成0輸出的CRC值。該CRC值與附錄A中所定義的相相似,但具備如下多項式:
x16+x12+x5+1
注2: 該CRC值是爲了用於網絡維護,例如將有間隙性錯誤的源隔離開來,而不是爲了供基本流解碼器使用。它僅用於計算數據字節,由於在傳輸過程當中PES分組標題數據可能被修改。
PES專用數據標誌字段 PES_private_data_flag
1位標誌。置'1'時表示PES分組標題中包含專用數據;置'0'時表示PES分組標題中無專用數據。
包標題字段標誌字段 pack_header_field_flag
1位標誌。置'1'時表示PES分組標題中有GB/T AAAA.2包標題或節目流包標題。若該字段在包含於節目流中的PES分組中,其值應爲'0'。在傳輸流中,當值爲'0'時表示PES標題中無包標題。
節目分組序列計數標誌字段 program_packet_sequence_counter_flag
1位標誌。值爲'1'時表示PES分組有program_packet_sequence_counter,MPEG1_MPEG2_identifier和original_stuff_length字段。值爲'0'時表示PES分組標題中無這些字段。
P-STD緩衝區標誌字段 P-STD_buffer_flag
1位標誌。置'1'時表示PES分組標題中有P-STD_buffer_scale和P-STD_buffer_size字段。值爲'0'時表示PES標題中無這些字段。
PES擴展標誌字段 PES_extension_flag_2
1位標誌,置'1'時表示有PES_extension_field_length及相關字段。
PES專用數據字段 PES_private_data
16位字段。包含專用數據。這些數據與其先後的字段組合在一塊兒時,不能與packet_start_code_prefix (0x000001)衝突。
包字段長度字段 pack_field_length
8位字段。表示pack_header_field()以字節爲單位時的長度。
節目分組序列計數字段 program_packet_sequence_counter
7位字段。它是一個可選的計數器,隨着來自於節目流或GB/T AAAA.1流的每個後續的PES分組或傳輸流中具備單個節目定義的PES分組而遞增,以提供與連續性計數器(參見2.4.3.2)類似的功能。它能用於檢索節目流或原始GB/T AAAA.1流中的初始PES分組序列。該計數器在達到最大值後回捲爲0。PES分組不能出現重複。所以,複合節目中任何兩個連續的PES分組不該具備相同的program_packet_sequence_counter值。
MPEG1 MPEG2標識符字段 MPEG1_MPEG2_identifier
1位標誌。置'1'時表示PES分組攜帶的信息來自於GB/T AAAA.1流;置'0'時表示PES分組攜帶的信息來自於節目流。
初始填充長度字段 original_stuff_length
6位字段。指定用於初始GB/T XXXX.1分組標題或初始GB/T AAAA.1分組標題中的填充字節數。
P-STD緩衝區比例字段 P-STD_ buffer_scale
1位字段。僅當該PES分組包含於節目流中時纔有意義。它指出了用來解釋後續P-STD_buffer_size字段的比例因子。若前面的stream_id表示一個音頻流,該字段值應爲'0';若前面的stream_id表示一個視頻流,該字段值應爲'1'。對於全部的其它流類型,其值能夠爲'0'或'1'。
P-STD緩衝區大小字段 P-STD_buffer_size
13位無符號整數。僅當該PES分組包含於節目流中時纔有意義。它定義了P-STD輸入緩衝區的大小BSn。若P-STD_ buffer_scale的值爲'0',那麼P-STD_buffer_size以128字節爲單位來度量緩衝區的大小。若P-STD_buffer_scale的值爲'1',那麼P-STD_buffer_size以1024字節爲單位來度量緩衝區的大小。所以:
if ( P-STD_buffer_scale == 0)
BSn=P-STD_buffer_size×128 (2-16)
else
BSn=P-STD_buffer_size×1024 (2-17)
當該字段被GB/T XXXX.1系統目標解碼器收到後,其編碼值當即生效。
PES擴展字段長度字段 PES_extension_field_length
7位字段。指出了跟在該字段以後在PES擴展字段中直到且包括任何保留字節的數據的字節長度。
填充字節字段 stuffing_byte
8位字段,其值恆定爲'1111 1111'。能夠由編碼器插入以知足通道的需求等。解碼器丟棄該字段。一個PES分組標題中只能出現32個填充字節。
PES分組數據字節字段 PES_packet_data_byte
該字段應該是來自於由分組的stream_id或PID所指定的基本流的連續數據字節。當基本流數據符合GB/T XXXX.2或GB/T XXXX.3時,該字段應該是與本標準的字節相對齊的字節。基本流的字節序應獲得保持。該字段的字節數N由PES_packet_length字段規定。N應等於PES_packet_length減去在PES_packet_length字段的最後一個字節與第一個 PES_packet_data_byte間的字節數。
填料字節字段 padding_byte
8位字段,其值恆定爲'1111 1111'。該字段被解碼器丟棄。