[Live-devel] Updated RTSP server implementation to support multiple TCP connections per session - new experimental release

Lionel Orry lionel.orry at em-sys.fr
Fri Jul 27 04:26:01 PDT 2012


Dear Ross,

Thank you very much for this hard and valuable work. I am trying to
migrate my current development on this branch. This is working well for
now, though I have not tested the independence between RTSP sessions and
TCP connections yet.

I am however facing some inheritance/relationship issues that I will try
to explain.

I have subclassed RTSPServerSupportingHTTPStreaming,
RTSPServer::RTSPClientSession and RTSPServer::RTSPClientConnection
classes for my needs, overriding virtual methods.

I am trying, in the SETUP phase for example, to augment the response
buffer with specific headers. Here is an outline of what I am doing
currently:

------------------------------------------------------------------------

// Declaration
class MyOwnRTSPServer: public RTSPServerSupportingHTTPStreaming {

public:
  class RTSPServerConnection: public RTSPServer::RTSPServerConnection {
    // [...]
  };

  class RTSPServerSession: public RTSPServer::RTSPServerSession {
    protected:
      virtual void handleCmd_SETUP(RTSPServer::RTSPClientConnection*
                     ourClientConnection, char const* urlPreSuffix,
                     char const* urlSuffix, char const* fullRequestStr);
  };

};

// Implementation
void MyOwnRTSPServer::RTSPServerSession
::handleCmd_SETUP(RTSPServer::RTSPClientConnection* ourClientConnection,
                  char const* urlPreSuffix,
                  char const* urlSuffix, char const* fullRequestStr) {
  
  // Doing specific stuff here...

  // calling original handler
  RTSPServer::RTSPClientSession::handleCmd_SETUP(ourClientConnection,
    urlPreSuffix, urlSuffix, fullRequestStr);

  // Trying to append lines to responseBuffer
  char *lastLine = strstr(
    (const char*)ourClientConnection->fResponseBuffer,
    "\r\n\r\n");
    if (lastLine==NULL)
    {
        envir() << "ERROR: last line of response buffer not found!\n";
        return;
    }
    sprintf(lastLine, "\r\nmyField: %d\r\n\r\n", myValue); 
}

------------------------------------------------------------------------

The problem is, if I write it as-is, the compiler (GCC) tells me:

include/RTSPServer.hh:196: error: ‘unsigned char
RTSPServer::RTSPClientConnection::fResponseBuffer [10000]’ is protected

even though I tried to do my best to correctly declare friend classes
and such.

I found a working solution but I am not extremely happy about it, and I
am searching for suggestions: I declared a new pointer with my own
RTSPClientConnection type, and I did a dynamic_cast of the original
Connection instance:

------------------------------------------------------------------------
void MyOwnRTSPServer::RTSPServerSession
::handleCmd_SETUP(RTSPServer::RTSPClientConnection* ourClientConnection,
                  char const* urlPreSuffix,
                  char const* urlSuffix, char const* fullRequestStr) {

 RTSPClientConnection* conn = dynamic_cast<RTSPClientConnection*>(
                                ourClientConnection);
  // calling original handler
  RTSPServer::RTSPClientSession::handleCmd_SETUP(ourClientConnection,
    urlPreSuffix, urlSuffix, fullRequestStr);

  // Trying to append lines to responseBuffer
  char *lastLine = strstr(
    (const char*)conn->fResponseBuffer,  // <---- I use 'conn' here
    "\r\n\r\n");
  // rest of code...
}
------------------------------------------------------------------------

The code above compiles and works fine. My first attempt was to declare
the handler with the first parameter of type
MyOwnRTSPServer::RTSPClientConnection, but it would not override the
original method because the prototype would be different.

Does any of you have an idea of how to make that look good ?

Thanks for your inputs,
Lionel

On Thu, 2012-07-26 at 17:47 -0700, Ross Finlayson wrote:
> (First, if you are not using a RTSP server at all in your application,
> you can ignore the rest of this email.)
> 
> 
> I have made a major update to the RTSP server implementation.  A
> single RTSP client session (i.e, the streaming of one particular
> stream to one particular client) can now use an arbitrary number (>=1)
> of TCP connections.  E.g., there can now be one TCP connection for the
> "DESCRIBE"; another TCP connection for each "SETUP"; another TCP
> connection for "PLAY", etc.  (Of course, this applies only to RTP/UDP
> sessions; RTP/TCP sessions have to use the same TCP connection, from
> "SETUP" through "TEARDOWN".)
> 
> 
> Similarly, a single TCP connection can now be used for more than one
> session (for the same client, of course).  (Despite this, our own RTSP
> *client* implementation continues to use a single TCP connection for
> each session.)
> 
> 
> The new RTSP server implementation does this by separating 'client
> connection' from 'client session'.  The "RTSPServer" class now has two
> member classes: "RTSPServer::RTSPClientConnection" (for a single TCP
> connection), and "RTSPServer::RTSPClientSession" (for a single client
> session, possibly used by multiple TCP connections).  You can, if you
> wish, subclass these two classes, along with subclassing "RTSPServer"
> itself.
> 
> 
> I have also improved the way that the "RTSPServer" class manages
> "ServerMediaSession" objects.  (Recall that a "ServerMediaSession"
> describes a single media stream source (possibly with 'subsessions'
> for audio, video, etc.), regardless of how many clients happen to be
> currently receiving it.)
> - As before, the "RTSPServer::removeServerMediaSession()" function
> removes a "ServerMediaSession" object from the server, thereby making
> it inaccessible to new clients, but does not stop any ongoing
> streaming to existing clients.
> - A new function "RTSPServer::deleteServerMediaSession()" removes (and
> deletes) a "ServerMediaSession" object from the server, *and also*
> stops any streaming to existing clients.
> - A new function
> "RTSPServer::closeAllClientSessionsForServerMediaSession()" stops any
> streaming (for a specified "ServerMediaSession" object) to existing
> clients, but leaves the "ServerMediaSession" object on the server, so
> that new clients can still access it.
> - The "RTSPServer" destructor now removes and deletes all
> "RTSPClientConnection" and "RTSPClientSession" objects, and thereby
> also stops any existing ongoing streams.  So, if you wish, you can
> call "Medium::close()" on your "RTSPServer" object, knowing that this
> will automatically stop all existing streaming, and reclaim all of its
> objects.
> 
> 
> Because these changes are substantial, and possibly have introduced
> some bugs, I have done something unusual, by making the new source
> code release an 'experimental' release.  It's available at:
> http://www.live555.com/liveMedia/public/live555-experimental.tgz
> 
> 
> Eventually, however (possibly just within a week or so), this new
> release will no longer be experimental; it will become the lone
> supported "LIVE555 Streaming Media" release.
> 
> 
> Therefore, if you're a developer who uses a RTSP server in your
> application, you are encouraged to download and test the new
> experimental release, and report back on any problems that you might
> find.  Note, in particular, that if you have subclassed "RTSPServer",
> then you should download and test the new experimental version sooner
> rather than later, because the API for subclassing has changed (the
> API for creating new "RTSPClientSession"s has changed, and there's now
> a new "RTSPClientConnection" class as well).
> 
> 
> Ross Finlayson
> Live Networks, Inc.
> http://www.live555.com/
> 
> _______________________________________________
> live-devel mailing list
> live-devel at lists.live555.com
> http://lists.live555.com/mailman/listinfo/live-devel




More information about the live-devel mailing list