|
|
packet#7:
|
|
|
Adaptation fields
|
|
|
Adaptation_field_length: 7
|
|
|
discontinuity_indicator: False
|
|
|
random_access_indicator: True
|
|
|
ES_priority_indicator: False
|
|
|
PCR_flag: True
|
|
|
OPCR_flag: False
|
|
|
splicing_point_flag: False
|
|
|
transport_private_data_flag: False
|
|
|
adaptation_field_extension_flag: False
|
|
|
PCR: 50572350000
|
|
|
PES header
|
|
|
stream_id: E0 (video stream 224)
|
|
|
PES_packet_length: 35808
|
|
|
PES_scrambling: 0
|
|
|
PES_priority: False
|
|
|
data_alignment: False
|
|
|
copyright: False
|
|
|
original_or_copy: False
|
|
|
PTS_flag: True
|
|
|
DTS_flag: True
|
|
|
ESCR_flag: False
|
|
|
ES_rate_flag: False
|
|
|
DSM_trick_mode_flag: False
|
|
|
additional_copy_info_flag: False
|
|
|
PES_CRC_flag: False
|
|
|
PES_extension_flag: False
|
|
|
PES_header_data_length: 10
|
|
|
PTS: 168704280
|
|
|
DTS: 168700500
|
|
|
|
|
|
|
|
|
|
|
|
packet#665:
|
|
|
Adaptation fields
|
|
|
Adaptation_field_length: 7
|
|
|
discontinuity_indicator: False
|
|
|
random_access_indicator: True
|
|
|
ES_priority_indicator: False
|
|
|
PCR_flag: True
|
|
|
OPCR_flag: False
|
|
|
splicing_point_flag: False
|
|
|
transport_private_data_flag: False
|
|
|
adaptation_field_extension_flag: False
|
|
|
PCR: 50616225000
|
|
|
PES header
|
|
|
stream_id: E0 (video stream 224)
|
|
|
PES_packet_length: 29213
|
|
|
PES_scrambling: 0
|
|
|
PES_priority: False
|
|
|
data_alignment: False
|
|
|
copyright: False
|
|
|
original_or_copy: False
|
|
|
PTS_flag: True
|
|
|
DTS_flag: True
|
|
|
ESCR_flag: False
|
|
|
ES_rate_flag: False
|
|
|
DSM_trick_mode_flag: False
|
|
|
additional_copy_info_flag: False
|
|
|
PES_CRC_flag: False
|
|
|
PES_extension_flag: False
|
|
|
PES_header_data_length: 10
|
|
|
PTS: 168850530
|
|
|
DTS: 168846750
|
|
|
|
|
|
参考nginx-rtmp函数:ngx_rtmp_mpegts_write_frame
|
|
|
其中,nginx-rtmp写入PCR的逻辑如下:
|
|
|
if (f->key) {
|
|
|
packet[3] |= 0x20; /* adaptation */
|
|
|
|
|
|
*p++ = 7; /* size */
|
|
|
*p++ = 0x50; /* random access + PCR */
|
|
|
|
|
|
p = ngx_rtmp_mpegts_write_pcr(p, f->dts - NGX_RTMP_HLS_DELAY);
|
|
|
}
|
|
|
只要碰到关键帧,就写入PCR。
|
|
|
ngx_rtmp_mpegts_write_pcr(u_char *p, uint64_t pcr)
|
|
|
{
|
|
|
*p++ = (u_char) (pcr >> 25);
|
|
|
*p++ = (u_char) (pcr >> 17);
|
|
|
*p++ = (u_char) (pcr >> 9);
|
|
|
*p++ = (u_char) (pcr >> 1);
|
|
|
*p++ = (u_char) (pcr << 7 | 0x7e);
|
|
|
*p++ = 0;
|
|
|
|
|
|
return p;
|
|
|
}
|
|
|
即将高9位置0,6个reserverd置1,低33位输出(little-endian)。
|
|
|
|
|
|
nginx-rtmp写入dts的逻辑如下:
|
|
|
p = ngx_rtmp_mpegts_write_pts(p, 1, f->dts + NGX_RTMP_HLS_DELAY);
|
|
|
也就是说,
|
|
|
pcr = f->dts - NGX_RTMP_HLS_DELAY
|
|
|
f->dts = dts - NGX_RTMP_HLS_DELAY
|
|
|
计算出来的:
|
|
|
pcr = program_clock_reference_base = 168574500
|
|
|
dts = 168700500
|
|
|
168574500 = 168700500 - 63000 - 63000
|
|
|
可见,工具MPEG-2 TS packet analyser分析出来的pcr是不对的。
|
|
|
|
|
|
解码出来的结果:
|
|
|
demuxer+read packet 0006 0001128 0x47 0x41 0x00 0x35 ... 0xb6 0x9f 0x89
|
|
|
ts+af af flags parsed, discontinuity: 0 random: 1 priority: 0 PCR: 1 OPCR: 0 slicing: 0 private: 0 extension: 0 pcr: 168574500 opcr: 0
|
|
|
ts+pes stream_id: 224 size: 35808 pts: 168704280 dts: 168700500 total: 35808 header: 13 packet_size: 35795 parsed_size: 157
|