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
f71a9bfa
Commit
f71a9bfa
authored
May 15, 2020
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修复rtsp播放器时间戳紊乱的bug
parent
cded823b
显示空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
152 行增加
和
165 行删除
+152
-165
src/Rtsp/RtspPlayer.cpp
+127
-140
src/Rtsp/RtspPlayer.h
+25
-25
没有找到文件。
src/Rtsp/RtspPlayer.cpp
查看文件 @
f71a9bfa
...
@@ -10,14 +10,11 @@
...
@@ -10,14 +10,11 @@
#include <set>
#include <set>
#include <cmath>
#include <cmath>
#include <stdarg.h>
#include <algorithm>
#include <algorithm>
#include <iomanip>
#include <iomanip>
#include "Common/config.h"
#include "Common/config.h"
#include "RtspPlayer.h"
#include "RtspPlayer.h"
#include "Util/MD5.h"
#include "Util/MD5.h"
#include "Util/mini.h"
#include "Util/util.h"
#include "Util/util.h"
#include "Util/base64.h"
#include "Util/base64.h"
#include "Network/sockutil.h"
#include "Network/sockutil.h"
...
@@ -40,28 +37,28 @@ RtspPlayer::~RtspPlayer(void) {
...
@@ -40,28 +37,28 @@ RtspPlayer::~RtspPlayer(void) {
}
}
void
RtspPlayer
::
teardown
(){
void
RtspPlayer
::
teardown
(){
if
(
alive
())
{
if
(
alive
())
{
sendRtspRequest
(
"TEARDOWN"
,
_
strContentB
ase
);
sendRtspRequest
(
"TEARDOWN"
,
_
content_b
ase
);
shutdown
(
SockException
(
Err_shutdown
,
"teardown"
));
shutdown
(
SockException
(
Err_shutdown
,
"teardown"
));
}
}
_
rtspMd5N
once
.
clear
();
_
md5_n
once
.
clear
();
_r
tspR
ealm
.
clear
();
_realm
.
clear
();
_
aTrackInfo
.
clear
();
_
sdp_track
.
clear
();
_s
trSession
.
clear
();
_s
ession_id
.
clear
();
_
strContentB
ase
.
clear
();
_
content_b
ase
.
clear
();
RtpReceiver
::
clear
();
RtpReceiver
::
clear
();
CLEAR_ARR
(
_
apRtpS
ock
);
CLEAR_ARR
(
_
rtp_s
ock
);
CLEAR_ARR
(
_
apRtcpS
ock
);
CLEAR_ARR
(
_
rtcp_s
ock
);
CLEAR_ARR
(
_
aui16FirstSeq
)
CLEAR_ARR
(
_
rtp_seq_start
)
CLEAR_ARR
(
_
aui64RtpRecv
)
CLEAR_ARR
(
_
rtp_recv_count
)
CLEAR_ARR
(
_
aui64RtpRecv
)
CLEAR_ARR
(
_
rtp_recv_count
)
CLEAR_ARR
(
_
aui16NowSeq
)
CLEAR_ARR
(
_
rtp_seq_now
)
_p
PlayT
imer
.
reset
();
_p
lay_check_t
imer
.
reset
();
_
pRtpT
imer
.
reset
();
_
rtp_check_t
imer
.
reset
();
_
uiCseq
=
1
;
_
cseq_send
=
1
;
_on
Handshak
e
=
nullptr
;
_on
_respons
e
=
nullptr
;
}
}
void
RtspPlayer
::
play
(
const
string
&
strUrl
){
void
RtspPlayer
::
play
(
const
string
&
strUrl
){
...
@@ -81,20 +78,20 @@ void RtspPlayer::play(const string &strUrl){
...
@@ -81,20 +78,20 @@ void RtspPlayer::play(const string &strUrl){
(
*
this
)[
kRtspPwdIsMD5
]
=
false
;
(
*
this
)[
kRtspPwdIsMD5
]
=
false
;
}
}
_
strU
rl
=
url
.
_url
;
_
play_u
rl
=
url
.
_url
;
_
eT
ype
=
(
Rtsp
::
eRtpType
)(
int
)(
*
this
)[
kRtpType
];
_
rtp_t
ype
=
(
Rtsp
::
eRtpType
)(
int
)(
*
this
)[
kRtpType
];
DebugL
<<
url
.
_url
<<
" "
<<
(
url
.
_user
.
size
()
?
url
.
_user
:
"null"
)
<<
" "
<<
(
url
.
_passwd
.
size
()
?
url
.
_passwd
:
"null"
)
<<
" "
<<
_
eT
ype
;
DebugL
<<
url
.
_url
<<
" "
<<
(
url
.
_user
.
size
()
?
url
.
_user
:
"null"
)
<<
" "
<<
(
url
.
_passwd
.
size
()
?
url
.
_passwd
:
"null"
)
<<
" "
<<
_
rtp_t
ype
;
weak_ptr
<
RtspPlayer
>
weakSelf
=
dynamic_pointer_cast
<
RtspPlayer
>
(
shared_from_this
());
weak_ptr
<
RtspPlayer
>
weakSelf
=
dynamic_pointer_cast
<
RtspPlayer
>
(
shared_from_this
());
float
playTimeOutSec
=
(
*
this
)[
kTimeoutMS
].
as
<
int
>
()
/
1000.0
;
float
playTimeOutSec
=
(
*
this
)[
kTimeoutMS
].
as
<
int
>
()
/
1000.0
;
_p
PlayTimer
.
reset
(
new
Timer
(
playTimeOutSec
,
[
weakSelf
]()
{
_p
lay_check_timer
.
reset
(
new
Timer
(
playTimeOutSec
,
[
weakSelf
]()
{
auto
strongSelf
=
weakSelf
.
lock
();
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
if
(
!
strongSelf
)
{
return
false
;
return
false
;
}
}
strongSelf
->
onPlayResult_l
(
SockException
(
Err_timeout
,
"play rtsp timeout"
),
false
);
strongSelf
->
onPlayResult_l
(
SockException
(
Err_timeout
,
"play rtsp timeout"
),
false
);
return
false
;
return
false
;
},
getPoller
()));
},
getPoller
()));
if
(
!
(
*
this
)[
kNetAdapter
].
empty
()){
if
(
!
(
*
this
)[
kNetAdapter
].
empty
()){
setNetAdapter
((
*
this
)[
kNetAdapter
]);
setNetAdapter
((
*
this
)[
kNetAdapter
]);
...
@@ -111,9 +108,9 @@ void RtspPlayer::onConnect(const SockException &err){
...
@@ -111,9 +108,9 @@ void RtspPlayer::onConnect(const SockException &err){
}
}
void
RtspPlayer
::
onRecv
(
const
Buffer
::
Ptr
&
pBuf
)
{
void
RtspPlayer
::
onRecv
(
const
Buffer
::
Ptr
&
pBuf
)
{
if
(
_benchmark_mode
&&
!
_p
PlayT
imer
){
if
(
_benchmark_mode
&&
!
_p
lay_check_t
imer
){
//在性能测试模式下,如果rtsp握手完毕后,不再解析rtp包
//在性能测试模式下,如果rtsp握手完毕后,不再解析rtp包
_rtp
T
icker
.
resetTime
();
_rtp
_recv_t
icker
.
resetTime
();
return
;
return
;
}
}
input
(
pBuf
->
data
(),
pBuf
->
size
());
input
(
pBuf
->
data
(),
pBuf
->
size
());
...
@@ -121,12 +118,12 @@ void RtspPlayer::onRecv(const Buffer::Ptr& pBuf) {
...
@@ -121,12 +118,12 @@ void RtspPlayer::onRecv(const Buffer::Ptr& pBuf) {
void
RtspPlayer
::
onErr
(
const
SockException
&
ex
)
{
void
RtspPlayer
::
onErr
(
const
SockException
&
ex
)
{
//定时器_pPlayTimer为空后表明握手结束了
//定时器_pPlayTimer为空后表明握手结束了
onPlayResult_l
(
ex
,
!
_p
PlayT
imer
);
onPlayResult_l
(
ex
,
!
_p
lay_check_t
imer
);
}
}
// from live555
// from live555
bool
RtspPlayer
::
handleAuthenticationFailure
(
const
string
&
paramsStr
)
{
bool
RtspPlayer
::
handleAuthenticationFailure
(
const
string
&
paramsStr
)
{
if
(
!
_r
tspR
ealm
.
empty
()){
if
(
!
_realm
.
empty
()){
//已经认证过了
//已经认证过了
return
false
;
return
false
;
}
}
...
@@ -141,17 +138,17 @@ bool RtspPlayer::handleAuthenticationFailure(const string ¶msStr) {
...
@@ -141,17 +138,17 @@ bool RtspPlayer::handleAuthenticationFailure(const string ¶msStr) {
});
});
if
(
sscanf
(
paramsStr
.
data
(),
"Digest realm=
\"
%[^
\"
]
\"
, nonce=
\"
%[^
\"
]
\"
, stale=%[a-zA-Z]"
,
realm
,
nonce
,
stale
)
==
3
)
{
if
(
sscanf
(
paramsStr
.
data
(),
"Digest realm=
\"
%[^
\"
]
\"
, nonce=
\"
%[^
\"
]
\"
, stale=%[a-zA-Z]"
,
realm
,
nonce
,
stale
)
==
3
)
{
_r
tspR
ealm
=
(
const
char
*
)
realm
;
_realm
=
(
const
char
*
)
realm
;
_
rtspMd5N
once
=
(
const
char
*
)
nonce
;
_
md5_n
once
=
(
const
char
*
)
nonce
;
return
true
;
return
true
;
}
}
if
(
sscanf
(
paramsStr
.
data
(),
"Digest realm=
\"
%[^
\"
]
\"
, nonce=
\"
%[^
\"
]
\"
"
,
realm
,
nonce
)
==
2
)
{
if
(
sscanf
(
paramsStr
.
data
(),
"Digest realm=
\"
%[^
\"
]
\"
, nonce=
\"
%[^
\"
]
\"
"
,
realm
,
nonce
)
==
2
)
{
_r
tspR
ealm
=
(
const
char
*
)
realm
;
_realm
=
(
const
char
*
)
realm
;
_
rtspMd5N
once
=
(
const
char
*
)
nonce
;
_
md5_n
once
=
(
const
char
*
)
nonce
;
return
true
;
return
true
;
}
}
if
(
sscanf
(
paramsStr
.
data
(),
"Basic realm=
\"
%[^
\"
]
\"
"
,
realm
)
==
1
)
{
if
(
sscanf
(
paramsStr
.
data
(),
"Basic realm=
\"
%[^
\"
]
\"
"
,
realm
)
==
1
)
{
_r
tspR
ealm
=
(
const
char
*
)
realm
;
_realm
=
(
const
char
*
)
realm
;
return
true
;
return
true
;
}
}
return
false
;
return
false
;
...
@@ -176,30 +173,25 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) {
...
@@ -176,30 +173,25 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) {
throw
std
::
runtime_error
(
throw
std
::
runtime_error
(
StrPrinter
<<
"DESCRIBE:"
<<
parser
.
Url
()
<<
" "
<<
parser
.
Tail
()
<<
endl
);
StrPrinter
<<
"DESCRIBE:"
<<
parser
.
Url
()
<<
" "
<<
parser
.
Tail
()
<<
endl
);
}
}
_
strContentB
ase
=
parser
[
"Content-Base"
];
_
content_b
ase
=
parser
[
"Content-Base"
];
if
(
_
strContentB
ase
.
empty
()){
if
(
_
content_b
ase
.
empty
()){
_
strContentBase
=
_strU
rl
;
_
content_base
=
_play_u
rl
;
}
}
if
(
_
strContentB
ase
.
back
()
==
'/'
)
{
if
(
_
content_b
ase
.
back
()
==
'/'
)
{
_
strContentB
ase
.
pop_back
();
_
content_b
ase
.
pop_back
();
}
}
SdpParser
sdpParser
(
parser
.
Content
());
SdpParser
sdpParser
(
parser
.
Content
());
//解析sdp
//解析sdp
_
aTrackInfo
=
sdpParser
.
getAvailableTrack
();
_
sdp_track
=
sdpParser
.
getAvailableTrack
();
auto
title
=
sdpParser
.
getTrack
(
TrackTitle
);
auto
title
=
sdpParser
.
getTrack
(
TrackTitle
);
_
is_play_back
=
false
;
bool
is_play_back
=
false
;
if
(
title
&&
title
->
_duration
){
if
(
title
&&
title
->
_duration
){
_is_play_back
=
true
;
is_play_back
=
true
;
}
for
(
auto
&
stamp
:
_stamp
){
stamp
.
setPlayBack
(
_is_play_back
);
stamp
.
setRelativeStamp
(
0
);
}
}
if
(
_
aTrackInfo
.
empty
())
{
if
(
_
sdp_track
.
empty
())
{
throw
std
::
runtime_error
(
"无有效的Sdp Track"
);
throw
std
::
runtime_error
(
"无有效的Sdp Track"
);
}
}
if
(
!
onCheckSDP
(
sdpParser
.
toString
()))
{
if
(
!
onCheckSDP
(
sdpParser
.
toString
()))
{
...
@@ -211,8 +203,8 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) {
...
@@ -211,8 +203,8 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) {
//有必要的情况下创建udp端口
//有必要的情况下创建udp端口
void
RtspPlayer
::
createUdpSockIfNecessary
(
int
track_idx
){
void
RtspPlayer
::
createUdpSockIfNecessary
(
int
track_idx
){
auto
&
rtpSockRef
=
_
apRtpS
ock
[
track_idx
];
auto
&
rtpSockRef
=
_
rtp_s
ock
[
track_idx
];
auto
&
rtcpSockRef
=
_
apRtcpS
ock
[
track_idx
];
auto
&
rtcpSockRef
=
_
rtcp_s
ock
[
track_idx
];
if
(
!
rtpSockRef
||
!
rtcpSockRef
)
{
if
(
!
rtpSockRef
||
!
rtcpSockRef
)
{
auto
pr
=
makeSockPair
(
getPoller
(),
get_local_ip
());
auto
pr
=
makeSockPair
(
getPoller
(),
get_local_ip
());
rtpSockRef
=
pr
.
first
;
rtpSockRef
=
pr
.
first
;
...
@@ -222,10 +214,10 @@ void RtspPlayer::createUdpSockIfNecessary(int track_idx){
...
@@ -222,10 +214,10 @@ void RtspPlayer::createUdpSockIfNecessary(int track_idx){
//发送SETUP命令
//发送SETUP命令
void
RtspPlayer
::
sendSetup
(
unsigned
int
trackIndex
)
{
void
RtspPlayer
::
sendSetup
(
unsigned
int
trackIndex
)
{
_on
Handshake
=
std
::
bind
(
&
RtspPlayer
::
handleResSETUP
,
this
,
placeholders
::
_1
,
trackIndex
);
_on
_response
=
std
::
bind
(
&
RtspPlayer
::
handleResSETUP
,
this
,
placeholders
::
_1
,
trackIndex
);
auto
&
track
=
_
aTrackInfo
[
trackIndex
];
auto
&
track
=
_
sdp_track
[
trackIndex
];
auto
baseUrl
=
_
strContentB
ase
+
"/"
+
track
->
_control_surffix
;
auto
baseUrl
=
_
content_b
ase
+
"/"
+
track
->
_control_surffix
;
switch
(
_
eT
ype
)
{
switch
(
_
rtp_t
ype
)
{
case
Rtsp
:
:
RTP_TCP
:
{
case
Rtsp
:
:
RTP_TCP
:
{
sendRtspRequest
(
"SETUP"
,
baseUrl
,{
"Transport"
,
StrPrinter
<<
"RTP/AVP/TCP;unicast;interleaved="
<<
track
->
_type
*
2
<<
"-"
<<
track
->
_type
*
2
+
1
});
sendRtspRequest
(
"SETUP"
,
baseUrl
,{
"Transport"
,
StrPrinter
<<
"RTP/AVP/TCP;unicast;interleaved="
<<
track
->
_type
*
2
<<
"-"
<<
track
->
_type
*
2
+
1
});
}
}
...
@@ -236,10 +228,10 @@ void RtspPlayer::sendSetup(unsigned int trackIndex) {
...
@@ -236,10 +228,10 @@ void RtspPlayer::sendSetup(unsigned int trackIndex) {
break
;
break
;
case
Rtsp
:
:
RTP_UDP
:
{
case
Rtsp
:
:
RTP_UDP
:
{
createUdpSockIfNecessary
(
trackIndex
);
createUdpSockIfNecessary
(
trackIndex
);
sendRtspRequest
(
"SETUP"
,
baseUrl
,
{
"Transport"
,
sendRtspRequest
(
"SETUP"
,
baseUrl
,
{
"Transport"
,
StrPrinter
<<
"RTP/AVP;unicast;client_port="
StrPrinter
<<
"RTP/AVP;unicast;client_port="
<<
_apRtpS
ock
[
trackIndex
]
->
get_local_port
()
<<
"-"
<<
_rtp_s
ock
[
trackIndex
]
->
get_local_port
()
<<
"-"
<<
_apRtcpS
ock
[
trackIndex
]
->
get_local_port
()});
<<
_rtcp_s
ock
[
trackIndex
]
->
get_local_port
()});
}
}
break
;
break
;
default
:
default
:
...
@@ -253,34 +245,34 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
...
@@ -253,34 +245,34 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
StrPrinter
<<
"SETUP:"
<<
parser
.
Url
()
<<
" "
<<
parser
.
Tail
()
<<
endl
);
StrPrinter
<<
"SETUP:"
<<
parser
.
Url
()
<<
" "
<<
parser
.
Tail
()
<<
endl
);
}
}
if
(
uiTrackIndex
==
0
)
{
if
(
uiTrackIndex
==
0
)
{
_s
trSession
=
parser
[
"Session"
];
_s
ession_id
=
parser
[
"Session"
];
_s
trSession
.
append
(
";"
);
_s
ession_id
.
append
(
";"
);
_s
trSession
=
FindField
(
_strSession
.
data
(),
nullptr
,
";"
);
_s
ession_id
=
FindField
(
_session_id
.
data
(),
nullptr
,
";"
);
}
}
auto
strTransport
=
parser
[
"Transport"
];
auto
strTransport
=
parser
[
"Transport"
];
if
(
strTransport
.
find
(
"TCP"
)
!=
string
::
npos
||
strTransport
.
find
(
"interleaved"
)
!=
string
::
npos
){
if
(
strTransport
.
find
(
"TCP"
)
!=
string
::
npos
||
strTransport
.
find
(
"interleaved"
)
!=
string
::
npos
){
_
eT
ype
=
Rtsp
::
RTP_TCP
;
_
rtp_t
ype
=
Rtsp
::
RTP_TCP
;
}
else
if
(
strTransport
.
find
(
"multicast"
)
!=
string
::
npos
){
}
else
if
(
strTransport
.
find
(
"multicast"
)
!=
string
::
npos
){
_
eT
ype
=
Rtsp
::
RTP_MULTICAST
;
_
rtp_t
ype
=
Rtsp
::
RTP_MULTICAST
;
}
else
{
}
else
{
_
eT
ype
=
Rtsp
::
RTP_UDP
;
_
rtp_t
ype
=
Rtsp
::
RTP_UDP
;
}
}
RtspSplitter
::
enableRecvRtp
(
_
eT
ype
==
Rtsp
::
RTP_TCP
);
RtspSplitter
::
enableRecvRtp
(
_
rtp_t
ype
==
Rtsp
::
RTP_TCP
);
if
(
_
eT
ype
==
Rtsp
::
RTP_TCP
)
{
if
(
_
rtp_t
ype
==
Rtsp
::
RTP_TCP
)
{
string
interleaved
=
FindField
(
FindField
((
strTransport
+
";"
).
data
(),
"interleaved="
,
";"
).
data
(),
NULL
,
"-"
);
string
interleaved
=
FindField
(
FindField
((
strTransport
+
";"
).
data
(),
"interleaved="
,
";"
).
data
(),
NULL
,
"-"
);
_
aTrackInfo
[
uiTrackIndex
]
->
_interleaved
=
atoi
(
interleaved
.
data
());
_
sdp_track
[
uiTrackIndex
]
->
_interleaved
=
atoi
(
interleaved
.
data
());
}
else
{
}
else
{
const
char
*
strPos
=
(
_
eT
ype
==
Rtsp
::
RTP_MULTICAST
?
"port="
:
"server_port="
)
;
const
char
*
strPos
=
(
_
rtp_t
ype
==
Rtsp
::
RTP_MULTICAST
?
"port="
:
"server_port="
)
;
auto
port_str
=
FindField
((
strTransport
+
";"
).
data
(),
strPos
,
";"
);
auto
port_str
=
FindField
((
strTransport
+
";"
).
data
(),
strPos
,
";"
);
uint16_t
rtp_port
=
atoi
(
FindField
(
port_str
.
data
(),
NULL
,
"-"
).
data
());
uint16_t
rtp_port
=
atoi
(
FindField
(
port_str
.
data
(),
NULL
,
"-"
).
data
());
uint16_t
rtcp_port
=
atoi
(
FindField
(
port_str
.
data
(),
"-"
,
NULL
).
data
());
uint16_t
rtcp_port
=
atoi
(
FindField
(
port_str
.
data
(),
"-"
,
NULL
).
data
());
auto
&
pRtpSockRef
=
_
apRtpS
ock
[
uiTrackIndex
];
auto
&
pRtpSockRef
=
_
rtp_s
ock
[
uiTrackIndex
];
auto
&
pRtcpSockRef
=
_
apRtcpS
ock
[
uiTrackIndex
];
auto
&
pRtcpSockRef
=
_
rtcp_s
ock
[
uiTrackIndex
];
if
(
_
eT
ype
==
Rtsp
::
RTP_MULTICAST
)
{
if
(
_
rtp_t
ype
==
Rtsp
::
RTP_MULTICAST
)
{
//udp组播
//udp组播
auto
multiAddr
=
FindField
((
strTransport
+
";"
).
data
(),
"destination="
,
";"
);
auto
multiAddr
=
FindField
((
strTransport
+
";"
).
data
(),
"destination="
,
";"
);
pRtpSockRef
.
reset
(
new
Socket
(
getPoller
()));
pRtpSockRef
.
reset
(
new
Socket
(
getPoller
()));
...
@@ -322,7 +314,7 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
...
@@ -322,7 +314,7 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
WarnL
<<
"收到其他地址的rtp数据:"
<<
SockUtil
::
inet_ntoa
(((
struct
sockaddr_in
*
)
addr
)
->
sin_addr
);
WarnL
<<
"收到其他地址的rtp数据:"
<<
SockUtil
::
inet_ntoa
(((
struct
sockaddr_in
*
)
addr
)
->
sin_addr
);
return
;
return
;
}
}
strongSelf
->
handleOneRtp
(
uiTrackIndex
,
strongSelf
->
_
aTrackInfo
[
uiTrackIndex
],
(
unsigned
char
*
)
buf
->
data
(),
buf
->
size
());
strongSelf
->
handleOneRtp
(
uiTrackIndex
,
strongSelf
->
_
sdp_track
[
uiTrackIndex
],
(
unsigned
char
*
)
buf
->
data
(),
buf
->
size
());
});
});
if
(
pRtcpSockRef
)
{
if
(
pRtcpSockRef
)
{
...
@@ -336,12 +328,12 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
...
@@ -336,12 +328,12 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
WarnL
<<
"收到其他地址的rtcp数据:"
<<
SockUtil
::
inet_ntoa
(((
struct
sockaddr_in
*
)
addr
)
->
sin_addr
);
WarnL
<<
"收到其他地址的rtcp数据:"
<<
SockUtil
::
inet_ntoa
(((
struct
sockaddr_in
*
)
addr
)
->
sin_addr
);
return
;
return
;
}
}
strongSelf
->
onRtcpPacket
(
uiTrackIndex
,
strongSelf
->
_
aTrackInfo
[
uiTrackIndex
],
(
unsigned
char
*
)
buf
->
data
(),
buf
->
size
());
strongSelf
->
onRtcpPacket
(
uiTrackIndex
,
strongSelf
->
_
sdp_track
[
uiTrackIndex
],
(
unsigned
char
*
)
buf
->
data
(),
buf
->
size
());
});
});
}
}
}
}
if
(
uiTrackIndex
<
_
aTrackInfo
.
size
()
-
1
)
{
if
(
uiTrackIndex
<
_
sdp_track
.
size
()
-
1
)
{
//需要继续发送SETUP命令
//需要继续发送SETUP命令
sendSetup
(
uiTrackIndex
+
1
);
sendSetup
(
uiTrackIndex
+
1
);
return
;
return
;
...
@@ -353,12 +345,12 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
...
@@ -353,12 +345,12 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
void
RtspPlayer
::
sendDescribe
()
{
void
RtspPlayer
::
sendDescribe
()
{
//发送DESCRIBE命令后处理函数:handleResDESCRIBE
//发送DESCRIBE命令后处理函数:handleResDESCRIBE
_on
Handshake
=
std
::
bind
(
&
RtspPlayer
::
handleResDESCRIBE
,
this
,
placeholders
::
_1
);
_on
_response
=
std
::
bind
(
&
RtspPlayer
::
handleResDESCRIBE
,
this
,
placeholders
::
_1
);
sendRtspRequest
(
"DESCRIBE"
,
_strUrl
,{
"Accept"
,
"application/sdp"
});
sendRtspRequest
(
"DESCRIBE"
,
_play_url
,
{
"Accept"
,
"application/sdp"
});
}
}
void
RtspPlayer
::
sendOptions
(){
void
RtspPlayer
::
sendOptions
(){
_on
Handshak
e
=
[
this
](
const
Parser
&
parser
){
_on
_respons
e
=
[
this
](
const
Parser
&
parser
){
if
(
parser
.
Url
()
!=
"200"
)
{
if
(
parser
.
Url
()
!=
"200"
)
{
throw
std
::
runtime_error
(
StrPrinter
<<
"OPTIONS:"
<<
parser
.
Url
()
<<
" "
<<
parser
.
Tail
()
<<
endl
);
throw
std
::
runtime_error
(
StrPrinter
<<
"OPTIONS:"
<<
parser
.
Url
()
<<
" "
<<
parser
.
Tail
()
<<
endl
);
}
}
...
@@ -372,36 +364,36 @@ void RtspPlayer::sendOptions(){
...
@@ -372,36 +364,36 @@ void RtspPlayer::sendOptions(){
//发送Describe请求,获取sdp
//发送Describe请求,获取sdp
sendDescribe
();
sendDescribe
();
};
};
sendRtspRequest
(
"OPTIONS"
,
_strU
rl
);
sendRtspRequest
(
"OPTIONS"
,
_play_u
rl
);
}
}
void
RtspPlayer
::
sendKeepAlive
(){
void
RtspPlayer
::
sendKeepAlive
(){
_on
Handshak
e
=
[
this
](
const
Parser
&
parser
){};
_on
_respons
e
=
[
this
](
const
Parser
&
parser
){};
if
(
_supported_cmd
.
find
(
"GET_PARAMETER"
)
!=
_supported_cmd
.
end
()){
if
(
_supported_cmd
.
find
(
"GET_PARAMETER"
)
!=
_supported_cmd
.
end
()){
//支持GET_PARAMETER,用此命令保活
//支持GET_PARAMETER,用此命令保活
sendRtspRequest
(
"GET_PARAMETER"
,
_strU
rl
);
sendRtspRequest
(
"GET_PARAMETER"
,
_play_u
rl
);
}
else
{
}
else
{
//不支持GET_PARAMETER,用OPTIONS命令保活
//不支持GET_PARAMETER,用OPTIONS命令保活
sendRtspRequest
(
"OPTIONS"
,
_strU
rl
);
sendRtspRequest
(
"OPTIONS"
,
_play_u
rl
);
}
}
}
}
void
RtspPlayer
::
sendPause
(
int
type
,
uint32_t
seekMS
){
void
RtspPlayer
::
sendPause
(
int
type
,
uint32_t
seekMS
){
_on
Handshake
=
std
::
bind
(
&
RtspPlayer
::
handleResPAUSE
,
this
,
placeholders
::
_1
,
type
);
_on
_response
=
std
::
bind
(
&
RtspPlayer
::
handleResPAUSE
,
this
,
placeholders
::
_1
,
type
);
//开启或暂停rtsp
//开启或暂停rtsp
switch
(
type
){
switch
(
type
){
case
type_pause
:
case
type_pause
:
sendRtspRequest
(
"PAUSE"
,
_
strContentB
ase
);
sendRtspRequest
(
"PAUSE"
,
_
content_b
ase
);
break
;
break
;
case
type_play
:
case
type_play
:
sendRtspRequest
(
"PLAY"
,
_
strContentB
ase
);
sendRtspRequest
(
"PLAY"
,
_
content_b
ase
);
break
;
break
;
case
type_seek
:
case
type_seek
:
sendRtspRequest
(
"PLAY"
,
_
strContentB
ase
,
{
"Range"
,
StrPrinter
<<
"npt="
<<
setiosflags
(
ios
::
fixed
)
<<
setprecision
(
2
)
<<
seekMS
/
1000.0
<<
"-"
});
sendRtspRequest
(
"PLAY"
,
_
content_b
ase
,
{
"Range"
,
StrPrinter
<<
"npt="
<<
setiosflags
(
ios
::
fixed
)
<<
setprecision
(
2
)
<<
seekMS
/
1000.0
<<
"-"
});
break
;
break
;
default
:
default
:
WarnL
<<
"unknown type : "
<<
type
;
WarnL
<<
"unknown type : "
<<
type
;
_on
Handshak
e
=
nullptr
;
_on
_respons
e
=
nullptr
;
break
;
break
;
}
}
}
}
...
@@ -428,7 +420,7 @@ void RtspPlayer::handleResPAUSE(const Parser& parser,int type) {
...
@@ -428,7 +420,7 @@ void RtspPlayer::handleResPAUSE(const Parser& parser,int type) {
if
(
type
==
type_pause
)
{
if
(
type
==
type_pause
)
{
//暂停成功!
//暂停成功!
_
pRtpT
imer
.
reset
();
_
rtp_check_t
imer
.
reset
();
return
;
return
;
}
}
...
@@ -445,22 +437,20 @@ void RtspPlayer::handleResPAUSE(const Parser& parser,int type) {
...
@@ -445,22 +437,20 @@ void RtspPlayer::handleResPAUSE(const Parser& parser,int type) {
DebugL
<<
"seekTo(ms):"
<<
iSeekTo
;
DebugL
<<
"seekTo(ms):"
<<
iSeekTo
;
}
}
//设置相对时间戳
//设置相对时间戳
_stamp
[
0
].
setRelativeStamp
(
iSeekTo
);
_stamp
[
1
].
setRelativeStamp
(
iSeekTo
);
onPlayResult_l
(
SockException
(
Err_success
,
type
==
type_seek
?
"resum rtsp success"
:
"rtsp play success"
),
type
==
type_seek
);
onPlayResult_l
(
SockException
(
Err_success
,
type
==
type_seek
?
"resum rtsp success"
:
"rtsp play success"
),
type
==
type_seek
);
}
}
void
RtspPlayer
::
onWholeRtspPacket
(
Parser
&
parser
)
{
void
RtspPlayer
::
onWholeRtspPacket
(
Parser
&
parser
)
{
try
{
try
{
decltype
(
_on
Handshake
)
fun
;
decltype
(
_on
_response
)
func
;
_on
Handshake
.
swap
(
fun
);
_on
_response
.
swap
(
func
);
if
(
fun
){
if
(
fun
c
){
fun
(
parser
);
fun
c
(
parser
);
}
}
parser
.
Clear
();
parser
.
Clear
();
}
catch
(
std
::
exception
&
err
)
{
}
catch
(
std
::
exception
&
err
)
{
//定时器_pPlayTimer为空后表明握手结束了
//定时器_pPlayTimer为空后表明握手结束了
onPlayResult_l
(
SockException
(
Err_other
,
err
.
what
()),
!
_p
PlayT
imer
);
onPlayResult_l
(
SockException
(
Err_other
,
err
.
what
()),
!
_p
lay_check_t
imer
);
}
}
}
}
...
@@ -470,12 +460,12 @@ void RtspPlayer::onRtpPacket(const char *data, uint64_t len) {
...
@@ -470,12 +460,12 @@ void RtspPlayer::onRtpPacket(const char *data, uint64_t len) {
if
(
interleaved
%
2
==
0
){
if
(
interleaved
%
2
==
0
){
trackIdx
=
getTrackIndexByInterleaved
(
interleaved
);
trackIdx
=
getTrackIndexByInterleaved
(
interleaved
);
if
(
trackIdx
!=
-
1
)
{
if
(
trackIdx
!=
-
1
)
{
handleOneRtp
(
trackIdx
,
_aTrackInfo
[
trackIdx
],
(
unsigned
char
*
)
data
+
4
,
len
-
4
);
handleOneRtp
(
trackIdx
,
_sdp_track
[
trackIdx
],
(
unsigned
char
*
)
data
+
4
,
len
-
4
);
}
}
}
else
{
}
else
{
trackIdx
=
getTrackIndexByInterleaved
(
interleaved
-
1
);
trackIdx
=
getTrackIndexByInterleaved
(
interleaved
-
1
);
if
(
trackIdx
!=
-
1
)
{
if
(
trackIdx
!=
-
1
)
{
onRtcpPacket
(
trackIdx
,
_
aTrackInfo
[
trackIdx
],
(
unsigned
char
*
)
data
+
4
,
len
-
4
);
onRtcpPacket
(
trackIdx
,
_
sdp_track
[
trackIdx
],
(
unsigned
char
*
)
data
+
4
,
len
-
4
);
}
}
}
}
}
}
...
@@ -545,8 +535,8 @@ void RtspPlayer::sendReceiverReport(bool overTcp,int iTrackIndex){
...
@@ -545,8 +535,8 @@ void RtspPlayer::sendReceiverReport(bool overTcp,int iTrackIndex){
static
const
char
s_cname
[]
=
"ZLMediaKitRtsp"
;
static
const
char
s_cname
[]
=
"ZLMediaKitRtsp"
;
uint8_t
aui8Rtcp
[
4
+
32
+
10
+
sizeof
(
s_cname
)
+
1
]
=
{
0
};
uint8_t
aui8Rtcp
[
4
+
32
+
10
+
sizeof
(
s_cname
)
+
1
]
=
{
0
};
uint8_t
*
pui8Rtcp_RR
=
aui8Rtcp
+
4
,
*
pui8Rtcp_SDES
=
pui8Rtcp_RR
+
32
;
uint8_t
*
pui8Rtcp_RR
=
aui8Rtcp
+
4
,
*
pui8Rtcp_SDES
=
pui8Rtcp_RR
+
32
;
auto
&
track
=
_
aTrackInfo
[
iTrackIndex
];
auto
&
track
=
_
sdp_track
[
iTrackIndex
];
auto
&
counter
=
_
aRtcpCnt
[
iTrackIndex
];
auto
&
counter
=
_
rtcp_counter
[
iTrackIndex
];
aui8Rtcp
[
0
]
=
'$'
;
aui8Rtcp
[
0
]
=
'$'
;
aui8Rtcp
[
1
]
=
track
->
_interleaved
+
1
;
aui8Rtcp
[
1
]
=
track
->
_interleaved
+
1
;
...
@@ -602,25 +592,22 @@ void RtspPlayer::sendReceiverReport(bool overTcp,int iTrackIndex){
...
@@ -602,25 +592,22 @@ void RtspPlayer::sendReceiverReport(bool overTcp,int iTrackIndex){
if
(
overTcp
){
if
(
overTcp
){
send
(
obtainBuffer
((
char
*
)
aui8Rtcp
,
sizeof
(
aui8Rtcp
)));
send
(
obtainBuffer
((
char
*
)
aui8Rtcp
,
sizeof
(
aui8Rtcp
)));
}
else
if
(
_
apRtcpS
ock
[
iTrackIndex
])
{
}
else
if
(
_
rtcp_s
ock
[
iTrackIndex
])
{
_
apRtcpS
ock
[
iTrackIndex
]
->
send
((
char
*
)
aui8Rtcp
+
4
,
sizeof
(
aui8Rtcp
)
-
4
);
_
rtcp_s
ock
[
iTrackIndex
]
->
send
((
char
*
)
aui8Rtcp
+
4
,
sizeof
(
aui8Rtcp
)
-
4
);
}
}
}
}
void
RtspPlayer
::
onRtpSorted
(
const
RtpPacket
::
Ptr
&
rtppt
,
int
trackidx
){
void
RtspPlayer
::
onRtpSorted
(
const
RtpPacket
::
Ptr
&
rtppt
,
int
trackidx
){
//统计丢包率
//统计丢包率
if
(
_
aui16FirstSeq
[
trackidx
]
==
0
||
rtppt
->
sequence
<
_aui16FirstSeq
[
trackidx
])
{
if
(
_
rtp_seq_start
[
trackidx
]
==
0
||
rtppt
->
sequence
<
_rtp_seq_start
[
trackidx
])
{
_
aui16FirstSeq
[
trackidx
]
=
rtppt
->
sequence
;
_
rtp_seq_start
[
trackidx
]
=
rtppt
->
sequence
;
_
aui64RtpRecv
[
trackidx
]
=
0
;
_
rtp_recv_count
[
trackidx
]
=
0
;
}
}
_
aui64RtpRecv
[
trackidx
]
++
;
_
rtp_recv_count
[
trackidx
]
++
;
_
aui16NowSeq
[
trackidx
]
=
rtppt
->
sequence
;
_
rtp_seq_now
[
trackidx
]
=
rtppt
->
sequence
;
_stamp
[
trackidx
]
=
rtppt
->
timeStamp
;
//计算相对时间戳
//计算相对时间戳
int64_t
dts_out
;
onRecvRTP_l
(
rtppt
,
_sdp_track
[
trackidx
]);
_stamp
[
trackidx
].
revise
(
rtppt
->
timeStamp
,
rtppt
->
timeStamp
,
dts_out
,
dts_out
);
rtppt
->
timeStamp
=
dts_out
;
onRecvRTP_l
(
rtppt
,
_aTrackInfo
[
trackidx
]);
}
}
float
RtspPlayer
::
getPacketLossRate
(
TrackType
type
)
const
{
float
RtspPlayer
::
getPacketLossRate
(
TrackType
type
)
const
{
...
@@ -628,9 +615,9 @@ float RtspPlayer::getPacketLossRate(TrackType type) const{
...
@@ -628,9 +615,9 @@ float RtspPlayer::getPacketLossRate(TrackType type) const{
if
(
iTrackIdx
==
-
1
){
if
(
iTrackIdx
==
-
1
){
uint64_t
totalRecv
=
0
;
uint64_t
totalRecv
=
0
;
uint64_t
totalSend
=
0
;
uint64_t
totalSend
=
0
;
for
(
unsigned
int
i
=
0
;
i
<
_
aTrackInfo
.
size
();
i
++
)
{
for
(
unsigned
int
i
=
0
;
i
<
_
sdp_track
.
size
();
i
++
)
{
totalRecv
+=
_
aui64RtpRecv
[
i
];
totalRecv
+=
_
rtp_recv_count
[
i
];
totalSend
+=
(
_
aui16NowSeq
[
i
]
-
_aui16FirstSeq
[
i
]
+
1
);
totalSend
+=
(
_
rtp_seq_now
[
i
]
-
_rtp_seq_start
[
i
]
+
1
);
}
}
if
(
totalSend
==
0
){
if
(
totalSend
==
0
){
return
0
;
return
0
;
...
@@ -638,14 +625,14 @@ float RtspPlayer::getPacketLossRate(TrackType type) const{
...
@@ -638,14 +625,14 @@ float RtspPlayer::getPacketLossRate(TrackType type) const{
return
1.0
-
(
double
)
totalRecv
/
totalSend
;
return
1.0
-
(
double
)
totalRecv
/
totalSend
;
}
}
if
(
_
aui16NowSeq
[
iTrackIdx
]
-
_aui16FirstSeq
[
iTrackIdx
]
+
1
==
0
){
if
(
_
rtp_seq_now
[
iTrackIdx
]
-
_rtp_seq_start
[
iTrackIdx
]
+
1
==
0
){
return
0
;
return
0
;
}
}
return
1.0
-
(
double
)
_
aui64RtpRecv
[
iTrackIdx
]
/
(
_aui16NowSeq
[
iTrackIdx
]
-
_aui16FirstSeq
[
iTrackIdx
]
+
1
);
return
1.0
-
(
double
)
_
rtp_recv_count
[
iTrackIdx
]
/
(
_rtp_seq_now
[
iTrackIdx
]
-
_rtp_seq_start
[
iTrackIdx
]
+
1
);
}
}
uint32_t
RtspPlayer
::
getProgressMilliSecond
()
const
{
uint32_t
RtspPlayer
::
getProgressMilliSecond
()
const
{
return
MAX
(
_stamp
[
0
]
.
getRelativeStamp
(),
_stamp
[
1
].
getRelativeStamp
()
);
return
MAX
(
_stamp
[
0
]
,
_stamp
[
1
]
);
}
}
void
RtspPlayer
::
seekToMilliSecond
(
uint32_t
ms
)
{
void
RtspPlayer
::
seekToMilliSecond
(
uint32_t
ms
)
{
...
@@ -668,15 +655,15 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url, const std
...
@@ -668,15 +655,15 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url, const std
void
RtspPlayer
::
sendRtspRequest
(
const
string
&
cmd
,
const
string
&
url
,
const
StrCaseMap
&
header_const
)
{
void
RtspPlayer
::
sendRtspRequest
(
const
string
&
cmd
,
const
string
&
url
,
const
StrCaseMap
&
header_const
)
{
auto
header
=
header_const
;
auto
header
=
header_const
;
header
.
emplace
(
"CSeq"
,
StrPrinter
<<
_
uiCseq
++
);
header
.
emplace
(
"CSeq"
,
StrPrinter
<<
_
cseq_send
++
);
header
.
emplace
(
"User-Agent"
,
SERVER_NAME
);
header
.
emplace
(
"User-Agent"
,
SERVER_NAME
);
if
(
!
_s
trSession
.
empty
()){
if
(
!
_s
ession_id
.
empty
()){
header
.
emplace
(
"Session"
,
_strSession
);
header
.
emplace
(
"Session"
,
_session_id
);
}
}
if
(
!
_r
tspR
ealm
.
empty
()
&&
!
(
*
this
)[
kRtspUser
].
empty
()){
if
(
!
_realm
.
empty
()
&&
!
(
*
this
)[
kRtspUser
].
empty
()){
if
(
!
_
rtspMd5N
once
.
empty
()){
if
(
!
_
md5_n
once
.
empty
()){
//MD5认证
//MD5认证
/*
/*
response计算方法如下:
response计算方法如下:
...
@@ -688,14 +675,14 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrC
...
@@ -688,14 +675,14 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrC
*/
*/
string
encrypted_pwd
=
(
*
this
)[
kRtspPwd
];
string
encrypted_pwd
=
(
*
this
)[
kRtspPwd
];
if
(
!
(
*
this
)[
kRtspPwdIsMD5
].
as
<
bool
>
()){
if
(
!
(
*
this
)[
kRtspPwdIsMD5
].
as
<
bool
>
()){
encrypted_pwd
=
MD5
((
*
this
)[
kRtspUser
]
+
":"
+
_rtspR
ealm
+
":"
+
encrypted_pwd
).
hexdigest
();
encrypted_pwd
=
MD5
((
*
this
)[
kRtspUser
]
+
":"
+
_r
ealm
+
":"
+
encrypted_pwd
).
hexdigest
();
}
}
auto
response
=
MD5
(
encrypted_pwd
+
":"
+
_rtspMd5Nonce
+
":"
+
MD5
(
cmd
+
":"
+
url
).
hexdigest
()).
hexdigest
();
auto
response
=
MD5
(
encrypted_pwd
+
":"
+
_md5_nonce
+
":"
+
MD5
(
cmd
+
":"
+
url
).
hexdigest
()).
hexdigest
();
_StrPrinter
printer
;
_StrPrinter
printer
;
printer
<<
"Digest "
;
printer
<<
"Digest "
;
printer
<<
"username=
\"
"
<<
(
*
this
)[
kRtspUser
]
<<
"
\"
, "
;
printer
<<
"username=
\"
"
<<
(
*
this
)[
kRtspUser
]
<<
"
\"
, "
;
printer
<<
"realm=
\"
"
<<
_r
tspR
ealm
<<
"
\"
, "
;
printer
<<
"realm=
\"
"
<<
_realm
<<
"
\"
, "
;
printer
<<
"nonce=
\"
"
<<
_
rtspMd5N
once
<<
"
\"
, "
;
printer
<<
"nonce=
\"
"
<<
_
md5_n
once
<<
"
\"
, "
;
printer
<<
"uri=
\"
"
<<
url
<<
"
\"
, "
;
printer
<<
"uri=
\"
"
<<
url
<<
"
\"
, "
;
printer
<<
"response=
\"
"
<<
response
<<
"
\"
"
;
printer
<<
"response=
\"
"
<<
response
<<
"
\"
"
;
header
.
emplace
(
"Authorization"
,
printer
);
header
.
emplace
(
"Authorization"
,
printer
);
...
@@ -717,23 +704,23 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrC
...
@@ -717,23 +704,23 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrC
}
}
void
RtspPlayer
::
onRecvRTP_l
(
const
RtpPacket
::
Ptr
&
pkt
,
const
SdpTrack
::
Ptr
&
track
)
{
void
RtspPlayer
::
onRecvRTP_l
(
const
RtpPacket
::
Ptr
&
pkt
,
const
SdpTrack
::
Ptr
&
track
)
{
_rtp
T
icker
.
resetTime
();
_rtp
_recv_t
icker
.
resetTime
();
onRecvRTP
(
pkt
,
track
);
onRecvRTP
(
pkt
,
track
);
int
iTrackIndex
=
getTrackIndexByInterleaved
(
pkt
->
interleaved
);
int
iTrackIndex
=
getTrackIndexByInterleaved
(
pkt
->
interleaved
);
if
(
iTrackIndex
==
-
1
)
{
if
(
iTrackIndex
==
-
1
)
{
return
;
return
;
}
}
RtcpCounter
&
counter
=
_
aRtcpCnt
[
iTrackIndex
];
RtcpCounter
&
counter
=
_
rtcp_counter
[
iTrackIndex
];
counter
.
pktCnt
=
pkt
->
sequence
;
counter
.
pktCnt
=
pkt
->
sequence
;
auto
&
ticker
=
_
aRtcpT
icker
[
iTrackIndex
];
auto
&
ticker
=
_
rtcp_send_t
icker
[
iTrackIndex
];
if
(
ticker
.
elapsedTime
()
>
5
*
1000
)
{
if
(
ticker
.
elapsedTime
()
>
5
*
1000
)
{
//send rtcp every 5 second
//send rtcp every 5 second
counter
.
lastTimeStamp
=
counter
.
timeStamp
;
counter
.
lastTimeStamp
=
counter
.
timeStamp
;
//直接保存网络字节序
//直接保存网络字节序
memcpy
(
&
counter
.
timeStamp
,
pkt
->
data
()
+
8
,
4
);
memcpy
(
&
counter
.
timeStamp
,
pkt
->
data
()
+
8
,
4
);
if
(
counter
.
lastTimeStamp
!=
0
)
{
if
(
counter
.
lastTimeStamp
!=
0
)
{
sendReceiverReport
(
_
eT
ype
==
Rtsp
::
RTP_TCP
,
iTrackIndex
);
sendReceiverReport
(
_
rtp_t
ype
==
Rtsp
::
RTP_TCP
,
iTrackIndex
);
ticker
.
resetTime
();
ticker
.
resetTime
();
}
}
...
@@ -750,27 +737,27 @@ void RtspPlayer::onPlayResult_l(const SockException &ex , bool handshakeComplete
...
@@ -750,27 +737,27 @@ void RtspPlayer::onPlayResult_l(const SockException &ex , bool handshakeComplete
if
(
!
ex
){
if
(
!
ex
){
//播放成功,恢复rtp接收超时定时器
//播放成功,恢复rtp接收超时定时器
_rtp
T
icker
.
resetTime
();
_rtp
_recv_t
icker
.
resetTime
();
weak_ptr
<
RtspPlayer
>
weakSelf
=
dynamic_pointer_cast
<
RtspPlayer
>
(
shared_from_this
());
weak_ptr
<
RtspPlayer
>
weakSelf
=
dynamic_pointer_cast
<
RtspPlayer
>
(
shared_from_this
());
int
timeoutMS
=
(
*
this
)[
kMediaTimeoutMS
].
as
<
int
>
();
int
timeoutMS
=
(
*
this
)[
kMediaTimeoutMS
].
as
<
int
>
();
//创建rtp数据接收超时检测定时器
//创建rtp数据接收超时检测定时器
_
pRtpTimer
.
reset
(
new
Timer
(
timeoutMS
/
2000.0
,
[
weakSelf
,
timeoutMS
]()
{
_
rtp_check_timer
.
reset
(
new
Timer
(
timeoutMS
/
2000.0
,
[
weakSelf
,
timeoutMS
]()
{
auto
strongSelf
=
weakSelf
.
lock
();
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
if
(
!
strongSelf
)
{
return
false
;
return
false
;
}
}
if
(
strongSelf
->
_rtp
Ticker
.
elapsedTime
()
>
timeoutMS
)
{
if
(
strongSelf
->
_rtp
_recv_ticker
.
elapsedTime
()
>
timeoutMS
)
{
//接收rtp媒体数据包超时
//接收rtp媒体数据包超时
strongSelf
->
onPlayResult_l
(
SockException
(
Err_timeout
,
"receive rtp timeout"
),
true
);
strongSelf
->
onPlayResult_l
(
SockException
(
Err_timeout
,
"receive rtp timeout"
),
true
);
return
false
;
return
false
;
}
}
return
true
;
return
true
;
},
getPoller
()));
},
getPoller
()));
}
}
if
(
!
handshakeCompleted
)
{
if
(
!
handshakeCompleted
)
{
//开始播放阶段
//开始播放阶段
_p
PlayT
imer
.
reset
();
_p
lay_check_t
imer
.
reset
();
onPlayResult
(
ex
);
onPlayResult
(
ex
);
//是否为性能测试模式
//是否为性能测试模式
_benchmark_mode
=
(
*
this
)[
Client
::
kBenchmarkMode
].
as
<
int
>
();
_benchmark_mode
=
(
*
this
)[
Client
::
kBenchmarkMode
].
as
<
int
>
();
...
@@ -787,25 +774,25 @@ void RtspPlayer::onPlayResult_l(const SockException &ex , bool handshakeComplete
...
@@ -787,25 +774,25 @@ void RtspPlayer::onPlayResult_l(const SockException &ex , bool handshakeComplete
}
}
}
}
int
RtspPlayer
::
getTrackIndexByInterleaved
(
int
interleaved
)
const
{
int
RtspPlayer
::
getTrackIndexByInterleaved
(
int
interleaved
)
const
{
for
(
unsigned
int
i
=
0
;
i
<
_
aTrackInfo
.
size
();
i
++
)
{
for
(
unsigned
int
i
=
0
;
i
<
_
sdp_track
.
size
();
i
++
)
{
if
(
_
aTrackInfo
[
i
]
->
_interleaved
==
interleaved
)
{
if
(
_
sdp_track
[
i
]
->
_interleaved
==
interleaved
)
{
return
i
;
return
i
;
}
}
}
}
if
(
_aTrackInfo
.
size
()
==
1
)
{
if
(
_sdp_track
.
size
()
==
1
)
{
return
0
;
return
0
;
}
}
return
-
1
;
return
-
1
;
}
}
int
RtspPlayer
::
getTrackIndexByTrackType
(
TrackType
trackType
)
const
{
int
RtspPlayer
::
getTrackIndexByTrackType
(
TrackType
trackType
)
const
{
for
(
unsigned
int
i
=
0
;
i
<
_
aTrackInfo
.
size
();
i
++
)
{
for
(
unsigned
int
i
=
0
;
i
<
_
sdp_track
.
size
();
i
++
)
{
if
(
_
aTrackInfo
[
i
]
->
_type
==
trackType
)
{
if
(
_
sdp_track
[
i
]
->
_type
==
trackType
)
{
return
i
;
return
i
;
}
}
}
}
if
(
_aTrackInfo
.
size
()
==
1
)
{
if
(
_sdp_track
.
size
()
==
1
)
{
return
0
;
return
0
;
}
}
return
-
1
;
return
-
1
;
...
...
src/Rtsp/RtspPlayer.h
查看文件 @
f71a9bfa
...
@@ -105,40 +105,40 @@ private:
...
@@ -105,40 +105,40 @@ private:
void
sendReceiverReport
(
bool
overTcp
,
int
iTrackIndex
);
void
sendReceiverReport
(
bool
overTcp
,
int
iTrackIndex
);
void
createUdpSockIfNecessary
(
int
track_idx
);
void
createUdpSockIfNecessary
(
int
track_idx
);
private
:
private
:
string
_strUrl
;
string
_play_url
;
vector
<
SdpTrack
::
Ptr
>
_aTrackInfo
;
vector
<
SdpTrack
::
Ptr
>
_sdp_track
;
function
<
void
(
const
Parser
&
)
>
_onHandshake
;
function
<
void
(
const
Parser
&
)
>
_on_response
;
Socket
::
Ptr
_apRtpSock
[
2
];
//RTP端口,trackid idx 为数组下标
//RTP端口,trackid idx 为数组下标
Socket
::
Ptr
_apRtcpSock
[
2
];
//RTCP端口,trackid idx 为数组下标
Socket
::
Ptr
_rtp_sock
[
2
];
//RTCP端口,trackid idx 为数组下标
Socket
::
Ptr
_rtcp_sock
[
2
];
//rtsp鉴权相关
//rtsp鉴权相关
string
_
rtspMd5N
once
;
string
_
md5_n
once
;
string
_r
tspR
ealm
;
string
_realm
;
//rtsp info
//rtsp info
string
_s
trSession
;
string
_s
ession_id
;
u
nsigned
int
_uiCseq
=
1
;
u
int32_t
_cseq_send
=
1
;
string
_
strContentB
ase
;
string
_
content_b
ase
;
Rtsp
::
eRtpType
_
eT
ype
=
Rtsp
::
RTP_TCP
;
Rtsp
::
eRtpType
_
rtp_t
ype
=
Rtsp
::
RTP_TCP
;
/* 丢包率统计需要用到的参数 */
/* 丢包率统计需要用到的参数 */
uint16_t
_aui16FirstSeq
[
2
]
=
{
0
,
0
};
uint16_t
_rtp_seq_start
[
2
]
=
{
0
,
0
};
uint16_t
_aui16NowSeq
[
2
]
=
{
0
,
0
};
uint16_t
_rtp_seq_now
[
2
]
=
{
0
,
0
};
uint64_t
_aui64RtpRecv
[
2
]
=
{
0
,
0
};
uint64_t
_rtp_recv_count
[
2
]
=
{
0
,
0
};
//当前rtp时间戳
uint32_t
_stamp
[
2
]
=
{
0
,
0
};
//超时功能实现
//超时功能实现
Ticker
_rtp
T
icker
;
Ticker
_rtp
_recv_t
icker
;
std
::
shared_ptr
<
Timer
>
_p
PlayT
imer
;
std
::
shared_ptr
<
Timer
>
_p
lay_check_t
imer
;
std
::
shared_ptr
<
Timer
>
_
pRtpT
imer
;
std
::
shared_ptr
<
Timer
>
_
rtp_check_t
imer
;
//时间戳
//rtcp统计,trackid idx 为数组下标
Stamp
_stamp
[
2
];
RtcpCounter
_rtcp_counter
[
2
];
//rtcp发送时间,trackid idx 为数组下标
Ticker
_rtcp_send_ticker
[
2
];
//rtcp相关
RtcpCounter
_aRtcpCnt
[
2
];
//rtcp统计,trackid idx 为数组下标
Ticker
_aRtcpTicker
[
2
];
//rtcp发送时间,trackid idx 为数组下标
//是否为rtsp点播
bool
_is_play_back
;
//是否为性能测试模式
//是否为性能测试模式
bool
_benchmark_mode
=
false
;
bool
_benchmark_mode
=
false
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论