From 3d16f55446472677f5a795df262e98431a1279e7 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Wed, 8 May 2019 16:19:00 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E7=BD=AErtcp=E7=AB=AF=E5=8F=A3?= =?UTF-8?q?=E7=9B=AE=E6=A0=87=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rtsp/RtspPlayer.cpp | 2 +- src/Rtsp/RtspSession.cpp | 45 +++++++++++++++++++--------------------- src/Rtsp/RtspSession.h | 5 ++--- 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/Rtsp/RtspPlayer.cpp b/src/Rtsp/RtspPlayer.cpp index 0ab62e68..926ecb71 100644 --- a/src/Rtsp/RtspPlayer.cpp +++ b/src/Rtsp/RtspPlayer.cpp @@ -254,7 +254,7 @@ void RtspPlayer::sendSetup(unsigned int trackIndex) { throw std::runtime_error("open rtp sock err"); } _apRtcpSock[trackIndex].reset(new Socket()); - if (!_apRtcpSock[trackIndex]->bindUdpSock(0, get_local_ip().data())) { + if (!_apRtcpSock[trackIndex]->bindUdpSock(_apRtpSock[trackIndex]->get_local_port() + 1, get_local_ip().data())) { _apRtcpSock[trackIndex].reset(); throw std::runtime_error("open rtcp sock err"); } diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index 5a333f0a..feb3a73a 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -605,13 +605,24 @@ bool RtspSession::handleReq_Setup(const Parser &parser) { _apRtcpSock[trackIdx] = pSockRtcp; //设置客户端内网端口信息 string strClientPort = FindField(parser["Transport"].data(), "client_port=", NULL); - uint16_t ui16PeerPort = atoi( FindField(strClientPort.data(), NULL, "-").data()); - struct sockaddr_in peerAddr; + uint16_t ui16RtpPort = atoi( FindField(strClientPort.data(), NULL, "-").data()); + uint16_t ui16RtcpPort = atoi( FindField(strClientPort.data(), "-" , NULL).data()); + + struct sockaddr_in peerAddr; + //设置rtp发送目标地址 peerAddr.sin_family = AF_INET; - peerAddr.sin_port = htons(ui16PeerPort); + peerAddr.sin_port = htons(ui16RtpPort); peerAddr.sin_addr.s_addr = inet_addr(get_peer_ip().data()); bzero(&(peerAddr.sin_zero), sizeof peerAddr.sin_zero); pSockRtp->setSendPeerAddr((struct sockaddr *)(&peerAddr)); + + //设置rtcp发送目标地址 + peerAddr.sin_family = AF_INET; + peerAddr.sin_port = htons(ui16RtcpPort); + peerAddr.sin_addr.s_addr = inet_addr(get_peer_ip().data()); + bzero(&(peerAddr.sin_zero), sizeof peerAddr.sin_zero); + pSockRtcp->setSendPeerAddr((struct sockaddr *)(&peerAddr)); + //尝试获取客户端nat映射地址 startListenPeerUdpData(trackIdx); //InfoL << "分配端口:" << srv_port; @@ -1013,30 +1024,16 @@ inline void RtspSession::onRcvPeerUdpData(int intervaled, const Buffer::Ptr &pBu if(intervaled % 2 == 0){ if(_pushSrc){ handleOneRtp(intervaled / 2,_aTrackInfo[intervaled / 2],( unsigned char *)pBuf->data(),pBuf->size()); - } - - //这是rtp探测包 - if(!_bGotAllPeerUdp){ - //还没有获取完整的rtp探测包 - if(SockUtil::in_same_lan(get_local_ip().data(),get_peer_ip().data())){ - //在内网中,客户端上报的端口号是真实的,所以我们忽略udp打洞包 - _bGotAllPeerUdp = true; - return; - } - //设置真实的客户端nat映射端口号 - _apRtpSock[intervaled / 2]->setSendPeerAddr(&addr); - _abGotPeerUdp[intervaled / 2] = true; - _bGotAllPeerUdp = true;//先假设获取到完整的rtp探测包 - for (unsigned int i = 0; i < _aTrackInfo.size(); i++) { - if (!_abGotPeerUdp[i]) { - //还有track没获取到rtp探测包 - _bGotAllPeerUdp = false; - break; - } - } + }else if(_udpSockConnected.count(intervaled)){ + //这是rtp打洞包 + _udpSockConnected.emplace(intervaled); + _apRtpSock[intervaled / 2]->setSendPeerAddr(&addr); } }else{ //rtcp包 + if(_udpSockConnected.count(intervaled)){ + _apRtcpSock[(intervaled - 1) / 2]->setSendPeerAddr(&addr); + } onRecvRtcp((intervaled - 1) / 2,_aTrackInfo[(intervaled - 1) / 2],( unsigned char *)pBuf->data(),pBuf->size()); } } diff --git a/src/Rtsp/RtspSession.h b/src/Rtsp/RtspSession.h index f955b223..6c5c4376 100644 --- a/src/Rtsp/RtspSession.h +++ b/src/Rtsp/RtspSession.h @@ -29,6 +29,7 @@ #include #include +#include #include #include "Util/util.h" #include "Util/logger.h" @@ -173,11 +174,9 @@ private: vector _aTrackInfo; //RTP over udp - bool _bGotAllPeerUdp = false; - bool _abGotPeerUdp[2] = { false, false }; //获取客户端udp端口计数 Socket::Ptr _apRtpSock[2]; //RTP端口,trackid idx 为数组下标 Socket::Ptr _apRtcpSock[2];//RTCP端口,trackid idx 为数组下标 - + unordered_set _udpSockConnected; //RTP over udp_multicast RtpBroadCaster::Ptr _pBrdcaster;