From 6fe90fe4ba1c82272a5c30d5b27ffc18b652b303 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Fri, 26 Oct 2018 09:56:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=BF=E6=8D=A2sdp=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Common/Factory.cpp | 14 +++---- src/Common/Factory.h | 2 +- src/Rtsp/Rtsp.cpp | 73 ++++++++------------------------ src/Rtsp/Rtsp.h | 36 +++++++--------- src/Rtsp/RtspMediaSource.h | 2 +- src/Rtsp/RtspPlayer.cpp | 78 ++++++++++++++++------------------- src/Rtsp/RtspPlayer.h | 11 ++--- src/Rtsp/RtspPlayerImp.h | 4 +- src/Rtsp/RtspSession.cpp | 39 ++++++++++-------- src/Rtsp/RtspSession.h | 9 ++-- src/RtspMuxer/RtspDemuxer.cpp | 52 +++++++++++++---------- src/RtspMuxer/RtspDemuxer.h | 6 ++- 12 files changed, 147 insertions(+), 179 deletions(-) diff --git a/src/Common/Factory.cpp b/src/Common/Factory.cpp index 0d5eee29..77bc8b83 100644 --- a/src/Common/Factory.cpp +++ b/src/Common/Factory.cpp @@ -66,11 +66,11 @@ Sdp::Ptr Factory::getSdpByTrack(const Track::Ptr &track) { } -Track::Ptr Factory::getTrackBySdp(const string &sdp) { - if (strcasestr(sdp.data(), "mpeg4-generic") != nullptr) { - string aac_cfg_str = FindField(sdp.c_str(), "config=", "\r\n"); +Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { + if (strcasestr(track->_codec.data(), "mpeg4-generic") != nullptr) { + string aac_cfg_str = FindField(track->_fmtp.c_str(), "config=", "\r\n"); if (aac_cfg_str.size() != 4) { - aac_cfg_str = FindField(sdp.c_str(), "config=", ";"); + aac_cfg_str = FindField(track->_fmtp.c_str(), "config=", ";"); } if (aac_cfg_str.size() != 4) { //延后获取adts头 @@ -91,8 +91,8 @@ Track::Ptr Factory::getTrackBySdp(const string &sdp) { return std::make_shared(aac_cfg); } - if (strcasestr(sdp.data(), "h264") != nullptr) { - string sps_pps = FindField(sdp.c_str(), "sprop-parameter-sets=", "\r\n"); + if (strcasestr(track->_codec.data(), "h264") != nullptr) { + string sps_pps = FindField(track->_fmtp.c_str(), "sprop-parameter-sets=", "\r\n"); if(sps_pps.empty()){ return std::make_shared(); } @@ -107,7 +107,7 @@ Track::Ptr Factory::getTrackBySdp(const string &sdp) { return std::make_shared(sps,pps,0,0); } - WarnL << "暂不支持该sdp:" << sdp; + WarnL << "暂不支持该sdp:" << track->_codec << " " << track->_fmtp; return nullptr; } diff --git a/src/Common/Factory.h b/src/Common/Factory.h index 407190a6..9db907c4 100644 --- a/src/Common/Factory.h +++ b/src/Common/Factory.h @@ -53,7 +53,7 @@ public: /** * 根据sdp生成Track对象 */ - static Track::Ptr getTrackBySdp(const string &sdp); + static Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track); /** * 根据Track生成SDP对象 diff --git a/src/Rtsp/Rtsp.cpp b/src/Rtsp/Rtsp.cpp index 168e75a4..4804ea9c 100644 --- a/src/Rtsp/Rtsp.cpp +++ b/src/Rtsp/Rtsp.cpp @@ -110,13 +110,13 @@ void SdpAttr::load(const string &sdp) { for (auto &pr : _track_map) { auto &track = *pr.second; if (pr.first == "") { - track._type = TrackTitle; + track.type = TrackTitle; } else if (pr.first == "video") { - track._type = TrackVideo; + track.type = TrackVideo; } else if (pr.first == "audio") { - track._type = TrackAudio; + track.type = TrackAudio; } else { - track._type = TrackInvalid; + track.type = TrackInvalid; } auto it = track._attr.find("range"); @@ -153,6 +153,8 @@ void SdpAttr::load(const string &sdp) { it = track._attr.find("control"); if(it != track._attr.end()) { track._control = it->second; + auto surffix = string("/") + track._control; + track._control_surffix = surffix.substr(1 + surffix.rfind('/')); } } } @@ -163,64 +165,25 @@ bool SdpAttr::available() const { SdpTrack::Ptr SdpAttr::getTrack(TrackType type) const { for (auto &pr : _track_map){ - if(pr.second->_type == type){ + if(pr.second->type == type){ return pr.second; } } return nullptr; } -int parserSDP(const string& sdp, RtspTrack Track[2]) { - int track_cnt = 0; - string::size_type pos_head = 0; - while ((pos_head = sdp.find("m=",pos_head)) != string::npos ) { - auto pos_end = sdp.find("m=", pos_head + 2); - if (pos_end == string::npos) { - pos_end = sdp.size(); - } - auto sdp_mid = sdp.substr(pos_head, pos_end - pos_head); - pos_head = pos_end; - Track[track_cnt].trackSdp = sdp_mid; - Track[track_cnt].inited = false; - Track[track_cnt].PT = atoi(FindField(sdp_mid.c_str(), "a=rtpmap:", " ").c_str()); - auto control = string("/") + trim(FindField(sdp_mid.c_str(), "a=control:", "\n")); - Track[track_cnt].controlSuffix = control.substr(1 + control.rfind('/')); - - if (sdp_mid.find("m=video") != string::npos) { - //视频通道 - Track[track_cnt].type = TrackVideo; - } else if (sdp_mid.find("m=audio") != string::npos) { - //音频通道 - Track[track_cnt].type = TrackAudio; - } else { - //不识别的track - continue; - } - track_cnt++; +vector SdpAttr::getAvailableTrack() const { + vector ret; + auto video = getTrack(TrackVideo); + if(video){ + ret.emplace_back(video); } - return track_cnt; + auto audio = getTrack(TrackAudio); + if(audio){ + ret.emplace_back(audio); + } + return ret; } -static onceToken s_token([](){ - string str = "v=0\n" - "o=- 1001 1 IN IP4 192.168.0.22\n" - "s=VCP IPC Realtime stream\n" - "a=range:npt=0-\n" - "m=video 0 RTP/AVP 105\n" - "c=IN IP4 192.168.0.22\n" - "a=control:rtsp://192.168.0.22/media/video1/video\n" - "a=rtpmap:105 H264/90000\n" - "a=fmtp:105 profile-level-id=64001f; packetization-mode=1; sprop-parameter-sets=Z2QAH6wrUCgC3QgAAB9AAAYahCAA,aO4xsg==\n" - "a=recvonly\n" - "m=application 0 RTP/AVP 107\n" - "c=IN IP4 192.168.0.22\n" - "a=control:rtsp://192.168.0.22/media/video1/metadata\n" - "a=rtpmap:107 vnd.onvif.metadata/90000\n" - "a=fmtp:107 DecoderTag=h3c-v3 RTCP=0\n" - "a=recvonly"; - RtspTrack track[2]; - parserSDP(str,track); - SdpAttr attr(str); - track[0].inited=true; -}); + diff --git a/src/Rtsp/Rtsp.h b/src/Rtsp/Rtsp.h index b4266adb..bdd466cd 100644 --- a/src/Rtsp/Rtsp.h +++ b/src/Rtsp/Rtsp.h @@ -62,34 +62,31 @@ public: int _samplerate; string _fmtp; string _control; - TrackType _type; + string _control_surffix; + TrackType type; +public: + uint8_t interleaved = 0; + bool inited = false; + uint32_t ssrc = 0; + uint16_t seq = 0; + uint32_t timeStamp = 0; }; class SdpAttr { public: typedef std::shared_ptr Ptr; - SdpAttr(const string &sdp){load(sdp);}; + SdpAttr(){} + SdpAttr(const string &sdp){load(sdp);} ~SdpAttr(){} - void load(const string &sdp); - SdpTrack::Ptr getTrack(TrackType type) const; - bool available() const ; + void load(const string &sdp); + bool available() const ; + + SdpTrack::Ptr getTrack(TrackType type) const; + vector getAvailableTrack() const; private: - map _track_map; + map _track_map; }; -class RtspTrack{ -public: - uint8_t PT; - uint8_t interleaved; - TrackType type = TrackInvalid; - string trackSdp; - string controlSuffix; - bool inited; - uint32_t ssrc = 0; - uint16_t seq; - uint32_t timeStamp; - uint32_t sampleRate; -}; class RtcpCounter { public: @@ -99,7 +96,6 @@ public: }; string FindField(const char* buf, const char* start, const char *end,int bufSize = 0 ); -int parserSDP(const string& sdp, RtspTrack Track[2]); struct StrCaseCompare { diff --git a/src/Rtsp/RtspMediaSource.h b/src/Rtsp/RtspMediaSource.h index b4c37e40..136208a4 100644 --- a/src/Rtsp/RtspMediaSource.h +++ b/src/Rtsp/RtspMediaSource.h @@ -95,7 +95,7 @@ public: _pRing->write(rtppt,keyPos); } protected: - unordered_map _mapTracks; + unordered_map _mapTracks; string _strSdp; //媒体描述信息 RingType::Ptr _pRing; //rtp环形缓冲 }; diff --git a/src/Rtsp/RtspPlayer.cpp b/src/Rtsp/RtspPlayer.cpp index d0b34692..9ad850b6 100644 --- a/src/Rtsp/RtspPlayer.cpp +++ b/src/Rtsp/RtspPlayer.cpp @@ -70,7 +70,7 @@ void RtspPlayer::teardown(){ erase(kRtspMd5Nonce); erase(kRtspRealm); - _uiTrackCnt = 0; + _aTrackInfo.clear(); _onHandshake = nullptr; _uiRtpBufLen = 0; _strSession.clear(); @@ -276,17 +276,21 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) { } //解析sdp - _uiTrackCnt = parserSDP(strSdp, _aTrackInfo); - for (unsigned int i=0; i<_uiTrackCnt; i++) { - _aTrackInfo[i].ssrc=0; - _aui32SsrcErrorCnt[i]=0; - } - if (!_uiTrackCnt) { + _sdpAttr.load(strSdp); + _aTrackInfo = _sdpAttr.getAvailableTrack(); + + if (_aTrackInfo.empty()) { throw std::runtime_error("解析SDP失败"); } - if (!onCheckSDP(strSdp, _aTrackInfo, _uiTrackCnt)) { + if (!onCheckSDP(strSdp, _sdpAttr)) { throw std::runtime_error("onCheckSDP faied"); } + + CLEAR_ARR(_aui32SsrcErrorCnt) + for (auto &track : _aTrackInfo) { + track->ssrc=0; + } + sendSetup(0); } //发送SETUP命令 @@ -294,11 +298,11 @@ bool RtspPlayer::sendSetup(unsigned int trackIndex) { _onHandshake = std::bind(&RtspPlayer::handleResSETUP,this, placeholders::_1,trackIndex); auto &track = _aTrackInfo[trackIndex]; - auto baseUrl = _strContentBase + "/" + track.controlSuffix; + auto baseUrl = _strContentBase + "/" + track->_control_surffix; switch (_eType) { case RTP_TCP: { StrCaseMap header; - header["Transport"] = StrPrinter << "RTP/AVP/TCP;unicast;interleaved=" << track.type * 2 << "-" << track.type * 2 + 1; + header["Transport"] = StrPrinter << "RTP/AVP/TCP;unicast;interleaved=" << track->type * 2 << "-" << track->type * 2 + 1; return sendRtspRequest("SETUP",baseUrl,header); } break; @@ -348,7 +352,7 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex) if(_eType == RTP_TCP) { string interleaved = FindField( FindField((strTransport + ";").c_str(), "interleaved=", ";").c_str(), NULL, "-"); - _aTrackInfo[uiTrackIndex].interleaved = atoi(interleaved.c_str()); + _aTrackInfo[uiTrackIndex]->interleaved = atoi(interleaved.c_str()); }else{ const char *strPos = (_eType == RTP_MULTICAST ? "port=" : "server_port=") ; auto port_str = FindField((strTransport + ";").c_str(), strPos, ";"); @@ -377,13 +381,13 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex) } } - if (uiTrackIndex < _uiTrackCnt - 1) { + if (uiTrackIndex < _aTrackInfo.size() - 1) { //需要继续发送SETUP命令 sendSetup(uiTrackIndex + 1); return; } - for (unsigned int i = 0; i < _uiTrackCnt && _eType != RTP_TCP; i++) { + for (unsigned int i = 0; i < _aTrackInfo.size() && _eType != RTP_TCP; i++) { auto &pUdpSockRef = _apUdpSock[i]; if(!pUdpSockRef){ continue; @@ -436,13 +440,8 @@ bool RtspPlayer::sendPause(bool bPause,float fTime){ _aNowStampTicker[0].resetTime(); _aNowStampTicker[1].resetTime(); float iTimeInc = fTime - getProgressTime(); - for(unsigned int i = 0 ;i < _uiTrackCnt ;i++){ - if (_aTrackInfo[i].type == TrackVideo) { - _adFistStamp[i] = _adNowStamp[i] + iTimeInc * 90000.0; - }else if (_aTrackInfo[i].type == TrackAudio){ - //todo(xzl) 修复此处 -// _adFistStamp[i] = _adNowStamp[i] + iTimeInc * getAudioSampleRate(); - } + for(unsigned int i = 0 ;i < _aTrackInfo.size() ;i++){ + _adFistStamp[i] = _adNowStamp[i] + iTimeInc * _aTrackInfo[i]->_samplerate; _adNowStamp[i] = _adFistStamp[i]; } _fSeekTo = fTime; @@ -590,7 +589,7 @@ bool RtspPlayer::handleOneRtp(int iTrackidx, unsigned char *pucData, unsigned in auto &track = _aTrackInfo[iTrackidx]; auto pt_ptr=_pktPool.obtain(); auto &rtppt=*pt_ptr; - rtppt.interleaved = track.interleaved; + rtppt.interleaved = track->interleaved; rtppt.length = uiLen + 4; rtppt.mark = pucData[1] >> 7; @@ -604,15 +603,15 @@ bool RtspPlayer::handleOneRtp(int iTrackidx, unsigned char *pucData, unsigned in //ssrc memcpy(&rtppt.ssrc,pucData+8,4);//内存对齐 rtppt.ssrc = ntohl(rtppt.ssrc); - rtppt.type = track.type; - if (track.ssrc == 0) { - track.ssrc = rtppt.ssrc; + rtppt.type = track->type; + if (track->ssrc == 0) { + track->ssrc = rtppt.ssrc; //保存SSRC - } else if (track.ssrc != rtppt.ssrc) { + } else if (track->ssrc != rtppt.ssrc) { //ssrc错误 WarnL << "ssrc错误"; if (_aui32SsrcErrorCnt[iTrackidx]++ > 10) { - track.ssrc = rtppt.ssrc; + track->ssrc = rtppt.ssrc; WarnL << "ssrc更换!"; } return false; @@ -694,7 +693,7 @@ float RtspPlayer::getRtpLossRate(int iTrackType) const{ if(iTrackIdx == -1){ uint64_t totalRecv = 0; uint64_t totalSend = 0; - for (unsigned int i = 0; i < _uiTrackCnt; i++) { + for (unsigned int i = 0; i < _aTrackInfo.size(); i++) { totalRecv += _aui64RtpRecv[i]; totalSend += (_aui16NowSeq[i] - _aui16FirstSeq[i] + 1); } @@ -713,15 +712,8 @@ float RtspPlayer::getRtpLossRate(int iTrackType) const{ float RtspPlayer::getProgressTime() const{ double iTime[2] = {0,0}; - for(unsigned int i = 0 ;i < _uiTrackCnt ;i++){ - if (_aTrackInfo[i].type == TrackVideo) { - iTime[i] = (_adNowStamp[i] - _adFistStamp[i]) / 90000.0; - }else if (_aTrackInfo[i].type == TrackAudio){ - //todo(xzl) 修复此处 -#if 0 - iTime[i] = (_adNowStamp[i] - _adFistStamp[i]) / getAudioSampleRate(); -#endif - } + for(unsigned int i = 0 ;i < _aTrackInfo.size() ;i++){ + iTime[i] = (_adNowStamp[i] - _adFistStamp[i]) / _aTrackInfo[i]->_samplerate; } return _fSeekTo + MAX(iTime[0],iTime[1]); } @@ -785,7 +777,7 @@ void RtspPlayer::onShutdown_l(const SockException &ex) { _pBeatTimer.reset(); onShutdown(ex); } -void RtspPlayer::onRecvRTP_l(const RtpPacket::Ptr &pRtppt, const RtspTrack &track) { +void RtspPlayer::onRecvRTP_l(const RtpPacket::Ptr &pRtppt, const SdpTrack::Ptr &track) { _rtpTicker.resetTime(); onRecvRTP(pRtppt,track); } @@ -814,16 +806,16 @@ void RtspPlayer::onPlayResult_l(const SockException &ex) { } int RtspPlayer::getTrackIndexByControlSuffix(const string &controlSuffix) const{ - for (unsigned int i = 0; i < _uiTrackCnt; i++) { - if (_aTrackInfo[i].controlSuffix == controlSuffix) { + for (unsigned int i = 0; i < _aTrackInfo.size(); i++) { + if (_aTrackInfo[i]->_control_surffix == controlSuffix) { return i; } } return -1; } int RtspPlayer::getTrackIndexByInterleaved(int interleaved) const{ - for (unsigned int i = 0; i < _uiTrackCnt; i++) { - if (_aTrackInfo[i].interleaved == interleaved) { + for (unsigned int i = 0; i < _aTrackInfo.size(); i++) { + if (_aTrackInfo[i]->interleaved == interleaved) { return i; } } @@ -831,8 +823,8 @@ int RtspPlayer::getTrackIndexByInterleaved(int interleaved) const{ } int RtspPlayer::getTrackIndexByTrackType(TrackType trackType) const { - for (unsigned int i = 0; i < _uiTrackCnt; i++) { - if (_aTrackInfo[i].type == trackType) { + for (unsigned int i = 0; i < _aTrackInfo.size(); i++) { + if (_aTrackInfo[i]->type == trackType) { return i; } } diff --git a/src/Rtsp/RtspPlayer.h b/src/Rtsp/RtspPlayer.h index 3310bf49..f05b0908 100644 --- a/src/Rtsp/RtspPlayer.h +++ b/src/Rtsp/RtspPlayer.h @@ -58,14 +58,14 @@ public: float getRtpLossRate(int iTrackType) const override; protected: //派生类回调函数 - virtual bool onCheckSDP(const string &strSdp, const RtspTrack *pTrack, int iTrackCnt) = 0; - virtual void onRecvRTP(const RtpPacket::Ptr &pRtppt, const RtspTrack &track) = 0; + virtual bool onCheckSDP(const string &strSdp, const SdpAttr &sdpAttr) = 0; + virtual void onRecvRTP(const RtpPacket::Ptr &pRtppt, const SdpTrack::Ptr &track) = 0; float getProgressTime() const; void seekToTime(float fTime); private: void onShutdown_l(const SockException &ex); void onRecvRTP_l(const RtpPacket::Ptr &pRtppt, int iTrackidx); - void onRecvRTP_l(const RtpPacket::Ptr &pRtppt, const RtspTrack &track); + void onRecvRTP_l(const RtpPacket::Ptr &pRtppt, const SdpTrack::Ptr &track); void onPlayResult_l(const SockException &ex); int getTrackIndexByControlSuffix(const string &controlSuffix) const; @@ -97,8 +97,9 @@ private: bool sendRtspRequest(const string &cmd, const string &url ,const StrCaseMap &header = StrCaseMap()); private: string _strUrl; - unsigned int _uiTrackCnt = 0; - RtspTrack _aTrackInfo[2]; + + SdpAttr _sdpAttr; + vector _aTrackInfo; function _onHandshake; RtspMediaSource::PoolType _pktPool; diff --git a/src/Rtsp/RtspPlayerImp.h b/src/Rtsp/RtspPlayerImp.h index 9ee2ec8b..7ea46c17 100644 --- a/src/Rtsp/RtspPlayerImp.h +++ b/src/Rtsp/RtspPlayerImp.h @@ -62,7 +62,7 @@ public: }; private: //派生类回调函数 - bool onCheckSDP(const string &sdp, const RtspTrack *track, int trackCnt) override { + bool onCheckSDP(const string &sdp, const SdpAttr &sdpAttr) override { _pRtspMediaSrc = dynamic_pointer_cast(_pMediaSrc); if(_pRtspMediaSrc){ _pRtspMediaSrc->onGetSDP(sdp); @@ -70,7 +70,7 @@ private: _parser.reset(new RtspDemuxer(sdp)); return true; } - void onRecvRTP(const RtpPacket::Ptr &rtppt, const RtspTrack &track) override { + void onRecvRTP(const RtpPacket::Ptr &rtppt, const SdpTrack::Ptr &track) override { if(_pRtspMediaSrc){ _pRtspMediaSrc->onWrite(rtppt,true); } diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index 908664f4..178c1098 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -511,12 +511,12 @@ bool RtspSession::handleReq_Setup() { //未找到相应track return false; } - RtspTrack &trackRef = _aTrackInfo[trackIdx]; - if (trackRef.inited) { + SdpTrack::Ptr &trackRef = _aTrackInfo[trackIdx]; + if (trackRef->inited) { //已经初始化过该Track return false; } - trackRef.inited = true; //现在初始化 + trackRef->inited = true; //现在初始化 auto strongRing = _pWeakRing.lock(); if (!strongRing) { @@ -562,9 +562,9 @@ bool RtspSession::handleReq_Setup() { "x-Dynamic-Rate: 1\r\n\r\n", _iCseq, SERVER_NAME, RTSP_VERSION, RTSP_BUILDTIME, - dateHeader().data(), trackRef.type * 2, - trackRef.type * 2 + 1, - printSSRC(trackRef.ssrc).data(), + dateHeader().data(), trackRef->type * 2, + trackRef->type * 2 + 1, + printSSRC(trackRef->ssrc).data(), _strSession.data()); SocketHelper::send(_pcBuf, iLen); } @@ -609,7 +609,7 @@ bool RtspSession::handleReq_Setup() { RTSP_VERSION, RTSP_BUILDTIME, dateHeader().data(), strClientPort.data(), pSockRtp->get_local_port(), pSockRtcp->get_local_port(), - printSSRC(trackRef.ssrc).data(), + printSSRC(trackRef->ssrc).data(), _strSession.data()); SocketHelper::send(_pcBuf, n); } @@ -630,7 +630,7 @@ bool RtspSession::handleReq_Setup() { strongSelf->safeShutdown(); }); } - int iSrvPort = _pBrdcaster->getPort(trackRef.type); + int iSrvPort = _pBrdcaster->getPort(trackRef->type); //我们用trackIdx区分rtp和rtcp包 auto pSockRtcp = UDPServer::Instance().getSock(get_local_ip().data(),2*trackIdx + 1,iSrvPort + 1); if (!pSockRtcp) { @@ -652,7 +652,7 @@ bool RtspSession::handleReq_Setup() { RTSP_VERSION, RTSP_BUILDTIME, dateHeader().data(), _pBrdcaster->getIP().data(), get_local_ip().data(), iSrvPort, pSockRtcp->get_local_port(), - udpTTL,printSSRC(trackRef.ssrc).data(), + udpTTL,printSSRC(trackRef->ssrc).data(), _strSession.data()); SocketHelper::send(_pcBuf, n); } @@ -733,9 +733,9 @@ bool RtspSession::handleReq_Play() { } for (unsigned int i = 0; i < _uiTrackCnt; i++) { auto &track = _aTrackInfo[i]; - track.ssrc = pMediaSrc->getSsrc(track.type); - track.seq = pMediaSrc->getSeqence(track.type); - track.timeStamp = pMediaSrc->getTimestamp(track.type); + track->ssrc = pMediaSrc->getSsrc(track->type); + track->seq = pMediaSrc->getSeqence(track->type); + track->timeStamp = pMediaSrc->getTimestamp(track->type); } } _bFirstPlay = false; @@ -750,13 +750,13 @@ bool RtspSession::handleReq_Play() { for (unsigned int i = 0; i < _uiTrackCnt; i++) { auto &track = _aTrackInfo[i]; - if (track.inited == false) { + if (track->inited == false) { //还有track没有setup shutdown(); return; } iLen += sprintf(_pcBuf + iLen, "url=%s/%s;seq=%d;rtptime=%u,", - _strUrl.data(), track.controlSuffix.data(), track.seq,track.timeStamp); + _strUrl.data(), track->_control_surffix.data(), track->seq,track->timeStamp); } iLen -= 1; (_pcBuf)[iLen] = '\0'; @@ -895,7 +895,10 @@ inline bool RtspSession::findStream() { _strSdp = pMediaSrc->getSdp(); _pWeakRing = pMediaSrc->getRing(); - _uiTrackCnt = parserSDP(_strSdp, _aTrackInfo); + _sdpAttr.load(_strSdp); + _aTrackInfo = _sdpAttr.getAvailableTrack(); + _uiTrackCnt = _aTrackInfo.size(); + if (_uiTrackCnt == 0 || _uiTrackCnt > 2) { return false; } @@ -904,9 +907,9 @@ inline bool RtspSession::findStream() { for (unsigned int i = 0; i < _uiTrackCnt; i++) { auto &track = _aTrackInfo[i]; - track.ssrc = pMediaSrc->getSsrc(track.type); - track.seq = pMediaSrc->getSeqence(track.type); - track.timeStamp = pMediaSrc->getTimestamp(track.type); + track->ssrc = pMediaSrc->getSsrc(track->type); + track->seq = pMediaSrc->getSeqence(track->type); + track->timeStamp = pMediaSrc->getTimestamp(track->type); } return true; diff --git a/src/Rtsp/RtspSession.h b/src/Rtsp/RtspSession.h index 348c3947..3af1a152 100644 --- a/src/Rtsp/RtspSession.h +++ b/src/Rtsp/RtspSession.h @@ -118,7 +118,7 @@ private: } inline int getTrackIndexByTrackType(TrackType type) { for (unsigned int i = 0; i < _uiTrackCnt; i++) { - if (type == _aTrackInfo[i].type) { + if (type == _aTrackInfo[i]->type) { return i; } } @@ -126,7 +126,7 @@ private: } inline int getTrackIndexByControlSuffix(const string &controlSuffix) { for (unsigned int i = 0; i < _uiTrackCnt; i++) { - if (controlSuffix == _aTrackInfo[i].controlSuffix) { + if (controlSuffix == _aTrackInfo[i]->_control_surffix) { return i; } } @@ -161,8 +161,11 @@ private: PlayerBase::eRtpType _rtpType = PlayerBase::RTP_UDP; bool _bSetUped = false; int _iCseq = 0; + + SdpAttr _sdpAttr; unsigned int _uiTrackCnt = 0; //媒体track个数 - RtspTrack _aTrackInfo[2]; //媒体track信息,trackid idx 为数组下标 + vector _aTrackInfo; + bool _bGotAllPeerUdp = false; #ifdef RTSP_SEND_RTCP diff --git a/src/RtspMuxer/RtspDemuxer.cpp b/src/RtspMuxer/RtspDemuxer.cpp index 69c22a0c..0e842df7 100644 --- a/src/RtspMuxer/RtspDemuxer.cpp +++ b/src/RtspMuxer/RtspDemuxer.cpp @@ -51,25 +51,34 @@ static int getTimeInSDP(const string &sdp) { return atof(strEnd.data()) - atof(strStart.data()); } RtspDemuxer::RtspDemuxer(const string& sdp) { - RtspTrack tmp[2]; - int cnt = parserSDP(sdp, tmp); - for (int i = 0; i < cnt; i++) { - switch (tmp[i].type) { - case TrackVideo: { - makeVideoTrack(tmp[i]); - } - break; - case TrackAudio: { - makeAudioTrack(tmp[i]); - } - break; - default: - break; - } - } - _fDuration = getTimeInSDP(sdp); + loadSdp(SdpAttr(sdp)); } +RtspDemuxer::RtspDemuxer(const SdpAttr &attr) { + loadSdp(attr); +} + +void RtspDemuxer::loadSdp(const SdpAttr &attr) { + auto tracks = attr.getAvailableTrack(); + for (auto &track : tracks){ + switch (track->type) { + case TrackVideo: { + makeVideoTrack(track); + } + break; + case TrackAudio: { + makeAudioTrack(track); + } + break; + default: + break; + } + } + auto titleTrack = attr.getTrack(TrackTitle); + if(titleTrack){ + _fDuration = titleTrack->_duration; + } +} bool RtspDemuxer::inputRtp(const RtpPacket::Ptr & rtp) { switch (rtp->type) { case TrackVideo:{ @@ -91,9 +100,9 @@ bool RtspDemuxer::inputRtp(const RtpPacket::Ptr & rtp) { } -void RtspDemuxer::makeAudioTrack(const RtspTrack &audio) { +void RtspDemuxer::makeAudioTrack(const SdpTrack::Ptr &audio) { //生成Track对象 - _audioTrack = dynamic_pointer_cast(Factory::getTrackBySdp(audio.trackSdp)); + _audioTrack = dynamic_pointer_cast(Factory::getTrackBySdp(audio)); if(_audioTrack){ //生成RtpCodec对象以便解码rtp _audioRtpDecoder = Factory::getRtpDecoderById(_audioTrack->getCodecId(),_audioTrack->getAudioSampleRate()); @@ -107,9 +116,9 @@ void RtspDemuxer::makeAudioTrack(const RtspTrack &audio) { } } -void RtspDemuxer::makeVideoTrack(const RtspTrack &video) { +void RtspDemuxer::makeVideoTrack(const SdpTrack::Ptr &video) { //生成Track对象 - _videoTrack = dynamic_pointer_cast(Factory::getTrackBySdp(video.trackSdp)); + _videoTrack = dynamic_pointer_cast(Factory::getTrackBySdp(video)); if(_videoTrack){ //生成RtpCodec对象以便解码rtp _videoRtpDecoder = Factory::getRtpDecoderById(_videoTrack->getCodecId(),90000); @@ -152,5 +161,4 @@ float RtspDemuxer::getDuration() const { return _fDuration; } - } /* namespace mediakit */ diff --git a/src/RtspMuxer/RtspDemuxer.h b/src/RtspMuxer/RtspDemuxer.h index 0bd70a31..b61a9a8e 100644 --- a/src/RtspMuxer/RtspDemuxer.h +++ b/src/RtspMuxer/RtspDemuxer.h @@ -43,6 +43,7 @@ class RtspDemuxer : public PlayerBase{ public: typedef std::shared_ptr Ptr; RtspDemuxer(const string &sdp); + RtspDemuxer(const SdpAttr &attr); virtual ~RtspDemuxer(){}; /** @@ -72,8 +73,9 @@ public: */ vector getTracks() const override; private: - void makeAudioTrack(const RtspTrack &audio); - void makeVideoTrack(const RtspTrack &video); + void makeAudioTrack(const SdpTrack::Ptr &audio); + void makeVideoTrack(const SdpTrack::Ptr &video); + void loadSdp(const SdpAttr &attr); private: float _fDuration = 0; AudioTrack::Ptr _audioTrack;