Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2013-11-23 11:25:58 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
37e53f373500896c61b7cb288e9e5152ec29569e
37e53f37
1 parent
71015dc4
add ts PCR analysis, the tool MPEG-2-ts-packet-analysis.2.4.5.0 decode PCR wrong
隐藏空白字符变更
内嵌
并排对比
正在显示
2 个修改的文件
包含
158 行增加
和
36 行删除
trunk/doc/ts-PCR-analysis.txt
trunk/research/ts_info.cpp
trunk/doc/ts-PCR-analysis.txt
0 → 100644
查看文件 @
37e53f3
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
...
...
trunk/research/ts_info.cpp
查看文件 @
37e53f3
...
...
@@ -228,6 +228,9 @@ public:
// user defined total adaption field size.
int
__field_size
;
// logic pcr/original_pcr
int64_t
pcr
;
int64_t
original_pcr
;
TSAdaptionField
();
virtual
~
TSAdaptionField
();
...
...
@@ -764,6 +767,8 @@ TSAdaptionField::TSAdaptionField()
af_ext_reserved
=
NULL
;
af_reserved
=
NULL
;
__field_size
=
0
;
pcr
=
0
;
original_pcr
=
0
;
}
TSAdaptionField
::~
TSAdaptionField
()
...
...
@@ -802,10 +807,6 @@ int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int
transport_private_data_flag
=
(
value
>>
1
)
&
0x01
;
adaptation_field_extension_flag
=
(
value
>>
0
)
&
0x01
;
trace
(
"ts+af af flags parsed, discontinuity: %d random: %d priority: %d PCR: %d OPCR: %d slicing: %d private: %d extension: %d"
,
discontinuity_indicator
,
random_access_indicator
,
elementary_stream_priority_indicator
,
PCR_flag
,
OPCR_flag
,
splicing_point_flag
,
transport_private_data_flag
,
adaptation_field_extension_flag
);
char
*
pp
=
NULL
;
if
(
PCR_flag
)
{
pp
=
(
char
*
)
&
program_clock_reference_base
;
...
...
@@ -816,8 +817,14 @@ int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
program_clock_reference_extension
=
program_clock_reference_base
&
0x1F
;
program_clock_reference_base
=
(
program_clock_reference_base
>>
9
)
&
0x1FFFFFFFF
;
program_clock_reference_extension
=
program_clock_reference_base
&
0x1ff
;
program_clock_reference_base
=
(
program_clock_reference_base
>>
15
)
&
0x1ffffffff
;
// high 9bits
pcr
=
program_clock_reference_extension
;
pcr
=
(
pcr
<<
33
)
&
0x3fe00000000
;
// low 33bits
pcr
|=
program_clock_reference_base
;
}
if
(
OPCR_flag
)
{
pp
=
(
char
*
)
&
original_program_clock_reference_base
;
...
...
@@ -828,8 +835,14 @@ int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int
pp
[
1
]
=
*
p
++
;
pp
[
0
]
=
*
p
++
;
original_program_clock_reference_extension
=
original_program_clock_reference_base
&
0x1F
;
original_program_clock_reference_base
=
(
original_program_clock_reference_base
>>
9
)
&
0x1FFFFFFFF
;
original_program_clock_reference_extension
=
original_program_clock_reference_base
&
0x1ff
;
original_program_clock_reference_base
=
(
original_program_clock_reference_base
>>
15
)
&
0x1ffffffff
;
// high 9bits
original_pcr
=
program_clock_reference_extension
;
original_pcr
=
(
original_pcr
<<
33
)
&
0x3fe00000000
;
// low 33bits
original_pcr
|=
program_clock_reference_base
;
}
if
(
splicing_point_flag
)
{
splice_countdown
=
*
p
++
;
...
...
@@ -909,6 +922,10 @@ int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int
p
+=
af_size
;
}
trace
(
"ts+af af flags parsed, discontinuity: %d random: %d priority: %d PCR: %d OPCR: %d slicing: %d private: %d extension: %d pcr: %"
PRId64
" opcr: %"
PRId64
""
,
discontinuity_indicator
,
random_access_indicator
,
elementary_stream_priority_indicator
,
PCR_flag
,
OPCR_flag
,
splicing_point_flag
,
transport_private_data_flag
,
adaptation_field_extension_flag
,
pcr
,
original_pcr
);
return
ret
;
}
...
...
@@ -1550,6 +1567,34 @@ int TSPayload::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* l
return
pmt
->
demux
(
ctx
,
pkt
,
start
,
last
,
p
,
pmsg
);
}
if
(
pid
&&
(
pid
->
type
==
TSPidTypeVideo
||
pid
->
type
==
TSPidTypeAudio
))
{
TSMessage
*
msg
=
ctx
->
get_msg
(
pkt
->
header
->
pid
);
// flush previous PES_packet_length(0) packets.
if
(
msg
->
packet_start_code_prefix
==
0x01
&&
pkt
->
header
->
payload_unit_start_indicator
==
1
&&
msg
->
PES_packet_length
==
0
)
{
msg
->
detach
(
ctx
,
pmsg
);
// reparse current message
p
=
start
;
return
ret
;
}
// parse continous packet.
if
(
!
pkt
->
header
->
payload_unit_start_indicator
)
{
if
(
msg
->
packet_start_code_prefix
!=
0x01
)
{
trace
(
"ts+pes decode continous packet error, msg is empty."
);
return
-
1
;
}
msg
->
append
(
p
,
last
-
p
);
// for PES_packet_length is 0, donot attach it.
if
(
msg
->
PES_packet_length
>
0
)
{
msg
->
detach
(
ctx
,
pmsg
);
}
return
ret
;
}
type
=
pid
->
type
;
pes
=
new
TSPayloadPES
();
return
pes
->
demux
(
ctx
,
pkt
,
start
,
last
,
p
,
pmsg
);
...
...
@@ -1599,34 +1644,6 @@ int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*&
payload
->
size
=
TS_PACKET_SIZE
-
header
->
get_size
()
-
adaption_field
->
get_size
();
if
(
header
->
adaption_field_control
==
TSAdaptionTypePayloadOnly
||
header
->
adaption_field_control
==
TSAdaptionTypeBoth
)
{
TSMessage
*
msg
=
ctx
->
get_msg
(
header
->
pid
);
// flush previous PES_packet_length(0) packets.
if
(
msg
->
packet_start_code_prefix
==
0x01
&&
header
->
payload_unit_start_indicator
==
1
&&
msg
->
PES_packet_length
==
0
)
{
msg
->
detach
(
ctx
,
pmsg
);
// reparse current message
p
=
start
;
return
ret
;
}
// parse continous packet.
if
(
!
header
->
payload_unit_start_indicator
)
{
if
(
msg
->
packet_start_code_prefix
!=
0x01
)
{
trace
(
"ts+pes decode continous packet error, msg is empty."
);
return
-
1
;
}
msg
->
append
(
p
,
last
-
p
);
// for PES_packet_length is 0, donot attach it.
if
(
msg
->
PES_packet_length
>
0
)
{
msg
->
detach
(
ctx
,
pmsg
);
}
return
ret
;
}
// parse new packet.
if
((
ret
=
payload
->
demux
(
ctx
,
this
,
start
,
last
,
p
,
pmsg
))
!=
0
)
{
trace
(
"ts+header payload decode error. ret=%d"
,
ret
);
...
...
请
注册
或
登录
后发表评论