[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