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
9498b96b
Commit
9498b96b
authored
2 years ago
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
确保rtp推流线程安全性
parent
80eb6dc4
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
25 行增加
和
48 行删除
+25
-48
server/WebApi.cpp
+1
-1
src/Rtp/RtpProcess.cpp
+0
-12
src/Rtp/RtpProcess.h
+0
-1
src/Rtp/RtpSelector.cpp
+4
-19
src/Rtp/RtpSelector.h
+1
-13
tests/test_rtp.cpp
+19
-2
没有找到文件。
server/WebApi.cpp
查看文件 @
9498b96b
...
...
@@ -400,7 +400,7 @@ uint16_t openRtpServer(uint16_t local_port, const string &stream_id, int tcp_mod
//设置rtp超时移除事件
lock_guard
<
recursive_mutex
>
lck
(
s_rtpServerMapMtx
);
s_rtpServerMap
.
erase
(
stream_id
);
});
});
//保存对象
s_rtpServerMap
.
emplace
(
stream_id
,
server
);
...
...
This diff is collapsed.
Click to expand it.
src/Rtp/RtpProcess.cpp
查看文件 @
9498b96b
...
...
@@ -66,18 +66,6 @@ RtpProcess::~RtpProcess() {
}
bool
RtpProcess
::
inputRtp
(
bool
is_udp
,
const
Socket
::
Ptr
&
sock
,
const
char
*
data
,
size_t
len
,
const
struct
sockaddr
*
addr
,
uint64_t
*
dts_out
)
{
auto
is_busy
=
_busy_flag
.
test_and_set
();
if
(
is_busy
)
{
//其他线程正在执行本函数
WarnP
(
this
)
<<
"其他线程正在执行本函数"
;
return
false
;
}
//没有其他线程执行本函数
onceToken
token
(
nullptr
,
[
&
]()
{
//本函数执行完毕时,释放状态
_busy_flag
.
clear
();
});
if
(
!
_sock
)
{
//第一次运行本函数
_sock
=
sock
;
...
...
This diff is collapsed.
Click to expand it.
src/Rtp/RtpProcess.h
查看文件 @
9498b96b
...
...
@@ -94,7 +94,6 @@ private:
ProcessInterface
::
Ptr
_process
;
MultiMediaSourceMuxer
::
Ptr
_muxer
;
std
::
atomic_bool
_stop_rtp_check
{
false
};
std
::
atomic_flag
_busy_flag
{
false
};
toolkit
::
Ticker
_last_check_alive
;
std
::
recursive_mutex
_func_mtx
;
std
::
deque
<
std
::
function
<
void
()
>
>
_cached_func
;
...
...
This diff is collapsed.
Click to expand it.
src/Rtp/RtpSelector.cpp
查看文件 @
9498b96b
...
...
@@ -25,25 +25,6 @@ void RtpSelector::clear(){
_map_rtp_process
.
clear
();
}
bool
RtpSelector
::
inputRtp
(
const
Socket
::
Ptr
&
sock
,
const
char
*
data
,
size_t
data_len
,
const
struct
sockaddr
*
addr
,
uint64_t
*
dts_out
)
{
uint32_t
ssrc
=
0
;
if
(
!
getSSRC
(
data
,
data_len
,
ssrc
))
{
WarnL
<<
"get ssrc from rtp failed:"
<<
data_len
;
return
false
;
}
auto
process
=
getProcess
(
printSSRC
(
ssrc
),
true
);
if
(
process
)
{
try
{
return
process
->
inputRtp
(
true
,
sock
,
data
,
data_len
,
addr
,
dts_out
);
}
catch
(...)
{
delProcess
(
printSSRC
(
ssrc
),
process
.
get
());
throw
;
}
}
return
false
;
}
bool
RtpSelector
::
getSSRC
(
const
char
*
data
,
size_t
data_len
,
uint32_t
&
ssrc
){
if
(
data_len
<
12
)
{
return
false
;
...
...
@@ -59,6 +40,10 @@ RtpProcess::Ptr RtpSelector::getProcess(const string &stream_id,bool makeNew) {
if
(
it
==
_map_rtp_process
.
end
()
&&
!
makeNew
)
{
return
nullptr
;
}
if
(
it
!=
_map_rtp_process
.
end
()
&&
makeNew
)
{
//已经被其他线程持有了,不得再被持有,否则会存在线程安全的问题
throw
std
::
runtime_error
(
StrPrinter
<<
"RtpProcess("
<<
stream_id
<<
") already existed"
);
}
RtpProcessHelper
::
Ptr
&
ref
=
_map_rtp_process
[
stream_id
];
if
(
!
ref
)
{
ref
=
std
::
make_shared
<
RtpProcessHelper
>
(
stream_id
,
shared_from_this
());
...
...
This diff is collapsed.
Click to expand it.
src/Rtp/RtpSelector.h
查看文件 @
9498b96b
...
...
@@ -53,21 +53,9 @@ public:
void
clear
();
/**
* 输入多个rtp流,根据ssrc分流
* @param sock 本地socket
* @param data 收到的数据
* @param data_len 收到的数据长度
* @param addr rtp流源地址
* @param dts_out 解析出最新的dts
* @return 是否成功
*/
bool
inputRtp
(
const
toolkit
::
Socket
::
Ptr
&
sock
,
const
char
*
data
,
size_t
data_len
,
const
struct
sockaddr
*
addr
,
uint64_t
*
dts_out
=
nullptr
);
/**
* 获取一个rtp处理器
* @param stream_id 流id
* @param makeNew 不存在时是否新建
* @param makeNew 不存在时是否新建
, 该参数为true时,必须确保之前未创建同名对象
* @return rtp处理器
*/
RtpProcess
::
Ptr
getProcess
(
const
std
::
string
&
stream_id
,
bool
makeNew
);
...
...
This diff is collapsed.
Click to expand it.
tests/test_rtp.cpp
查看文件 @
9498b96b
...
...
@@ -42,6 +42,8 @@ static bool loadFile(const char *path){
addr
.
ss_family
=
AF_INET
;
auto
sock
=
Socket
::
createSocket
();
size_t
total_size
=
0
;
RtpProcess
::
Ptr
process
;
uint32_t
ssrc
=
0
;
while
(
true
)
{
if
(
2
!=
fread
(
&
len
,
1
,
2
,
fp
))
{
WarnL
;
...
...
@@ -58,9 +60,24 @@ static bool loadFile(const char *path){
break
;
}
total_size
+=
len
;
uint64_t
timeStamp
;
uint64_t
timeStamp
=
0
;
if
(
!
process
)
{
if
(
!
RtpSelector
::
getSSRC
(
rtp
,
len
,
ssrc
))
{
WarnL
<<
"get ssrc from rtp failed:"
<<
len
;
return
false
;
}
process
=
RtpSelector
::
Instance
().
getProcess
(
printSSRC
(
ssrc
),
true
);
}
if
(
process
)
{
try
{
process
->
inputRtp
(
true
,
sock
,
rtp
,
len
,
(
struct
sockaddr
*
)
&
addr
,
&
timeStamp
);
}
catch
(...)
{
RtpSelector
::
Instance
().
delProcess
(
printSSRC
(
ssrc
),
process
.
get
());
throw
;
}
}
RtpSelector
::
Instance
().
inputRtp
(
sock
,
rtp
,
len
,
(
struct
sockaddr
*
)
&
addr
,
&
timeStamp
);
auto
diff
=
timeStamp
-
timeStamp_last
;
if
(
diff
>
0
&&
diff
<
500
)
{
usleep
(
diff
*
1000
);
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论