<div dir="ltr"><div><div><div><div><div><div>Hi Ross<br><br></div>I have found what I believe to a bug in the latest live555 code and I also have a fix for the problem. We have tested this fix in our implementation and I would like to submit this fix for inclusion in your project.<br>
<br></div><b>PROBLEM DESCRIPTION:</b><br></div>We are streaming using RTP-over-TCP. We are streaming via 3G cell phone connections which means that latency is higher than on a cabled network. We are setting up different Audio and Video streams which means that the client will issue a DESCRIBE request, followed by two SETUP requests and will then issue a PLAY request to start playing the stream. We have found that, after sending the second SETUP request (and before getting the result of this from the server), the client sends out an RR packet to the server. Since this happens before the client has issued a "PLAY" to the server, the server gets confused and responds with a "405 Method Not Allowed". This doesn't happen when we stream on a local LAN since the latency isn't a problem. The problem is only observed once we stream over a "real" network where there is some latency.<br>
<br></div><b>SOLUTION:</b><br></div>I have now debugged the Live555 code and have found the cause of the problem. Basically, in the case of a Sink Node being assigned, the RTCPInstance::addReport function checks the setting we have for enableRTCPReports (whether we can start sending reports or not). However, in the case of a Source Node being assigned, this function neglects to check the corresponding value of the Source Node. I have applied the following fix that I'd like to propose to include in the code:<br>
<br></div><div>In <b>livemedia/include/RTSPSource.hh</b>:<br><br><span style="font-family:courier new,monospace">...<br>  Boolean& enableRTCPReports() { return fEnableRTCPReports; }<br>  <span style="color:rgb(255,0,0)"><b>Boolean constAccessibleEnableRTCPReports() const { return fEnableRTCPReports; }</b> //****Function added by me (Stanley). The same as enableRTCPReports except that it is "const" and "safe" for const object references to call, which means we can call this from RTCPInstance using the fSource object there.</span><br>
</span></div><div><span style="font-family:courier new,monospace">...</span><br><br></div>In <b>livemedia/RTSPClient.cpp</b>:<br><br><span style="font-family:courier new,monospace">...<br>Boolean RTCPInstance::addReport(Boolean alwaysAdd) {<br>
  // Include a SR or a RR, depending on whether we have an associated sink or source:<br>  if (fSink != NULL) {<br>    if (!alwaysAdd) {<br>      if (!fSink->enableRTCPReports()) return False;<br><br>      // Hack: Don't send a SR during those (brief) times when the timestamp of the<br>
      // next outgoing RTP packet has been preset, to ensure that that timestamp gets<br>      // used for that outgoing packet. (David Bertrand, 2006.07.18)<br>      if (fSink->nextTimestampHasBeenPreset()) return False;<br>
    }<br><br>    addSR();<br>  } else if (fSource != NULL) {<br>    <span style="color:rgb(255,0,0)">//****The following IF-statement was added by me (Stanley). As in the case of the Sink Node above, we first check the value of EnableRTCPReports before we do addRR().</span><br>
    <b><span style="color:rgb(255,0,0)">if (!fSource-></span></b></span><span style="font-family:courier new,monospace"><b><span style="color:rgb(255,0,0)"><span style="font-family:courier new,monospace">constAccessibleEnableRTCPReports()</span>) return false;</span></b><br>
    addRR();<br>  }<br><br>  return True;<br>}</span><br>...<br clear="all"><div><div><div><div><div><div><div><div><br></div><div>Kind Regards<br><br></div><div>Stanley Biggs<br></div><div><br><font style="font-family:georgia,serif" size="1"><a href="mailto:stanley@gofuseit.com" target="_blank"></a></font>
</div></div></div></div></div></div></div></div></div>