ts-PCR-analysis.txt 2.9 KB
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