[Live-devel] odd port number for transport stream over UDP

John Orr john.orr at scala.com
Mon Feb 20 10:16:37 PST 2012


I have a media player that uses Live555 to stream from RTSP/RTP as well 
as transport stream over UDP (IPTV style).  When playing transport 
stream over UDP, I put together an SDP description like this:

s=MPEG Transport Stream over UDP
i=TS over UDP
t=0 0
a=type:broadcast
m=video <port number> UDP 33
c=IN IP4 <ip address>
b=AS:5000

Then I create a MediaSession with it, like this:

         m_pLive555Session = MediaSession::createNew(*m_pLive555Env, 
sdpDescription);

The call initiate() on the subsession.  This creates a 
MPEG2TransportStreamFramer, with a BasicUDPSource to feed it.

This works great as long as the port number for the UDP transport stream 
is even.  If it is odd, 
liveMedia/MediaSession.cpp/MediaSubsession::initiate() forces the data 
delivery port to be even.

There is convention/rule that says you use even port numbers for RTP and 
odd for the corresponding RTCP backchannel.  I'm not disputing that, but 
this code can also handle TS over UDP.  In the case of raw transport 
stream over UDP there is no RTCP back channel and the port number isn't 
generally negotiable.

To get around the problem, I hacked initiate() to avoid changing the 
port number when fProtocolName is UDP, I added the diff to the end of 
this message.  I don't have a very deep understanding of this code base, 
maybe this was the wrong approach, but this patch met my immediate 
needs.  I'm guessing my case here is either fairly obscure or I missed a 
better way of dealing with this.

Comments and criticisms are welcome.

--Johno



diff --git a/liveMedia/MediaSession.cpp b/liveMedia/MediaSession.cpp
index 8e17d26..9b49bba 100644
--- a/liveMedia/MediaSession.cpp
+++ b/liveMedia/MediaSession.cpp
@@ -588,9 +588,18 @@ Boolean MediaSubsession::initiate(int 
useSpecialRTPoffset) {
      tempAddr.s_addr = connectionEndpointAddress();
          // This could get changed later, as a result of a RTSP "SETUP"

+       // ZZZ: Feb 2012
+       // do not bother forcing port to be even when using UDP, should 
only apply to RTP
+       //
+       bool bIsUDP = (strcmp(fProtocolName, "UDP") == 0);
+
      if (fClientPortNum != 0) {
-      // The sockets' port numbers were specified for us.  Use these:
-      fClientPortNum = fClientPortNum&~1; // even
+
+               if ( !bIsUDP )
+               {
+                       // The sockets' port numbers were specified for 
us.  Use these:
+                       fClientPortNum = fClientPortNum&~1; // even
+               }
        if (isSSM()) {
         fRTPSocket = new Groupsock(env(), tempAddr, fSourceFilterAddr, 
fClientPortNum);
        } else {
@@ -600,20 +609,23 @@ Boolean MediaSubsession::initiate(int 
useSpecialRTPoffset) {
         env().setResultMsg("Failed to create RTP socket");
         break;
        }
-
-      // Set our RTCP port to be the RTP port +1
-      portNumBits const rtcpPortNum = fClientPortNum|1;
-      if (isSSM()) {
-       fRTCPSocket = new Groupsock(env(), tempAddr, fSourceFilterAddr, 
rtcpPortNum);
-      } else {
-       fRTCPSocket = new Groupsock(env(), tempAddr, rtcpPortNum, 255);
-      }
-      if (fRTCPSocket == NULL) {
-       char tmpBuf[100];
-       sprintf(tmpBuf, "Failed to create RTCP socket (port %d)", 
rtcpPortNum);
-       env().setResultMsg(tmpBuf);
-       break;
-      }
+
+         if ( !bIsUDP )
+         {
+                 // Set our RTCP port to be the RTP port +1
+                 portNumBits const rtcpPortNum = fClientPortNum|1;
+                 if (isSSM()) {
+                         fRTCPSocket = new Groupsock(env(), tempAddr, 
fSourceFilterAddr, rtcpPortNum);
+                 } else {
+                         fRTCPSocket = new Groupsock(env(), tempAddr, 
rtcpPortNum, 255);
+                 }
+                 if (fRTCPSocket == NULL) {
+                         char tmpBuf[100];
+                         sprintf(tmpBuf, "Failed to create RTCP socket 
(port %d)", rtcpPortNum);
+                         env().setResultMsg(tmpBuf);
+                         break;
+                 }
+         }
      } else {
        // Port numbers were not specified in advance, so we use 
ephemeral port numbers.
        // Create sockets until we get a port-number pair (even: RTP; 
even+1: RTCP).
@@ -691,7 +703,7 @@ Boolean MediaSubsession::initiate(int 
useSpecialRTPoffset) {
      increaseReceiveBufferTo(env(), fRTPSocket->socketNum(), rtpBufSize);

      // ASSERT: fRTPSocket != NULL && fRTCPSocket != NULL
-    if (isSSM()) {
+    if (isSSM() && !bIsUDP ) {
        // Special case for RTCP SSM: Send RTCP packets back to the 
source via unicast:
        fRTCPSocket->changeDestinationParameters(fSourceFilterAddr,0,~0);
      }



More information about the live-devel mailing list