From bf7363714dc86a7615d257646c151955d449c6b1 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Thu, 22 Aug 2019 15:23:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rtsp/RtspSession.cpp | 31 ++++++------- src/Rtsp/RtspSession.h | 94 +++++++++++++++++++++++++++++----------- 2 files changed, 85 insertions(+), 40 deletions(-) diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index a7449920..2cacd699 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -153,24 +153,24 @@ void RtspSession::onWholeRtspPacket(Parser &parser) { } typedef void (RtspSession::*rtsp_request_handler)(const Parser &parser); - static unordered_map s_handler_map; + static unordered_map s_cmd_functions; static onceToken token( []() { - s_handler_map.emplace("OPTIONS",&RtspSession::handleReq_Options); - s_handler_map.emplace("DESCRIBE",&RtspSession::handleReq_Describe); - s_handler_map.emplace("ANNOUNCE",&RtspSession::handleReq_ANNOUNCE); - s_handler_map.emplace("RECORD",&RtspSession::handleReq_RECORD); - s_handler_map.emplace("SETUP",&RtspSession::handleReq_Setup); - s_handler_map.emplace("PLAY",&RtspSession::handleReq_Play); - s_handler_map.emplace("PAUSE",&RtspSession::handleReq_Pause); - s_handler_map.emplace("TEARDOWN",&RtspSession::handleReq_Teardown); - s_handler_map.emplace("GET",&RtspSession::handleReq_Get); - s_handler_map.emplace("POST",&RtspSession::handleReq_Post); - s_handler_map.emplace("SET_PARAMETER",&RtspSession::handleReq_SET_PARAMETER); - s_handler_map.emplace("GET_PARAMETER",&RtspSession::handleReq_SET_PARAMETER); + s_cmd_functions.emplace("OPTIONS",&RtspSession::handleReq_Options); + s_cmd_functions.emplace("DESCRIBE",&RtspSession::handleReq_Describe); + s_cmd_functions.emplace("ANNOUNCE",&RtspSession::handleReq_ANNOUNCE); + s_cmd_functions.emplace("RECORD",&RtspSession::handleReq_RECORD); + s_cmd_functions.emplace("SETUP",&RtspSession::handleReq_Setup); + s_cmd_functions.emplace("PLAY",&RtspSession::handleReq_Play); + s_cmd_functions.emplace("PAUSE",&RtspSession::handleReq_Pause); + s_cmd_functions.emplace("TEARDOWN",&RtspSession::handleReq_Teardown); + s_cmd_functions.emplace("GET",&RtspSession::handleReq_Get); + s_cmd_functions.emplace("POST",&RtspSession::handleReq_Post); + s_cmd_functions.emplace("SET_PARAMETER",&RtspSession::handleReq_SET_PARAMETER); + s_cmd_functions.emplace("GET_PARAMETER",&RtspSession::handleReq_SET_PARAMETER); }, []() {}); - auto it = s_handler_map.find(strCmd); - if (it == s_handler_map.end()) { + auto it = s_cmd_functions.find(strCmd); + if (it == s_cmd_functions.end()) { sendRtspResponse("403 Forbidden"); shutdown(SockException(Err_shutdown,StrPrinter << "403 Forbidden:" << strCmd)); return; @@ -918,6 +918,7 @@ inline void RtspSession::send_NotAcceptable() { void RtspSession::onRtpSorted(const RtpPacket::Ptr &rtppt, int trackidx) { + _pushSrc->onWrite(rtppt, false); } inline void RtspSession::onRcvPeerUdpData(int intervaled, const Buffer::Ptr &pBuf, const struct sockaddr& addr) { diff --git a/src/Rtsp/RtspSession.h b/src/Rtsp/RtspSession.h index 51561c6c..d768d499 100644 --- a/src/Rtsp/RtspSession.h +++ b/src/Rtsp/RtspSession.h @@ -76,6 +76,7 @@ public: RtspSession(const Socket::Ptr &pSock); virtual ~RtspSession(); + ////TcpSession override//// void onRecv(const Buffer::Ptr &pBuf) override; void onError(const SockException &err) override; void onManager() override; @@ -119,59 +120,101 @@ protected: */ virtual void onRtcpPacket(int iTrackidx, SdpTrack::Ptr &track, unsigned char *pucData, unsigned int uiLen); private: - void handleReq_Options(const Parser &parser); //处理options方法 - void handleReq_Describe(const Parser &parser); //处理describe方法 - void handleReq_ANNOUNCE(const Parser &parser); //处理options方法 - void handleReq_RECORD(const Parser &parser); //处理options方法 - void handleReq_Setup(const Parser &parser); //处理setup方法 - void handleReq_Play(const Parser &parser); //处理play方法 - void handleReq_Pause(const Parser &parser); //处理pause方法 - void handleReq_Teardown(const Parser &parser); //处理teardown方法 - void handleReq_Get(const Parser &parser); //处理Get方法 - void handleReq_Post(const Parser &parser); //处理Post方法 - void handleReq_SET_PARAMETER(const Parser &parser); //处理SET_PARAMETER方法 + //处理options方法,获取服务器能力 + void handleReq_Options(const Parser &parser); + //处理describe方法,请求服务器rtsp sdp信息 + void handleReq_Describe(const Parser &parser); + //处理ANNOUNCE方法,请求推流,附带sdp + void handleReq_ANNOUNCE(const Parser &parser); + //处理record方法,开始推流 + void handleReq_RECORD(const Parser &parser); + //处理setup方法,播放和推流协商rtp传输方式用 + void handleReq_Setup(const Parser &parser); + //处理play方法,开始或恢复播放 + void handleReq_Play(const Parser &parser); + //处理pause方法,暂停播放 + void handleReq_Pause(const Parser &parser); + //处理teardown方法,结束播放 + void handleReq_Teardown(const Parser &parser); + //处理Get方法,rtp over http才用到 + void handleReq_Get(const Parser &parser); + //处理Post方法,rtp over http才用到 + void handleReq_Post(const Parser &parser); + //处理SET_PARAMETER、GET_PARAMETER方法,一般用于心跳 + void handleReq_SET_PARAMETER(const Parser &parser); - void inline send_StreamNotFound(); //rtsp资源未找到 - void inline send_UnsupportedTransport(); //不支持的传输模式 - void inline send_SessionNotFound(); //会话id错误 - void inline send_NotAcceptable(); //rtsp同时播放数限制 + //rtsp资源未找到 + void inline send_StreamNotFound(); + //不支持的传输模式 + void inline send_UnsupportedTransport(); + //会话id错误 + void inline send_SessionNotFound(); + //一般rtsp服务器打开端口失败时触发 + void inline send_NotAcceptable(); + //ssrc转字符串 inline string printSSRC(uint32_t ui32Ssrc); + + //获取track下标 inline int getTrackIndexByTrackType(TrackType type); inline int getTrackIndexByControlSuffix(const string &controlSuffix); inline int getTrackIndexByInterleaved(int interleaved); + //一般用于接收udp打洞包,也用于rtsp推流 inline void onRcvPeerUdpData(int intervaled, const Buffer::Ptr &pBuf, const struct sockaddr &addr); + //配合onRcvPeerUdpData使用 inline void startListenPeerUdpData(int iTrackIdx); - //认证相关 + ////rtsp专有认证相关//// + //认证成功 void onAuthSuccess(); + //认证失败 void onAuthFailed(const string &realm,const string &why,bool close = true); + //开始走rtsp专有认证流程 void onAuthUser(const string &realm,const string &authorization); + //校验base64方式的认证加密 void onAuthBasic(const string &realm,const string &strBase64); + //校验md5方式的认证加密 void onAuthDigest(const string &realm,const string &strMd5); + //发送rtp给客户端 void sendRtpPacket(const RtpPacket::Ptr &pkt); + //回复客户端 bool sendRtspResponse(const string &res_code,const std::initializer_list &header, const string &sdp = "" , const char *protocol = "RTSP/1.0"); bool sendRtspResponse(const string &res_code,const StrCaseMap &header = StrCaseMap(), const string &sdp = "",const char *protocol = "RTSP/1.0"); + //服务器发送rtcp void sendSenderReport(bool overTcp,int iTrackIndex); private: + //用于判断客户端是否超时 Ticker _ticker; + //收到的seq,回复时一致 int _iCseq = 0; + //ContentBase string _strContentBase; + //推流端发送的sdp或播放端请求的sdp string _strSdp; + //Session号 string _strSession; + //是否第一次播放,第一次播放需要鉴权,第二次播放属于暂停恢复 bool _bFirstPlay = true; + //url解析后保存的相关信息 MediaInfo _mediaInfo; + //rtsp播放器绑定的直播源 std::weak_ptr _pMediaSrc; + //直播源读取器 RingBuffer::RingReader::Ptr _pRtpReader; + //推流或拉流客户端采用的rtp传输方式 Rtsp::eRtpType _rtpType = Rtsp::RTP_Invalid; + //sdp里面有效的track,包含音频或视频 vector _aTrackInfo; - - //RTP over udp - Socket::Ptr _apRtpSock[2]; //RTP端口,trackid idx 为数组下标 - Socket::Ptr _apRtcpSock[2];//RTCP端口,trackid idx 为数组下标 + ////////RTP over udp//////// + //RTP端口,trackid idx 为数组下标 + Socket::Ptr _apRtpSock[2]; + //RTCP端口,trackid idx 为数组下标 + Socket::Ptr _apRtcpSock[2]; + //标记是否收到播放的udp打洞包,收到播放的udp打洞包后才能知道其外网udp端口号 unordered_set _udpSockConnected; - //RTP over udp_multicast + ////////RTP over udp_multicast//////// + //共享的rtp组播对象 RtpBroadCaster::Ptr _pBrdcaster; //登录认证 @@ -184,13 +227,14 @@ private: //一次发送 get 一次发送post,需要通过x-sessioncookie关联起来 string _http_x_sessioncookie; function _onRecv; + //是否开始发送rtp bool _enableSendRtp; - //rtsp推流相关 RtspToRtmpMediaSource::Ptr _pushSrc; - - RtcpCounter _aRtcpCnt[2]; //rtcp统计,trackid idx 为数组下标 - Ticker _aRtcpTicker[2]; //rtcp发送时间,trackid idx 为数组下标 + //rtcp统计,trackid idx 为数组下标 + RtcpCounter _aRtcpCnt[2]; + //rtcp发送时间,trackid idx 为数组下标 + Ticker _aRtcpTicker[2]; }; /**