完善rtsp播放器推流udp端口创建机制

This commit is contained in:
xiongziliang 2019-07-11 12:12:33 +08:00
parent 6518398aa5
commit d0d730985f
4 changed files with 47 additions and 26 deletions

View File

@ -232,6 +232,29 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) {
sendSetup(0); sendSetup(0);
} }
//有必须的情况下创建udp端口
void RtspPlayer::createUdpSockIfNecessary(int track_idx){
auto &rtpSockRef = _apRtpSock[track_idx];
auto &rtcpSockRef = _apRtcpSock[track_idx];
if(!rtpSockRef){
rtpSockRef.reset(new Socket(getPoller()));
if (!rtpSockRef->bindUdpSock(0, get_local_ip().data())) {
rtpSockRef.reset();
throw std::runtime_error("open rtp sock failed");
}
}
if(!rtcpSockRef){
rtcpSockRef.reset(new Socket(getPoller()));
if (!rtcpSockRef->bindUdpSock(rtpSockRef->get_local_port() + 1, get_local_ip().data())) {
rtcpSockRef.reset();
throw std::runtime_error("open rtcp sock failed");
}
}
}
//发送SETUP命令 //发送SETUP命令
void RtspPlayer::sendSetup(unsigned int trackIndex) { void RtspPlayer::sendSetup(unsigned int trackIndex) {
_onHandshake = std::bind(&RtspPlayer::handleResSETUP,this, placeholders::_1,trackIndex); _onHandshake = std::bind(&RtspPlayer::handleResSETUP,this, placeholders::_1,trackIndex);
@ -247,16 +270,7 @@ void RtspPlayer::sendSetup(unsigned int trackIndex) {
} }
break; break;
case Rtsp::RTP_UDP: { case Rtsp::RTP_UDP: {
_apRtpSock[trackIndex].reset(new Socket(getPoller())); createUdpSockIfNecessary(trackIndex);
if (!_apRtpSock[trackIndex]->bindUdpSock(0, get_local_ip().data())) {
_apRtpSock[trackIndex].reset();
throw std::runtime_error("open rtp sock err");
}
_apRtcpSock[trackIndex].reset(new Socket(getPoller()));
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");
}
sendRtspRequest("SETUP",baseUrl,{"Transport", sendRtspRequest("SETUP",baseUrl,{"Transport",
StrPrinter << "RTP/AVP;unicast;client_port=" StrPrinter << "RTP/AVP;unicast;client_port="
<< _apRtpSock[trackIndex]->get_local_port() << "-" << _apRtpSock[trackIndex]->get_local_port() << "-"
@ -314,10 +328,8 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
SockUtil::joinMultiAddr(fd, multiAddr.data(),get_local_ip().data()); SockUtil::joinMultiAddr(fd, multiAddr.data(),get_local_ip().data());
} }
} else { } else {
if(!pRtpSockRef || !pRtcpSockRef){ createUdpSockIfNecessary(uiTrackIndex);
throw std::runtime_error("udp socket not created yet when rtp over udp"); //udp单播
}
//udp单播
struct sockaddr_in rtpto; struct sockaddr_in rtpto;
rtpto.sin_port = ntohs(rtp_port); rtpto.sin_port = ntohs(rtp_port);
rtpto.sin_family = AF_INET; rtpto.sin_family = AF_INET;

View File

@ -120,6 +120,7 @@ private:
void sendRtspRequest(const string &cmd, const string &url ,const StrCaseMap &header = StrCaseMap()); void sendRtspRequest(const string &cmd, const string &url ,const StrCaseMap &header = StrCaseMap());
void sendRtspRequest(const string &cmd, const string &url ,const std::initializer_list<string> &header); void sendRtspRequest(const string &cmd, const string &url ,const std::initializer_list<string> &header);
void sendReceiverReport(bool overTcp,int iTrackIndex); void sendReceiverReport(bool overTcp,int iTrackIndex);
void createUdpSockIfNecessary(int track_idx);
private: private:
string _strUrl; string _strUrl;
SdpParser _sdpParser; SdpParser _sdpParser;

View File

@ -242,6 +242,19 @@ bool RtspPusher::handleAuthenticationFailure(const string &paramsStr) {
return false; return false;
} }
//有必须的情况下创建udp端口
void RtspPusher::createUdpSockIfNecessary(int track_idx){
auto &rtpSockRef = _apUdpSock[track_idx];
if(!rtpSockRef){
rtpSockRef.reset(new Socket(getPoller()));
if (!rtpSockRef->bindUdpSock(0, get_local_ip().data())) {
rtpSockRef.reset();
throw std::runtime_error("open rtp sock failed");
}
}
}
void RtspPusher::sendSetup(unsigned int trackIndex) { void RtspPusher::sendSetup(unsigned int trackIndex) {
_onHandshake = std::bind(&RtspPusher::handleResSetup,this, placeholders::_1,trackIndex); _onHandshake = std::bind(&RtspPusher::handleResSetup,this, placeholders::_1,trackIndex);
auto &track = _aTrackInfo[trackIndex]; auto &track = _aTrackInfo[trackIndex];
@ -252,11 +265,7 @@ void RtspPusher::sendSetup(unsigned int trackIndex) {
} }
break; break;
case Rtsp::RTP_UDP: { case Rtsp::RTP_UDP: {
_apUdpSock[trackIndex].reset(new Socket(getPoller())); createUdpSockIfNecessary(trackIndex);
if (!_apUdpSock[trackIndex]->bindUdpSock(0, get_local_ip().data())) {
_apUdpSock[trackIndex].reset();
throw std::runtime_error("open udp sock err");
}
int port = _apUdpSock[trackIndex]->get_local_port(); int port = _apUdpSock[trackIndex]->get_local_port();
sendRtspRequest("SETUP",baseUrl,{"Transport",StrPrinter << "RTP/AVP;unicast;client_port=" << port << "-" << port + 1}); sendRtspRequest("SETUP",baseUrl,{"Transport",StrPrinter << "RTP/AVP;unicast;client_port=" << port << "-" << port + 1});
} }
@ -266,6 +275,7 @@ void RtspPusher::sendSetup(unsigned int trackIndex) {
} }
} }
void RtspPusher::handleResSetup(const Parser &parser, unsigned int uiTrackIndex) { void RtspPusher::handleResSetup(const Parser &parser, unsigned int uiTrackIndex) {
if (parser.Url() != "200") { if (parser.Url() != "200") {
throw std::runtime_error( throw std::runtime_error(
@ -278,7 +288,7 @@ void RtspPusher::handleResSetup(const Parser &parser, unsigned int uiTrackIndex)
} }
auto strTransport = parser["Transport"]; auto strTransport = parser["Transport"];
if(strTransport.find("TCP") != string::npos){ if(strTransport.find("TCP") != string::npos || strTransport.find("interleaved") != string::npos){
_eType = Rtsp::RTP_TCP; _eType = 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()); _aTrackInfo[uiTrackIndex]->_interleaved = atoi(interleaved.data());
@ -286,19 +296,15 @@ void RtspPusher::handleResSetup(const Parser &parser, unsigned int uiTrackIndex)
throw std::runtime_error("SETUP rtsp pusher can not support multicast!"); throw std::runtime_error("SETUP rtsp pusher can not support multicast!");
}else{ }else{
_eType = Rtsp::RTP_UDP; _eType = Rtsp::RTP_UDP;
createUdpSockIfNecessary(uiTrackIndex);
const char *strPos = "server_port=" ; const char *strPos = "server_port=" ;
auto port_str = FindField((strTransport + ";").data(), strPos, ";"); auto port_str = FindField((strTransport + ";").data(), strPos, ";");
uint16_t port = atoi(FindField(port_str.data(), NULL, "-").data()); uint16_t port = atoi(FindField(port_str.data(), NULL, "-").data());
auto &pUdpSockRef = _apUdpSock[uiTrackIndex];
if(!pUdpSockRef){
pUdpSockRef.reset(new Socket(getPoller()));
}
struct sockaddr_in rtpto; struct sockaddr_in rtpto;
rtpto.sin_port = ntohs(port); rtpto.sin_port = ntohs(port);
rtpto.sin_family = AF_INET; rtpto.sin_family = AF_INET;
rtpto.sin_addr.s_addr = inet_addr(get_peer_ip().data()); rtpto.sin_addr.s_addr = inet_addr(get_peer_ip().data());
pUdpSockRef->setSendPeerAddr((struct sockaddr *)&(rtpto)); _apUdpSock[uiTrackIndex]->setSendPeerAddr((struct sockaddr *)&(rtpto));
} }
RtspSplitter::enableRecvRtp(_eType == Rtsp::RTP_TCP); RtspSplitter::enableRecvRtp(_eType == Rtsp::RTP_TCP);

View File

@ -65,6 +65,8 @@ private:
void sendRtpPacket(const RtpPacket::Ptr & pkt) ; void sendRtpPacket(const RtpPacket::Ptr & pkt) ;
void sendRtspRequest(const string &cmd, const string &url ,const StrCaseMap &header = StrCaseMap(),const string &sdp = "" ); void sendRtspRequest(const string &cmd, const string &url ,const StrCaseMap &header = StrCaseMap(),const string &sdp = "" );
void sendRtspRequest(const string &cmd, const string &url ,const std::initializer_list<string> &header,const string &sdp = ""); void sendRtspRequest(const string &cmd, const string &url ,const std::initializer_list<string> &header,const string &sdp = "");
void createUdpSockIfNecessary(int track_idx);
private: private:
//rtsp鉴权相关 //rtsp鉴权相关
string _rtspMd5Nonce; string _rtspMd5Nonce;