Hi Ross, we have the need to create a RTSP Session without a RTCP Instance because of a Server that has a bug causing it not to terminate sessions after it received an RTCP report from the client. I came up with the attached patch, which feels really ugly and I'm pretty sure could have unexpected side-effects. Would you mind taking a look and maybe propose a better way to do this?
Thanks, Julian --- Allow connections without a RTCP port to be configured. --- liveMedia/MediaSession.cpp | 6 +++++- liveMedia/RTSPClient.cpp | 18 ++++++++++++++---- liveMedia/include/MediaSession.hh | 3 +++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/liveMedia/MediaSession.cpp b/liveMedia/MediaSession.cpp index a5b13d0..54e9346 100644 --- a/liveMedia/MediaSession.cpp +++ b/liveMedia/MediaSession.cpp @@ -821,7 +821,7 @@ Boolean MediaSubsession::initiate(int useSpecialRTPoffset) { } // Finally, create our RTCP instance. (It starts running automatically) - if (fRTPSource != NULL && fRTCPSocket != NULL) { + if (fRTPSource != NULL && fRTCPSocket != NULL && !fNoRTCP) { // If bandwidth is specified, use it and add 5% for RTCP overhead. // Otherwise make a guess at 500 kbps. unsigned totSessionBandwidth @@ -867,6 +867,10 @@ Boolean MediaSubsession::setClientPortNum(unsigned short portNum) { return True; } +void MediaSubsession::setNoRTCP(Boolean enable) { + fNoRTCP = enable; +} + char const* MediaSubsession::attrVal_str(char const* attrName) const { SDPAttribute* attr = (SDPAttribute*)(fAttributeTable->Lookup(attrName)); if (attr == NULL) return ""; diff --git a/liveMedia/RTSPClient.cpp b/liveMedia/RTSPClient.cpp index fc68042..f659ff5 100644 --- a/liveMedia/RTSPClient.cpp +++ b/liveMedia/RTSPClient.cpp @@ -662,9 +662,15 @@ Boolean RTSPClient::setRequestFields(RequestRecord* request, char const* transportFmt; if (strcmp(subsession.protocolName(), "UDP") == 0) { suffix = ""; - transportFmt = "Transport: RAW/RAW/UDP%s%s%s=%d-%d\r\n"; + if (subsession.noRTCP()) + transportFmt = "Transport: RAW/RAW/UDP%s%s%s=%d\r\n"; + else + transportFmt = "Transport: RAW/RAW/UDP%s%s%s=%d-%d\r\n"; } else { - transportFmt = "Transport: RTP/AVP%s%s%s=%d-%d\r\n"; + if (subsession.noRTCP()) + transportFmt = "Transport: RTP/AVP%s%s%s=%d\r\n"; + else + transportFmt = "Transport: RTP/AVP%s%s%s=%d-%d\r\n"; } cmdURL = new char[strlen(prefix) + strlen(separator) + strlen(suffix) + 1]; @@ -699,8 +705,12 @@ Boolean RTSPClient::setRequestFields(RequestRecord* request, unsigned transportSize = strlen(transportFmt) + strlen(transportTypeStr) + strlen(modeStr) + strlen(portTypeStr) + 2*5 /* max port len */; char* transportStr = new char[transportSize]; - sprintf(transportStr, transportFmt, - transportTypeStr, modeStr, portTypeStr, rtpNumber, rtcpNumber); + if (subsession.noRTCP()) + sprintf(transportStr, transportFmt, + transportTypeStr, modeStr, portTypeStr, rtpNumber); + else + sprintf(transportStr, transportFmt, + transportTypeStr, modeStr, portTypeStr, rtpNumber, rtcpNumber); // When sending more than one "SETUP" request, include a "Session:" header in the 2nd and later commands: char* sessionStr = createSessionString(fLastSessionId); diff --git a/liveMedia/include/MediaSession.hh b/liveMedia/include/MediaSession.hh index f2ea909..107fcdc 100644 --- a/liveMedia/include/MediaSession.hh +++ b/liveMedia/include/MediaSession.hh @@ -168,6 +168,7 @@ public: char const* protocolName() const { return fProtocolName; } char const* controlPath() const { return fControlPath; } Boolean isSSM() const { return fSourceFilterAddr.s_addr != 0; } + Boolean noRTCP() const { return fNoRTCP; } unsigned short videoWidth() const { return fVideoWidth; } unsigned short videoHeight() const { return fVideoHeight; } @@ -207,6 +208,7 @@ public: // description does not specfy a client port number - an ephemeral // (even) port number is chosen.) This routine must *not* be // called after initiate(). + void setNoRTCP(Boolean enable); void receiveRawMP3ADUs() { fReceiveRawMP3ADUs = True; } // optional hack for audio/MPA-ROBUST; must not be called after initiate() void receiveRawJPEGFrames() { fReceiveRawJPEGFrames = True; } // optional hack for video/JPEG; must not be called after initiate() char*& connectionEndpointName() { return fConnectionEndpointName; } @@ -312,6 +314,7 @@ protected: char* fControlPath; // holds optional a=control: string struct in_addr fSourceFilterAddr; // used for SSM unsigned fBandwidth; // in kilobits-per-second, from b= line + Boolean fNoRTCP; // disable rtcp port announcement double fPlayStartTime; double fPlayEndTime; -- 2.7.0 _______________________________________________ live-devel mailing list live-devel@lists.live555.com http://lists.live555.com/mailman/listinfo/live-devel