Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
51435d95
Commit
51435d95
authored
Jan 31, 2021
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化rtp统计性能
parent
070bf19c
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
76 行增加
和
50 行删除
+76
-50
src/Rtcp/RtcpContext.cpp
+67
-45
src/Rtcp/RtcpContext.h
+4
-1
src/Rtsp/RtspPlayer.cpp
+1
-1
src/Rtsp/RtspPusher.cpp
+1
-1
src/Rtsp/RtspSession.cpp
+3
-2
没有找到文件。
src/Rtcp/RtcpContext.cpp
查看文件 @
51435d95
...
...
@@ -9,65 +9,75 @@
*/
#include "RtcpContext.h"
#include "Util/logger.h"
using
namespace
toolkit
;
namespace
mediakit
{
void
RtcpContext
::
clear
(){
void
RtcpContext
::
clear
()
{
memset
(
this
,
0
,
sizeof
(
RtcpContext
));
}
RtcpContext
::
RtcpContext
(
uint32_t
sample_rate
)
{
RtcpContext
::
RtcpContext
(
uint32_t
sample_rate
,
bool
is_receiver
)
{
_sample_rate
=
sample_rate
;
_is_receiver
=
is_receiver
;
}
void
RtcpContext
::
onRtp
(
uint16_t
seq
,
uint32_t
stamp
,
size_t
bytes
)
{
_bytes
+=
bytes
;
++
_packets
;
if
(
_is_receiver
)
{
//接收者才做复杂的统计运算
auto
sys_stamp
=
getCurrentMillisecond
();
if
(
_last_rtp_sys_stamp
)
{
//计算时间戳抖动值
double
diff
=
double
(
int64_t
(
sys_stamp
)
-
int64_t
(
_last_rtp_sys_stamp
)
-
int64_t
(
stamp
)
+
int64_t
(
_last_rtp_stamp
));
if
(
diff
<
0
)
{
diff
=
-
diff
;
}
//抖动单位为采样次数
diff
*=
(
_sample_rate
/
1000.0
);
_jitter
+=
(
diff
-
_jitter
)
/
16.0
;
}
else
{
_jitter
=
0
;
}
auto
sys_stamp
=
getCurrentMillisecond
();
if
(
_last_rtp_sys_stamp
)
{
//计算时间戳抖动值
double
diff
=
double
(
int64_t
(
sys_stamp
)
-
int64_t
(
_last_rtp_sys_stamp
)
-
int64_t
(
stamp
)
+
int64_t
(
_last_rtp_stamp
));
if
(
diff
<
0
)
{
diff
=
-
diff
;
if
(
_last_rtp_seq
>
0xFF00
&&
seq
<
0xFF
&&
(
!
_seq_cycles
||
_packets
-
_last_cycle_packets
>
0x1FFF
))
{
//上次seq大于0xFF00且本次seq小于0xFF,
//且未发生回环或者距离上次回环间隔超过0x1FFF个包,则认为回环
++
_seq_cycles
;
_last_cycle_packets
=
_packets
;
_seq_max
=
seq
;
}
else
if
(
seq
>
_seq_max
)
{
//本次回环前最大seq
_seq_max
=
seq
;
}
//抖动单位为采样次数
diff
*=
(
_sample_rate
/
1000.0
);
_jitter
+=
(
diff
-
_jitter
)
/
16.0
;
}
else
{
_jitter
=
0
;
}
if
(
_last_rtp_seq
>
0xFF00
&&
seq
<
0xFF
&&
(
!
_seq_cycles
||
_packets
-
_last_cycle_packets
>
0x1FFF
))
{
//上次seq大于0xFF00且本次seq小于0xFF,
//且未发生回环或者距离上次回环间隔超过0x1FFF个包,则认为回环
++
_seq_cycles
;
_last_cycle_packets
=
_packets
;
_seq_max
=
seq
;
}
else
if
(
seq
>
_seq_max
)
{
//本次回环前最大seq
_seq_max
=
seq
;
}
if
(
!
_seq_base
)
{
//记录第一个rtp的seq
_seq_base
=
seq
;
}
else
if
(
!
_seq_cycles
&&
seq
<
_seq_base
)
{
//未发生回环,那么取最新的seq为基准seq
_seq_base
=
seq
;
}
if
(
!
_seq_base
)
{
//记录第一个rtp的seq
_seq_base
=
seq
;
}
else
if
(
!
_seq_cycles
&&
seq
<
_seq_base
)
{
//未发生回环,那么取最新的seq为基准seq
_seq_base
=
seq
;
_last_rtp_seq
=
seq
;
_last_rtp_sys_stamp
=
sys_stamp
;
}
++
_packets
;
_bytes
+=
bytes
;
_last_rtp_stamp
=
stamp
;
_last_rtp_sys_stamp
=
sys_stamp
;
_last_rtp_seq
=
seq
;
}
void
RtcpContext
::
onRtcp
(
RtcpHeader
*
rtcp
){
void
RtcpContext
::
onRtcp
(
RtcpHeader
*
rtcp
)
{
if
((
RtcpType
)
rtcp
->
pt
!=
RtcpType
::
RTCP_SR
)
{
return
;
}
auto
rtcp_sr
=
(
RtcpSR
*
)(
rtcp
);
if
(
!
_is_receiver
)
{
WarnL
<<
"rtp发送者收到sr包"
;
return
;
}
auto
rtcp_sr
=
(
RtcpSR
*
)
(
rtcp
);
/**
last SR timestamp (LSR): 32 bits
The middle 32 bits out of 64 in the NTP timestamp (as explained in
...
...
@@ -79,29 +89,38 @@ void RtcpContext::onRtcp(RtcpHeader *rtcp){
_last_sr_ntp_sys
=
getCurrentMillisecond
();
}
size_t
RtcpContext
::
getExpectedPackets
()
const
{
size_t
RtcpContext
::
getExpectedPackets
()
const
{
if
(
!
_is_receiver
)
{
throw
std
::
runtime_error
(
"rtp发送者无法统计应收包数"
);
}
return
(
_seq_cycles
<<
16
)
+
_seq_max
-
_seq_base
+
1
;
}
size_t
RtcpContext
::
getExpectedPacketsInterval
(){
size_t
RtcpContext
::
getExpectedPacketsInterval
()
{
auto
expected
=
getExpectedPackets
();
auto
ret
=
expected
-
_last_expected
;
_last_expected
=
expected
;
return
ret
;
}
size_t
RtcpContext
::
getLost
(){
size_t
RtcpContext
::
getLost
()
{
if
(
!
_is_receiver
)
{
throw
std
::
runtime_error
(
"rtp发送者无法统计丢包率"
);
}
return
getExpectedPackets
()
-
_packets
;
}
size_t
RtcpContext
::
geLostInterval
(){
size_t
RtcpContext
::
geLostInterval
()
{
auto
lost
=
getLost
();
auto
ret
=
lost
-
_last_lost
;
_last_lost
=
lost
;
return
ret
;
}
Buffer
::
Ptr
RtcpContext
::
createRtcpSR
(
uint32_t
rtcp_ssrc
){
Buffer
::
Ptr
RtcpContext
::
createRtcpSR
(
uint32_t
rtcp_ssrc
)
{
if
(
_is_receiver
)
{
throw
std
::
runtime_error
(
"rtp接收者尝试发送sr包"
);
}
auto
rtcp
=
RtcpSR
::
create
(
0
);
rtcp
->
ssrc
=
htonl
(
rtcp_ssrc
);
...
...
@@ -111,12 +130,15 @@ Buffer::Ptr RtcpContext::createRtcpSR(uint32_t rtcp_ssrc){
//转换成rtp时间戳
rtcp
->
rtpts
=
htonl
(
uint32_t
(
_last_rtp_stamp
*
(
_sample_rate
/
1000.0
)));
rtcp
->
packet_count
=
htonl
((
uint32_t
)
_packets
);
rtcp
->
octet_count
=
htonl
((
uint32_t
)
_bytes
);
rtcp
->
packet_count
=
htonl
((
uint32_t
)
_packets
);
rtcp
->
octet_count
=
htonl
((
uint32_t
)
_bytes
);
return
RtcpHeader
::
toBuffer
(
std
::
move
(
rtcp
));
}
Buffer
::
Ptr
RtcpContext
::
createRtcpRR
(
uint32_t
rtcp_ssrc
,
uint32_t
rtp_ssrc
){
Buffer
::
Ptr
RtcpContext
::
createRtcpRR
(
uint32_t
rtcp_ssrc
,
uint32_t
rtp_ssrc
)
{
if
(
!
_is_receiver
)
{
throw
std
::
runtime_error
(
"rtp发送者尝试发送rr包"
);
}
auto
rtcp
=
RtcpRR
::
create
(
1
);
rtcp
->
ssrc
=
htonl
(
rtcp_ssrc
);
...
...
@@ -139,7 +161,7 @@ Buffer::Ptr RtcpContext::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc){
// now - Last SR time,单位毫秒
auto
delay
=
getCurrentMillisecond
()
-
_last_sr_ntp_sys
;
// in units of 1/65536 seconds
auto
dlsr
=
(
uint32_t
)(
delay
/
1000.0
f
*
65536
);
auto
dlsr
=
(
uint32_t
)
(
delay
/
1000.0
f
*
65536
);
item
->
delay_since_last_sr
=
htonl
(
_last_sr_lsr
?
dlsr
:
0
);
return
RtcpHeader
::
toBuffer
(
rtcp
);
}
...
...
src/Rtcp/RtcpContext.h
查看文件 @
51435d95
...
...
@@ -23,8 +23,9 @@ public:
/**
* 创建rtcp上下文
* @param sample_rate 音频采用率,视频一般为90000
* @param is_receiver 是否为rtp接收者,接收者更消耗性能
*/
RtcpContext
(
uint32_t
sample_rate
);
RtcpContext
(
uint32_t
sample_rate
,
bool
is_receiver
);
/**
* 输出或输入rtp时调用
...
...
@@ -82,6 +83,8 @@ private:
size_t
geLostInterval
();
private
:
//是否为接收者
bool
_is_receiver
;
//时间戳抖动值
double
_jitter
=
0
;
//视频默认90000,音频为采样率
...
...
src/Rtsp/RtspPlayer.cpp
查看文件 @
51435d95
...
...
@@ -204,7 +204,7 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) {
throw
std
::
runtime_error
(
"onCheckSDP faied"
);
}
for
(
auto
&
track
:
_sdp_track
)
{
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
track
->
_samplerate
));
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
track
->
_samplerate
,
true
));
}
sendSetup
(
0
);
}
...
...
src/Rtsp/RtspPusher.cpp
查看文件 @
51435d95
...
...
@@ -177,7 +177,7 @@ void RtspPusher::sendAnnounce() {
throw
std
::
runtime_error
(
"无有效的Sdp Track"
);
}
for
(
auto
&
track
:
_track_vec
)
{
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
track
->
_samplerate
));
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
track
->
_samplerate
,
false
));
}
_on_res_func
=
std
::
bind
(
&
RtspPusher
::
handleResAnnounce
,
this
,
placeholders
::
_1
);
sendRtspRequest
(
"ANNOUNCE"
,
_url
,
{},
src
->
getSdp
());
...
...
src/Rtsp/RtspSession.cpp
查看文件 @
51435d95
...
...
@@ -235,8 +235,9 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) {
sendRtspResponse
(
"403 Forbidden"
,
{
"Content-Type"
,
"text/plain"
},
err
);
throw
SockException
(
Err_shutdown
,
StrPrinter
<<
err
<<
":"
<<
full_url
);
}
_rtcp_context
.
clear
();
for
(
auto
&
track
:
_sdp_track
)
{
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
track
->
_samplerate
));
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
track
->
_samplerate
,
true
));
}
_push_src
=
std
::
make_shared
<
RtspMediaSourceImp
>
(
_media_info
.
_vhost
,
_media_info
.
_app
,
_media_info
.
_streamid
);
_push_src
->
setListener
(
dynamic_pointer_cast
<
MediaSourceEvent
>
(
shared_from_this
()));
...
...
@@ -406,7 +407,7 @@ void RtspSession::onAuthSuccess() {
return
;
}
for
(
auto
&
track
:
strongSelf
->
_sdp_track
)
{
strongSelf
->
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
track
->
_samplerate
));
strongSelf
->
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
track
->
_samplerate
,
false
));
}
strongSelf
->
_sessionid
=
makeRandStr
(
12
);
strongSelf
->
_play_src
=
rtsp_src
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论