本章开始尝试更加有难度的操作,把H264打包成ps流。PS流分为4大部分:PS头/系统头/节目流/PES包。这四大部分每个都有大量需要填写的字段,一时弄不清楚如何填写。为了解决这一问题,我找了一段公安一所的测试PS流进行逐步分析,希望能弄清楚每个字段如何填写。
第一个:PS头定义如下:
上码流一共14个字节:
转换成2进行如下:
0000 0000 0000 0000 0000 0001 1011 1010 0100 0100
0000 1010 1011 0100 1111 1100 0000 0100 0000 0001
0000 0000 0011 1010 1001 1011 1111 1000
pack_start_code =0000 0000 0000 0000 0000 0001 1011 1010
‘01’=01
system_clock_reference_base [32..30] =000
marker_bit=1
system_clock_reference_base [29..15] =00 0000 1010 1011 0
marker_bit=1
system_clock_reference_base [14..0] =00 1111 1100 0000 0
marker_bit=1
system_clock_reference_extension = 00 0000 000
marker_bit=1
program_mux_rate=0000 0000 0011 1010 1001 10
marker_bit=1
marker_bit=1
reserved=1111 1
pack_stuffing_length =000
总结:
system_clock_reference_base 和和system_clock_reference_extension和 program_mux_rate需要填值,其他的都能理解。
system_clock_reference_base:
系统时钟参考(SCR)为分成两部分编码的42比特字段第一部分,system_clock_reference_base为33比特字段,其值由公式2-19中给出的SCR_base (i)给出。
所以需要研究公式2-19(67页)
这里我们直接默认取系统system_clock_frequency = 27 000 000
t(i)为当前系统的秒数,单位为秒。
system_clock_reference_extension:为9比特字段,其值由公式2-20中给出的SCR_ext (i)给出。
program_mux_rate:此为22比特整数,指示包期间P-STD接收节目流的速率/其中该节目流包含在包中
看了一圈,还是没搞明白这个值如何填写,先暂时跨过。
第二个:系统头定义如下:
上码流:一共18个字节
转换成2进行如下:
0000 0000 0000 0000 0000 0001 1011 1011 0000 0000 0000 1100
1000 0000 0001 1110 1111 1111 1111 1110 1110 0001 0111 1111
1110 0000 1110 0000 1110 1000 1100 0000 1100 0000 0010 0000
system_header_start_code =0000 0000 0000 0000 0000 0001 1011 1011
header_length = 0000 0000 0000 1100
marker_bit =1
rate_bound = 000 0000 0001 1110 1111 111
marker_bit =1
audio_bound = 1111 11
fixed_flag = 1
CSPS_flag = 0
system_audio_lock_flag = 1
system_video_lock_flag = 1
marker_bit =1
video_bound = 0 0001
packet_rate_restriction_flag = 0
reserved_bits = 111 1111
stream_id = 1110 0000
'11'
P-STD_buffer_bound_scale = 1
P-STD_buffer_size_bound = 0 0000 1110 1000
stream_id = 1100 0000
'11'
P-STD_buffer_bound_scale = 0
P-STD_buffer_size_bound = 0 0000 0010 0000
rate_bound :没搞明白这个值如何填写,先暂时跨过。
第三个:节目流定义如下:
上码流一共30个字节
转换成2进制:
0000 0000 0000 0000 0000 0001 1011 1100 0000 0000 0001 1000
1110 0001 1111 1111 0000 0000 0000 0000 0000 0000 0000 1000
0001 1011 1110 0000 0000 0000 0000 0110 0000 1010 0000 0100
0110 0101 0110 1110 0110 0111 0000 0000 1001 0000 1100 0000
0000 0000 0000 0000 0010 1110 1011 1001 0000 1111 0011 1101
packet_start_code_prefix = 0000 0000 0000 0000 0000 0001
map_stream_id =1011 1100
program_stream_map_length = 0000 0000 0001 1000
current_next_indicator =1
reserved = 11
program_stream_map_version =0 0001
reserved = 1111 111
marker_bit =1
program_stream_info_length = 0000 0000 0000 0000
elementary_stream_map_length = 0000 0000 0000 1000
stream_type =0001 1011
elementary_stream_id=1110 0000
elementary_stream_info_length = 0000 0000 0000 0110
stream_type =1001 0000
elementary_stream_id=1100 0000
elementary_stream_info_length = 0000 0000 0000 0000
CRC_32 =0010 1110 1011 1001 0000 1111 0011 1101
第四个:Pes定义如下:
上码流:
2进制:
0000 0000 0000 0000 0000 0001 1100 0000 0000 0000 0101 1101
1000 0100 1100 0000 0000 1010 0011 0001 0000 0010 1010 1101
0011 0000 1111 0001 0001 0001 0000 0010 1010 1101 0001 0100
1101 0001
packet_start_code_prefix =0000 0000 0000 0000 0000 0001
stream_id = 1100 0000
PES_packet_length = 0000 0000 0101 1101
PES_scrambling_control =00
PES_priority =0
data_alignment_indicator =1
copyright =0
original_or_copy =0
PTS_DTS_flags = 11
ESCR_flag =0
ES_rate_flag =0
DSM_trick_mode_flag =0
additional_copy_info_flag =0
PES_CRC_flag =0
PES_extension_flag =0
PES_header_data_length = 0000 1010
PTS = 000 0000 0010 1010 110 0011 0000 1111 000
DTS =000 0000 0010 1010 110 0001 0100 1101 000
pes包的重点是分析Pts和DTS如何填值,其他值默认都是0
根据我的理解,PTS等于下一个传输的I或P图像的解码时间DTS值,DTS就是system_clock_reference_base的值。目前这么理解吧,其实还是没高太明白。
大概的字段含义搞明白之后,下面开始着手把H264封装到PS流里面,不明白的字段,准备按照上述的字段默认填写值,暂时这么定。