diff --git a/src/Rtsp/Rtsp.cpp b/src/Rtsp/Rtsp.cpp index da6af7b9..bfdaa49e 100644 --- a/src/Rtsp/Rtsp.cpp +++ b/src/Rtsp/Rtsp.cpp @@ -50,65 +50,57 @@ string FindField(const char* buf, const char* start, const char *end ,int bufSiz return string(msg_start, msg_end); } int parserSDP(const string& sdp, RtspTrack Track[2]) { - string track_str; - if (sdp.find("trackID=") != string::npos) { - track_str = "trackID="; - }else if (sdp.find("track") != string::npos) { - track_str = "track"; - }else if (sdp.find("streamid=") != string::npos) { - track_str = "streamid="; - }else if (sdp.find("stream") != string::npos) { - track_str = "stream"; - } int track_cnt = 0; - string::size_type pos_head = sdp.find("m="); - string::size_type pos_end = 0; - string IDStr; - int TrackID; - string mid; - while (true) { - IDStr = FindField(sdp.c_str() + pos_head, track_str.c_str(), "\r\n"); - if (IDStr == "") { - break; - } - if(strcasecmp(IDStr.data(),"video") == 0){ - TrackID = 0; - }else if(strcasecmp(IDStr.data(),"audio") == 0){ - TrackID = 1; - }else{ - TrackID = atoi(IDStr.c_str()); - } - pos_end = sdp.find("m=", pos_head + 2); + 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(); } - mid = sdp.substr(pos_head, pos_end - pos_head); - Track[track_cnt].trackSdp = mid; - Track[track_cnt].trackStyle = track_str; + auto sdp_mid = sdp.substr(pos_head, pos_end - pos_head); + Track[track_cnt].trackSdp = sdp_mid; Track[track_cnt].inited = false; - Track[track_cnt].trackId = TrackID; - Track[track_cnt].trackIdStr = IDStr; - Track[track_cnt].PT = atoi(FindField(mid.c_str(), "rtpmap:", " ").c_str()); - if (mid.find("m=video") != string::npos) { + 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.find_last_of('/')); + + if (sdp_mid.find("m=video") != string::npos) { //视频通道 Track[track_cnt].type = TrackVideo; - } else if (mid.find("m=audio") != string::npos) { + Track[track_cnt].trackId = 0; + } else if (sdp_mid.find("m=audio") != string::npos) { //音频通道 Track[track_cnt].type = TrackAudio; - } else { + Track[track_cnt].trackId = 1; + } else { //不识别的track - return 0; + return track_cnt; } pos_head = pos_end; - if (track_cnt++ > 2) { - //最大支持2个通道 - return 0; - } + track_cnt++; } return track_cnt; - } - +//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" +// "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); +// track[0].inited=true; +//}); bool MakeNalu(char in, NALU &nal) { nal.forbidden_zero_bit = in >> 7; if (nal.forbidden_zero_bit) { diff --git a/src/Rtsp/Rtsp.h b/src/Rtsp/Rtsp.h index 83ed9408..03b8f133 100644 --- a/src/Rtsp/Rtsp.h +++ b/src/Rtsp/Rtsp.h @@ -44,11 +44,10 @@ class RtspTrack{ public: uint8_t PT; uint8_t trackId; - string trackIdStr; uint8_t interleaved; TrackType type = (TrackType) -1; string trackSdp; - string trackStyle; + string controlSuffix; bool inited; uint32_t ssrc = 0; uint16_t seq; diff --git a/src/Rtsp/RtspPlayer.cpp b/src/Rtsp/RtspPlayer.cpp index 72c7171a..7d4be327 100644 --- a/src/Rtsp/RtspPlayer.cpp +++ b/src/Rtsp/RtspPlayer.cpp @@ -261,21 +261,21 @@ inline void RtspPlayer::sendSetup(unsigned int trackIndex) { auto &track = m_aTrackInfo[trackIndex]; switch (m_eType) { case RTP_TCP: { - iLen = sprintf(acRtspbuf, "SETUP %s/%s%s RTSP/1.0\r\n" + iLen = sprintf(acRtspbuf, "SETUP %s/%s RTSP/1.0\r\n" "CSeq: %d\r\n" "Transport: RTP/AVP/TCP;unicast;interleaved=%d-%d\r\n" "Authorization: Basic %s\r\n\r\n", m_strContentBase.c_str(), - track.trackStyle.c_str(), track.trackIdStr.data(), m_uiCseq++, + track.controlSuffix.c_str(), m_uiCseq++, track.trackId * 2, track.trackId * 2 + 1, m_strAuthorization.c_str()); } break; case RTP_MULTICAST: { - iLen = sprintf(acRtspbuf, "SETUP %s/%s%s RTSP/1.0\r\n" + iLen = sprintf(acRtspbuf, "SETUP %s/%s RTSP/1.0\r\n" "CSeq: %d\r\n" "Transport: RTP/AVP;multicast\r\n" "Authorization: Basic %s\r\n\r\n", m_strContentBase.c_str(), - track.trackStyle.c_str(), track.trackIdStr.data(), m_uiCseq++, + track.controlSuffix.c_str(), m_uiCseq++, m_strAuthorization.c_str()); } break; @@ -286,11 +286,11 @@ inline void RtspPlayer::sendSetup(unsigned int trackIndex) { throw std::runtime_error("open udp sock err"); } int port = m_apUdpSock[trackIndex]->get_local_port(); - iLen = sprintf(acRtspbuf, "SETUP %s/%s%s RTSP/1.0\r\n" + iLen = sprintf(acRtspbuf, "SETUP %s/%s RTSP/1.0\r\n" "CSeq: %d\r\n" "Transport: RTP/AVP;unicast;client_port=%d-%d\r\n" "Authorization: Basic %s\r\n\r\n", m_strContentBase.c_str(), - track.trackStyle.c_str(), track.trackIdStr.data(), m_uiCseq++, port, + track.controlSuffix.c_str(), m_uiCseq++, port, port + 1, m_strAuthorization.c_str()); } break; @@ -456,12 +456,12 @@ void RtspPlayer::HandleResPAUSE(const Parser& parser, bool bPause) { vector vec = split(strRtpInfo, ","); for(auto &strTrack : vec){ strTrack.append(";"); - auto strTrackId = FindField(strTrack.data(), m_aTrackInfo[0].trackStyle.data(), ";"); + auto strControlSuffix = strTrack.substr(1 + strTrack.find_last_of('/'),strTrack.find(';') - strTrack.find_last_of('/') - 1); auto strRtpTime = FindField(strTrack.data(), "rtptime=", ";"); - auto iIdx = getTrackIndex(atoi(strTrackId.data())); + auto iIdx = getTrackIndex(strControlSuffix); m_adFistStamp[iIdx] = atoll(strRtpTime.data()); m_adNowStamp[iIdx] = m_adFistStamp[iIdx]; - DebugL << "rtptime:" << strTrackId <<" " << strRtpTime; + DebugL << "rtptime:" << strControlSuffix <<" " << strRtpTime; } } _onPlayResult(SockException(Err_success, "rtsp play success")); diff --git a/src/Rtsp/RtspPlayer.h b/src/Rtsp/RtspPlayer.h index 937b4bd3..590162ff 100644 --- a/src/Rtsp/RtspPlayer.h +++ b/src/Rtsp/RtspPlayer.h @@ -127,14 +127,22 @@ private: inline bool HandleOneRtp(int iTrackidx, unsigned char *ucData, unsigned int uiLen); bool sendOptions(); inline void _onRecvRTP(const RtpPacket::Ptr &pRtppt, int iTrackidx); - inline int getTrackIndex(int iTrackId) const{ + inline int getTrackIndex(const string &controlSuffix) const{ for (unsigned int i = 0; i < m_uiTrackCnt; i++) { - if (m_aTrackInfo[i].trackId == iTrackId) { + if (m_aTrackInfo[i].controlSuffix == controlSuffix) { return i; } } return -1; } + inline int getTrackIndex(int iTrackId) const{ + for (unsigned int i = 0; i < m_uiTrackCnt; i++) { + if (m_aTrackInfo[i].trackId == iTrackId) { + return i; + } + } + return -1; + } string m_strUrl; unsigned int m_uiTrackCnt = 0; diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index ef36c592..1f9b4166 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -481,11 +481,8 @@ inline void RtspSession::send_SessionNotFound() { } bool RtspSession::handleReq_Setup() { //处理setup命令,该函数可能进入多次 -//track id - int trackid = atoi( FindField( m_parser.Url().data(), - m_aTrackInfo[0].trackStyle.data(), - NULL).data()); - int trackIdx = getTrackIndexByTrackId(trackid); + auto controlSuffix = m_parser.Url().substr(1 + m_parser.Url().find_last_of('/')); + int trackIdx = getTrackIndexByControlSuffix(controlSuffix); if (trackIdx == -1) { //未找到相应track return false; @@ -541,8 +538,8 @@ bool RtspSession::handleReq_Setup() { "x-Dynamic-Rate: 1\r\n\r\n", m_iCseq, SERVER_NAME, RTSP_VERSION, RTSP_BUILDTIME, - dateHeader().data(), trackid * 2, - trackid * 2 + 1, + dateHeader().data(), trackRef.trackId * 2, + trackRef.trackId * 2 + 1, printSSRC(trackRef.ssrc).data(), m_strSession.data()); send(m_pcBuf, iLen); @@ -609,7 +606,7 @@ bool RtspSession::handleReq_Setup() { strongSelf->safeShutdown(); }); } - int iSrvPort = m_pBrdcaster->getPort(trackid); + int iSrvPort = m_pBrdcaster->getPort(trackRef.trackId); //我们用trackIdx区分rtp和rtcp包 auto pSockRtcp = UDPServer::Instance().getSock(get_local_ip().data(),2*trackIdx + 1,iSrvPort + 1); if (!pSockRtcp) { @@ -734,9 +731,8 @@ bool RtspSession::handleReq_Play() { shutdown(); return; } - iLen += sprintf(m_pcBuf + iLen, "url=%s/%s%s;seq=%d;rtptime=%u,", - m_strUrl.data(), track.trackStyle.data(), - track.trackIdStr.data(), track.seq,track.timeStamp); + iLen += sprintf(m_pcBuf + iLen, "url=%s/%s;seq=%d;rtptime=%u,", + m_strUrl.data(), track.controlSuffix.data(), track.seq,track.timeStamp); } iLen -= 1; (m_pcBuf)[iLen] = '\0'; diff --git a/src/Rtsp/RtspSession.h b/src/Rtsp/RtspSession.h index 7e835462..7ad9e003 100644 --- a/src/Rtsp/RtspSession.h +++ b/src/Rtsp/RtspSession.h @@ -134,6 +134,15 @@ private: } return -1; } + inline int getTrackIndexByControlSuffix(const string &controlSuffix) { + for (unsigned int i = 0; i < m_uiTrackCnt; i++) { + if (controlSuffix == m_aTrackInfo[i].controlSuffix) { + return i; + } + } + return -1; + } + inline void onRcvPeerUdpData(int iTrackIdx, const Buffer::Ptr &pBuf, const struct sockaddr &addr); inline void startListenPeerUdpData();