<!doctype html public "-//W3C//DTD W3 HTML//EN">
<html><head><style type="text/css"><!--
blockquote, dl, ul, ol, li { padding-top: 0 ; padding-bottom: 0 }
 --></style><title>Re: [Live-devel] Several problems with
RTP-over-TCP</title></head><body>
<div>Thanks for the note.  Yes, the implementation of
RTP-over-TCP (for both clients and servers, and, in particular, its
interaction with RTSP) has been difficult, and in fact there were
major changes (improvements and bug fixes) made to the code back in
July and August of last year to support this better, especially for
servers.<br>
</div>
<div>Undoubtedly, though, some problems remain - but certainly not
enough to require a "major rewrite of the code".  The
existing code architecture - in which RTP/RTCP sending/receiving over
either UDP or TCP (the data delivery protocol) is handled by the
"RTPInterface" class, with RTSP (the control protocol) being
handled by the "RTSPServer::RTSPClientSession" class - seems
appropriate, and will remain, as "data delivery" and
"control" are logically separate functions.  (Note, for
example, that it is possible, in principle, for RTP/RTCP-over-TCP
streams to be delivered without using RTSP at all, or by using some
different control protocol (other than RTSP) embedded within the
RTP/RTCP-over-TCP stream.)</div>
<div><br>
Now, to address the specific issues that you raise in your
email:</div>
<div><br></div>
<div><br></div>
<blockquote type="cite" cite><font face="Arial" size="-1">* "No
response to TEARDOWN when the source ended"</font><br>
<font face="Arial" size="-1">If the source ends playing (e.g. EOF),
StreamState::reclaim will be called by the afterPlayingStreamState
handler. The RTCPInstance and RTPSink will be deleted, which causes
them to de-register the TCP socket from the RTPInterface. This turns
off reading of this socket. The delete of the RTCPInstance also will
send a BYE-Event to the client. The client will try to TEARDOWN, but
as nobody is listening on the still open TCP socket, it never get's an
answer.</font></blockquote>
<div><br></div>
<div>Yes, it's unfortunate that the server behavior in this case
(RTP-over-TCP) is unusual (and different from the server behavior in
the normal RTP-over-UDP case).  However, this (i.e., clients not
receiving a response to a RTSP command) is something that clients need
to allow for, as it's always possible for servers to die before they
send a response.</div>
<div><br></div>
<div><br></div>
<blockquote type="cite" cite><font face="Arial" size="-1"> VLC
(1.1.7) totally locks up in that situation - nice.</font></blockquote>
<div><br></div>
<div>I doubt that VLC 'totally' locks up (because I think it uses a
separate thread for its UI), but, in any case, the real problem here
is that VLC is still using the old, now-deprecated synchronous
"RTSPClient" interface.  (From what I've been told (by
the VLC developers), VLC won't start using the new asynchronous
"RTSPClient" interface until its 2.* versions.)</div>
<div><br></div>
<div>To help overcome this problem for now, I've released a new
version (2011.03.06) of the "LIVE555 Streaming Media" code
that changes the implementation of "teardownMediaSession()"
and "teardownMediaSubsession()" in the synchronous interface
to not handle or wait for reponses to RTSP "TEARDOWN"
commands.  Now, clients that use the old synchronous interface
won't ever block when sending "TEARDOWN" commands,
regardless of what the server is doing.</div>
<div><br></div>
<div>Nonetheless, I agree with you that the server's behavior in this
case is not ideal, so at some point in the future I may see if I can
fix this, by (somehow) having the "RTSPClientSession" object
retake control of the TCP socket after the "RTPInterface"
object is finished with it.</div>
<div><br></div>
<div><br></div>
<blockquote type="cite" cite><font face="Arial" size="-1">*
"Defective reuseFirstSource when using
OnDemandServerMediaSubsession with
RTP-over-TCP"</font></blockquote>
<blockquote type="cite" cite><font face="Arial" size="-1">Again, if
the source ends (e.g. EOF) the StreamState will "reclaim",
but the OnDemandServerMediaSubsession will not be informed by that. So
on the next request, it will readily re-use the StreamState that is
already dead, no data at all. This will only be cured if eventually
the RTSPClientSession owning the StreamTokens are garbage collected by
the liveness timeout.</font></blockquote>
<div><br></div>
<div>Yes, you're right - this is a bug (albeit minor).  It's
actually independent of RTP-over-TCP streaming (i.e., I think it
applies to RTP-over-UDP streams as well).  Fortunately it's easy
to fix; a fix will probably appear in the next release of the
code.</div>
<div><br></div>
<div><br></div>
<blockquote type="cite" cite><font face="Arial" size="-1">* "RTSP
is dead after stopping all RTP-over-TCP
streams"</font></blockquote>
<blockquote type="cite" cite><font face="Arial" size="-1">I'm not too
sure about that one, as I'm not too deep into RTSP RFC and I don't
have any testcode to prove it. But from what I see, if within a RTSP
session you start RTP-over-TCP streams and stop them all, also the
RTSP session will be dead. It seems to be impossible to start any
other streams now.</font></blockquote>
<div><br></div>
<div>This is probably a consequence of the first point you noted -
i.e., when a RTP-over-TCP stream is closed, the
"RTSPClientSession" object doesn't get to handle any more
RTSP commands.</div>
<div><br></div>
<div><br></div>
<blockquote type="cite" cite><font face="Arial" size="-1">* "No
error handling on TCP Socket errors"</font><br>
<font face="Arial" size="-1">There are already some posts about this
on the list. Personally I think not doing error handling on serious
errors (socket closed => "Broken pipe") is not good. The
server will continue to try to put packets into a socket that is known
closed. So you will have extra load until some time a liveness check
will kill the RTSPClientSession.</font></blockquote>
<div><br></div>
<div>I don't see this being a major problem.  Note that the same
thing happens for RTP-over-UDP streams if the client happens to die
(actually RTP-over-UDP streams are worse, because the server can't
detect this at all, and you also get network packets being sent). 
I don't think it's worthwhile adding special-case code just to do a
minor optimization of the handling of an error case just for
RTP-over-TCP streams.</div>
<x-sigsep><pre>-- 
</pre></x-sigsep>
<div><br>
Ross Finlayson<br>
Live Networks, Inc.<br>
http://www.live555.com/</div>
</body>
</html>