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
101261c2
Commit
101261c2
authored
Nov 08, 2017
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
支持rtcp心跳包
parent
8242ad67
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
57 行增加
和
35 行删除
+57
-35
src/Rtsp/RtspSession.cpp
+50
-29
src/Rtsp/RtspSession.h
+3
-2
src/Rtsp/UDPServer.cpp
+3
-3
src/Rtsp/UDPServer.h
+1
-1
没有找到文件。
src/Rtsp/RtspSession.cpp
查看文件 @
101261c2
...
@@ -107,10 +107,10 @@ void RtspSession::shutdown(){
...
@@ -107,10 +107,10 @@ void RtspSession::shutdown(){
void
RtspSession
::
onError
(
const
SockException
&
err
)
{
void
RtspSession
::
onError
(
const
SockException
&
err
)
{
TraceL
<<
err
.
getErrCode
()
<<
" "
<<
err
.
what
();
TraceL
<<
err
.
getErrCode
()
<<
" "
<<
err
.
what
();
if
(
m_bListenPeerUdp
Port
)
{
if
(
m_bListenPeerUdp
Data
)
{
//取消UDP
断
口监听
//取消UDP
端
口监听
UDPServer
::
Instance
().
stopListenPeer
(
getPeerIp
().
data
(),
this
);
UDPServer
::
Instance
().
stopListenPeer
(
getPeerIp
().
data
(),
this
);
m_bListenPeerUdp
Port
=
false
;
m_bListenPeerUdp
Data
=
false
;
}
}
if
(
!
m_bBase64need
&&
m_strSessionCookie
.
size
()
!=
0
)
{
if
(
!
m_bBase64need
&&
m_strSessionCookie
.
size
()
!=
0
)
{
//quickTime http getter
//quickTime http getter
...
@@ -135,10 +135,6 @@ void RtspSession::onManager() {
...
@@ -135,10 +135,6 @@ void RtspSession::onManager() {
shutdown
();
shutdown
();
return
;
return
;
}
}
if
(
m_bListenPeerUdpPort
)
{
UDPServer
::
Instance
().
stopListenPeer
(
getPeerIp
().
data
(),
this
);
m_bListenPeerUdpPort
=
false
;
}
}
}
if
(
m_rtpType
!=
PlayerBase
::
RTP_TCP
&&
m_ticker
.
elapsedTime
()
>
15
*
1000
)
{
if
(
m_rtpType
!=
PlayerBase
::
RTP_TCP
&&
m_ticker
.
elapsedTime
()
>
15
*
1000
)
{
WarnL
<<
"RTSP会话超时:"
<<
getPeerIp
();
WarnL
<<
"RTSP会话超时:"
<<
getPeerIp
();
...
@@ -330,15 +326,23 @@ bool RtspSession::handleReq_Setup() {
...
@@ -330,15 +326,23 @@ bool RtspSession::handleReq_Setup() {
}
}
break
;
break
;
case
PlayerBase
:
:
RTP_UDP
:
{
case
PlayerBase
:
:
RTP_UDP
:
{
auto
pSock
=
UDPServer
::
Instance
().
getSock
(
getLocalIp
().
data
(),
trackIdx
);
//我们用trackIdx区分rtp和rtcp包
if
(
!
pSock
)
{
auto
pSockRtp
=
UDPServer
::
Instance
().
getSock
(
getLocalIp
().
data
(),
2
*
trackIdx
);
if
(
!
pSockRtp
)
{
//分配端口失败
WarnL
<<
"分配rtp端口失败"
;
send_NotAcceptable
();
return
false
;
}
auto
pSockRtcp
=
UDPServer
::
Instance
().
getSock
(
getLocalIp
().
data
(),
2
*
trackIdx
+
1
,
pSockRtp
->
get_local_port
()
+
1
);
if
(
!
pSockRtcp
)
{
//分配端口失败
//分配端口失败
WarnL
<<
"分配端口失败"
;
WarnL
<<
"分配
rtcp
端口失败"
;
send_NotAcceptable
();
send_NotAcceptable
();
return
false
;
return
false
;
}
}
m_apUdpSock
[
trackIdx
]
=
pSock
;
m_apUdpSock
[
trackIdx
]
=
pSock
Rtp
;
int
iSrvPort
=
pSock
->
get_local_port
();
//设置客户端内网端口信息
string
strClientPort
=
FindField
(
m_parser
[
"Transport"
].
data
(),
"client_port="
,
NULL
);
string
strClientPort
=
FindField
(
m_parser
[
"Transport"
].
data
(),
"client_port="
,
NULL
);
uint16_t
ui16PeerPort
=
atoi
(
FindField
(
strClientPort
.
data
(),
NULL
,
"-"
).
data
());
uint16_t
ui16PeerPort
=
atoi
(
FindField
(
strClientPort
.
data
(),
NULL
,
"-"
).
data
());
struct
sockaddr_in
peerAddr
;
struct
sockaddr_in
peerAddr
;
...
@@ -347,7 +351,8 @@ bool RtspSession::handleReq_Setup() {
...
@@ -347,7 +351,8 @@ bool RtspSession::handleReq_Setup() {
peerAddr
.
sin_addr
.
s_addr
=
inet_addr
(
getPeerIp
().
data
());
peerAddr
.
sin_addr
.
s_addr
=
inet_addr
(
getPeerIp
().
data
());
bzero
(
&
(
peerAddr
.
sin_zero
),
sizeof
peerAddr
.
sin_zero
);
bzero
(
&
(
peerAddr
.
sin_zero
),
sizeof
peerAddr
.
sin_zero
);
m_apPeerUdpAddr
[
trackIdx
].
reset
((
struct
sockaddr
*
)
(
new
struct
sockaddr_in
(
peerAddr
)));
m_apPeerUdpAddr
[
trackIdx
].
reset
((
struct
sockaddr
*
)
(
new
struct
sockaddr_in
(
peerAddr
)));
tryGetPeerUdpPort
();
//尝试获取客户端nat映射地址
startListenPeerUdpData
();
//InfoL << "分配端口:" << srv_port;
//InfoL << "分配端口:" << srv_port;
int
n
=
sprintf
(
m_pcBuf
,
"RTSP/1.0 200 OK
\r\n
"
int
n
=
sprintf
(
m_pcBuf
,
"RTSP/1.0 200 OK
\r\n
"
"CSeq: %d
\r\n
"
"CSeq: %d
\r\n
"
...
@@ -359,7 +364,7 @@ bool RtspSession::handleReq_Setup() {
...
@@ -359,7 +364,7 @@ bool RtspSession::handleReq_Setup() {
m_iCseq
,
g_serverName
.
data
(),
m_iCseq
,
g_serverName
.
data
(),
RTSP_VERSION
,
RTSP_BUILDTIME
,
RTSP_VERSION
,
RTSP_BUILDTIME
,
dateHeader
().
data
(),
strClientPort
.
data
(),
dateHeader
().
data
(),
strClientPort
.
data
(),
iSrvPort
,
iSrvPort
+
1
,
pSockRtp
->
get_local_port
(),
pSockRtcp
->
get_local_port
()
,
printSSRC
(
trackRef
.
ssrc
).
data
(),
printSSRC
(
trackRef
.
ssrc
).
data
(),
m_strSession
.
data
());
m_strSession
.
data
());
send
(
m_pcBuf
,
n
);
send
(
m_pcBuf
,
n
);
...
@@ -382,6 +387,15 @@ bool RtspSession::handleReq_Setup() {
...
@@ -382,6 +387,15 @@ bool RtspSession::handleReq_Setup() {
});
});
}
}
int
iSrvPort
=
m_pBrdcaster
->
getPort
(
trackid
);
int
iSrvPort
=
m_pBrdcaster
->
getPort
(
trackid
);
//我们用trackIdx区分rtp和rtcp包
auto
pSockRtcp
=
UDPServer
::
Instance
().
getSock
(
getLocalIp
().
data
(),
2
*
trackIdx
+
1
,
iSrvPort
+
1
);
if
(
!
pSockRtcp
)
{
//分配端口失败
WarnL
<<
"分配rtcp端口失败"
;
send_NotAcceptable
();
return
false
;
}
startListenPeerUdpData
();
static
uint32_t
udpTTL
=
mINI
::
Instance
()[
MultiCast
::
kUdpTTL
].
as
<
uint32_t
>
();
static
uint32_t
udpTTL
=
mINI
::
Instance
()[
MultiCast
::
kUdpTTL
].
as
<
uint32_t
>
();
int
n
=
sprintf
(
m_pcBuf
,
"RTSP/1.0 200 OK
\r\n
"
int
n
=
sprintf
(
m_pcBuf
,
"RTSP/1.0 200 OK
\r\n
"
"CSeq: %d
\r\n
"
"CSeq: %d
\r\n
"
...
@@ -393,7 +407,7 @@ bool RtspSession::handleReq_Setup() {
...
@@ -393,7 +407,7 @@ bool RtspSession::handleReq_Setup() {
m_iCseq
,
g_serverName
.
data
(),
m_iCseq
,
g_serverName
.
data
(),
RTSP_VERSION
,
RTSP_BUILDTIME
,
RTSP_VERSION
,
RTSP_BUILDTIME
,
dateHeader
().
data
(),
m_pBrdcaster
->
getIP
().
data
(),
dateHeader
().
data
(),
m_pBrdcaster
->
getIP
().
data
(),
getLocalIp
().
data
(),
iSrvPort
,
iSrvPort
+
1
,
getLocalIp
().
data
(),
iSrvPort
,
pSockRtcp
->
get_local_port
()
,
udpTTL
,
printSSRC
(
trackRef
.
ssrc
).
data
(),
udpTTL
,
printSSRC
(
trackRef
.
ssrc
).
data
(),
m_strSession
.
data
());
m_strSession
.
data
());
send
(
m_pcBuf
,
n
);
send
(
m_pcBuf
,
n
);
...
@@ -655,30 +669,37 @@ inline void RtspSession::sendRtpPacket(const RtpPacket& pkt) {
...
@@ -655,30 +669,37 @@ inline void RtspSession::sendRtpPacket(const RtpPacket& pkt) {
}
}
inline
void
RtspSession
::
onRcvPeerUdpData
(
int
iTrackIdx
,
const
Socket
::
Buffer
::
Ptr
&
pBuf
,
const
struct
sockaddr
&
addr
)
{
inline
void
RtspSession
::
onRcvPeerUdpData
(
int
iTrackIdx
,
const
Socket
::
Buffer
::
Ptr
&
pBuf
,
const
struct
sockaddr
&
addr
)
{
m_apPeerUdpAddr
[
iTrackIdx
].
reset
(
new
struct
sockaddr
(
addr
));
if
(
iTrackIdx
%
2
==
0
){
m_abGotPeerUdp
[
iTrackIdx
]
=
true
;
//这是rtp探测包
bool
bGotAllPeerUdp
=
true
;
if
(
!
m_bGotAllPeerUdp
){
//还没有获取完整的rtp探测包
if
(
SockUtil
::
in_same_lan
(
getLocalIp
().
data
(),
getPeerIp
().
data
())){
//在内网中,客户端上报的端口号是真实的,所以我们忽略udp打洞包
m_bGotAllPeerUdp
=
true
;
return
;
}
//设置真实的客户端nat映射端口号
m_apPeerUdpAddr
[
iTrackIdx
/
2
].
reset
(
new
struct
sockaddr
(
addr
));
m_abGotPeerUdp
[
iTrackIdx
/
2
]
=
true
;
m_bGotAllPeerUdp
=
true
;
//先假设获取到完整的rtp探测包
for
(
unsigned
int
i
=
0
;
i
<
m_uiTrackCnt
;
i
++
)
{
for
(
unsigned
int
i
=
0
;
i
<
m_uiTrackCnt
;
i
++
)
{
if
(
!
m_abGotPeerUdp
[
i
])
{
if
(
!
m_abGotPeerUdp
[
i
])
{
bGotAllPeerUdp
=
false
;
//还有track没获取到rtp探测包
m_bGotAllPeerUdp
=
false
;
break
;
break
;
}
}
}
}
if
(
bGotAllPeerUdp
)
{
if
(
m_bListenPeerUdpPort
)
{
UDPServer
::
Instance
().
stopListenPeer
(
getPeerIp
().
data
(),
this
);
m_bListenPeerUdpPort
=
false
;
InfoL
<<
"获取到客户端端口"
;
}
}
}
else
{
//这是rtcp心跳包,说明播放器还存活
m_ticker
.
resetTime
();
TraceL
<<
"rtcp:"
<<
(
iTrackIdx
-
1
)
/
2
;
}
}
}
}
inline
void
RtspSession
::
tryGetPeerUdpPort
()
{
inline
void
RtspSession
::
startListenPeerUdpData
()
{
if
(
SockUtil
::
in_same_lan
(
getLocalIp
().
data
(),
getPeerIp
().
data
())){
m_bListenPeerUdpData
=
true
;
return
;
}
m_bListenPeerUdpPort
=
true
;
weak_ptr
<
RtspSession
>
weakSelf
=
dynamic_pointer_cast
<
RtspSession
>
(
shared_from_this
());
weak_ptr
<
RtspSession
>
weakSelf
=
dynamic_pointer_cast
<
RtspSession
>
(
shared_from_this
());
UDPServer
::
Instance
().
listenPeer
(
getPeerIp
().
data
(),
this
,
UDPServer
::
Instance
().
listenPeer
(
getPeerIp
().
data
(),
this
,
[
weakSelf
](
int
iTrackIdx
,
const
Socket
::
Buffer
::
Ptr
&
pBuf
,
struct
sockaddr
*
pPeerAddr
)
->
bool
{
[
weakSelf
](
int
iTrackIdx
,
const
Socket
::
Buffer
::
Ptr
&
pBuf
,
struct
sockaddr
*
pPeerAddr
)
->
bool
{
...
...
src/Rtsp/RtspSession.h
查看文件 @
101261c2
...
@@ -102,7 +102,7 @@ private:
...
@@ -102,7 +102,7 @@ private:
return
-
1
;
return
-
1
;
}
}
inline
void
onRcvPeerUdpData
(
int
iTrackIdx
,
const
Socket
::
Buffer
::
Ptr
&
pBuf
,
const
struct
sockaddr
&
addr
);
inline
void
onRcvPeerUdpData
(
int
iTrackIdx
,
const
Socket
::
Buffer
::
Ptr
&
pBuf
,
const
struct
sockaddr
&
addr
);
inline
void
tryGetPeerUdpPort
();
inline
void
startListenPeerUdpData
();
char
*
m_pcBuf
=
nullptr
;
char
*
m_pcBuf
=
nullptr
;
Ticker
m_ticker
;
Ticker
m_ticker
;
...
@@ -125,6 +125,7 @@ private:
...
@@ -125,6 +125,7 @@ private:
int
m_iCseq
=
0
;
int
m_iCseq
=
0
;
unsigned
int
m_uiTrackCnt
=
0
;
//媒体track个数
unsigned
int
m_uiTrackCnt
=
0
;
//媒体track个数
RtspTrack
m_aTrackInfo
[
2
];
//媒体track信息,trackid idx 为数组下标
RtspTrack
m_aTrackInfo
[
2
];
//媒体track信息,trackid idx 为数组下标
bool
m_bGotAllPeerUdp
=
false
;
#ifdef RTSP_SEND_RTCP
#ifdef RTSP_SEND_RTCP
RtcpCounter
m_aRtcpCnt
[
2
];
//rtcp统计,trackid idx 为数组下标
RtcpCounter
m_aRtcpCnt
[
2
];
//rtcp统计,trackid idx 为数组下标
...
@@ -136,7 +137,7 @@ private:
...
@@ -136,7 +137,7 @@ private:
bool
m_abGotPeerUdp
[
2
]
=
{
false
,
false
};
//获取客户端udp端口计数
bool
m_abGotPeerUdp
[
2
]
=
{
false
,
false
};
//获取客户端udp端口计数
weak_ptr
<
Socket
>
m_apUdpSock
[
2
];
//发送RTP的UDP端口,trackid idx 为数组下标
weak_ptr
<
Socket
>
m_apUdpSock
[
2
];
//发送RTP的UDP端口,trackid idx 为数组下标
std
::
shared_ptr
<
struct
sockaddr
>
m_apPeerUdpAddr
[
2
];
//播放器接收RTP的地址,trackid idx 为数组下标
std
::
shared_ptr
<
struct
sockaddr
>
m_apPeerUdpAddr
[
2
];
//播放器接收RTP的地址,trackid idx 为数组下标
bool
m_bListenPeerUdp
Port
=
false
;
bool
m_bListenPeerUdp
Data
=
false
;
RtpBroadCaster
::
Ptr
m_pBrdcaster
;
RtpBroadCaster
::
Ptr
m_pBrdcaster
;
//RTSP over HTTP
//RTSP over HTTP
...
...
src/Rtsp/UDPServer.cpp
查看文件 @
101261c2
...
@@ -39,15 +39,15 @@ UDPServer::~UDPServer() {
...
@@ -39,15 +39,15 @@ UDPServer::~UDPServer() {
InfoL
;
InfoL
;
}
}
Socket
::
Ptr
UDPServer
::
getSock
(
const
char
*
strLocalIp
,
int
iTrackIndex
)
{
Socket
::
Ptr
UDPServer
::
getSock
(
const
char
*
strLocalIp
,
int
iTrackIndex
,
uint16_t
iLocalPort
)
{
lock_guard
<
mutex
>
lck
(
m_mtxUpdSock
);
lock_guard
<
mutex
>
lck
(
m_mtxUpdSock
);
string
strKey
=
StrPrinter
<<
strLocalIp
<<
":"
<<
iTrackIndex
<<
endl
;
string
strKey
=
StrPrinter
<<
strLocalIp
<<
":"
<<
iTrackIndex
<<
endl
;
auto
it
=
m_mapUpdSock
.
find
(
strKey
);
auto
it
=
m_mapUpdSock
.
find
(
strKey
);
if
(
it
==
m_mapUpdSock
.
end
())
{
if
(
it
==
m_mapUpdSock
.
end
())
{
Socket
::
Ptr
pSock
(
new
Socket
());
Socket
::
Ptr
pSock
(
new
Socket
());
//InfoL<<localIp;
//InfoL<<localIp;
if
(
!
pSock
->
bindUdpSock
(
0
,
strLocalIp
))
{
if
(
!
pSock
->
bindUdpSock
(
iLocalPort
,
strLocalIp
))
{
//
系统随机分配端口
//
分配失败
return
nullptr
;
return
nullptr
;
}
}
...
...
src/Rtsp/UDPServer.h
查看文件 @
101261c2
...
@@ -54,7 +54,7 @@ public:
...
@@ -54,7 +54,7 @@ public:
static
void
Destory
()
{
static
void
Destory
()
{
delete
&
UDPServer
::
Instance
();
delete
&
UDPServer
::
Instance
();
}
}
Socket
::
Ptr
getSock
(
const
char
*
strLocalIp
,
int
iTrackIndex
);
Socket
::
Ptr
getSock
(
const
char
*
strLocalIp
,
int
iTrackIndex
,
uint16_t
iLocalPort
=
0
);
void
listenPeer
(
const
char
*
strPeerIp
,
void
*
pSelf
,
const
onRecvData
&
cb
);
void
listenPeer
(
const
char
*
strPeerIp
,
void
*
pSelf
,
const
onRecvData
&
cb
);
void
stopListenPeer
(
const
char
*
strPeerIp
,
void
*
pSelf
);
void
stopListenPeer
(
const
char
*
strPeerIp
,
void
*
pSelf
);
private
:
private
:
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论