[Live-devel] [PATCH] Parse SDP bandwidth line and use to set the receive socket buffer size

Ben Hutchings ben at decadent.org.uk
Sun Sep 20 09:12:32 PDT 2009


This is required to avoid packet loss for high-bandwidth codecs such as
DV video.

Ben.

diff --git a/liveMedia/MediaSession.cpp b/liveMedia/MediaSession.cpp
index 2768157..1a09f2c 100644
--- a/liveMedia/MediaSession.cpp
+++ b/liveMedia/MediaSession.cpp
@@ -211,6 +211,7 @@ Boolean MediaSession::initializeWithSDP(char const* sdpDescription) {
 
       // Check for various special SDP lines that we understand:
       if (subsession->parseSDPLine_c(sdpLine)) continue;
+      if (subsession->parseSDPLine_b(sdpLine)) continue;
       if (subsession->parseSDPAttribute_rtpmap(sdpLine)) continue;
       if (subsession->parseSDPAttribute_control(sdpLine)) continue;
       if (subsession->parseSDPAttribute_range(sdpLine)) continue;
@@ -540,7 +541,7 @@ MediaSubsession::MediaSubsession(MediaSession& parent)
     fClientPortNum(0), fRTPPayloadFormat(0xFF),
     fSavedSDPLines(NULL), fMediumName(NULL), fCodecName(NULL), fProtocolName(NULL),
     fRTPTimestampFrequency(0), fControlPath(NULL),
-    fSourceFilterAddr(parent.sourceFilterAddr()),
+    fSourceFilterAddr(parent.sourceFilterAddr()), fBandwidth(0),
     fAuxiliarydatasizelength(0), fConstantduration(0), fConstantsize(0),
     fCRC(0), fCtsdeltalength(0), fDe_interleavebuffersize(0), fDtsdeltalength(0),
     fIndexdeltalength(0), fIndexlength(0), fInterleaving(0), fMaxdisplacement(0),
@@ -690,6 +691,13 @@ Boolean MediaSubsession::initiate(int useSpecialRTPoffset) {
       if (!success) break; // a fatal error occurred trying to create the RTP and RTCP sockets; we can't continue
     }
 
+    // Try to use a big receive buffer for RTP - at least 0.1 second of
+    // specified bandwidth and at least 50 KB
+    unsigned rtpBufSize = fBandwidth * 25 / 2; // 1 kbps * 0.1 s = 12.5 bytes
+    if (rtpBufSize < 50 * 1024)
+      rtpBufSize = 50 * 1024;
+    increaseReceiveBufferTo(env(), fRTPSocket->socketNum(), rtpBufSize);
+
     // ASSERT: fRTPSocket != NULL && fRTCPSocket != NULL
     if (isSSM()) {
       // Special case for RTCP SSM: Send RTCP packets back to the source via unicast:
@@ -892,7 +900,10 @@ Boolean MediaSubsession::initiate(int useSpecialRTPoffset) {
 
     // Finally, create our RTCP instance. (It starts running automatically)
     if (fRTPSource != NULL) {
-      unsigned totSessionBandwidth = 500; // HACK - later get from SDP#####
+      // If bandwidth is specified, use it and add 5% for RTCP overhead.
+      // Otherwise make a guess at 500 kbps.
+      unsigned totSessionBandwidth
+	= fBandwidth ? fBandwidth + fBandwidth / 20 : 500;
       fRTCPInstance = RTCPInstance::createNew(env(), fRTCPSocket,
 					      totSessionBandwidth,
 					      (unsigned char const*)
@@ -1028,6 +1039,12 @@ Boolean MediaSubsession::parseSDPLine_c(char const* sdpLine) {
   return False;
 }
 
+Boolean MediaSubsession::parseSDPLine_b(char const* sdpLine) {
+  // Check for "b=<bwtype>:<bandwidth>" line
+  // RTP applications are expected to use bwtype="AS"
+  return sscanf(sdpLine, "b=AS:%u", &fBandwidth) == 1;
+}
+
 Boolean MediaSubsession::parseSDPAttribute_rtpmap(char const* sdpLine) {
   // Check for a "a=rtpmap:<fmt> <codec>/<freq>" line:
   // (Also check without the "/<freq>"; RealNetworks omits this)
diff --git a/liveMedia/MultiFramedRTPSource.cpp b/liveMedia/MultiFramedRTPSource.cpp
index dee9a53..1e4bdc4 100644
--- a/liveMedia/MultiFramedRTPSource.cpp
+++ b/liveMedia/MultiFramedRTPSource.cpp
@@ -68,9 +68,6 @@ MultiFramedRTPSource
   : RTPSource(env, RTPgs, rtpPayloadFormat, rtpTimestampFrequency) {
   reset();
   fReorderingBuffer = new ReorderingPacketBuffer(packetFactory);
-
-  // Try to use a big receive buffer for RTP:
-  increaseReceiveBufferTo(env, RTPgs->socketNum(), 50*1024);
 }
 
 void MultiFramedRTPSource::reset() {
diff --git a/liveMedia/include/MediaSession.hh b/liveMedia/include/MediaSession.hh
index 5b9ad06..a73bb46 100644
--- a/liveMedia/include/MediaSession.hh
+++ b/liveMedia/include/MediaSession.hh
@@ -249,6 +249,7 @@ protected:
   void setNext(MediaSubsession* next) { fNext = next; }
 
   Boolean parseSDPLine_c(char const* sdpLine);
+  Boolean parseSDPLine_b(char const* sdpLine);
   Boolean parseSDPAttribute_rtpmap(char const* sdpLine);
   Boolean parseSDPAttribute_control(char const* sdpLine);
   Boolean parseSDPAttribute_range(char const* sdpLine);
@@ -274,6 +275,7 @@ protected:
   unsigned fRTPTimestampFrequency;
   char* fControlPath; // holds optional a=control: string
   struct in_addr fSourceFilterAddr; // used for SSM
+  unsigned fBandwidth; // in kilobits, from b= line
 
   // Parameters set by "a=fmtp:" SDP lines:
   unsigned fAuxiliarydatasizelength, fConstantduration, fConstantsize;
-- 
1.6.4.3


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 828 bytes
Desc: This is a digitally signed message part
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20090920/8180187a/attachment-0001.bin>


More information about the live-devel mailing list