[Live-devel] extend cont.

Ross Finlayson finlayson at live555.com
Mon Aug 12 12:22:36 PDT 2013


> class RTSPServerExtensions :protected RTSPServer

That's your first problem.  When subclassing LIVE555 classes, you should always use public inheritance (because you want a 'is a' relationship), not protected or private inheritance.  (Personally, I don't think that protected or private inheritance is a good idea for *any* C++ code.)

Second, note that there are two "handleCmd_GET_PARAMETER()" virtual functions (and ditto for "handleCmd_SET_PARAMETER()").  The first one (used to implement commands that operate on the entire server - i.e., "GET_PARAMETER *") is a member function of "RTSPServer::RTSPClientConnection".  The second one (used to implement commands that operate within a RTSP session - i.e., for one particular stream, specified by "rtsp://" URL) is a member function of "RTSPServer::RTSPClientSession".  Therefore, depending on which virtual function(s) you wish to reimplement, you will need to subclass not just "RTSPServer", but also "RTSPServer::RTSPClientConnection", "RTSPServer::RTSPClientSession", or both.

Finally, if you subclass "RTSPServer::RTSPClientConnection", you must also reimplement the virtual function "createNewClientConnection()" in your "RTSPServer" subclass.  Similarly, if you subclass "RTSPServer::RTSPClientSession", you must also reimplement the virtual function "createNewClientSession()" in your "RTSPServer" subclass.

So, your first step is decide which RTSP operation(s) you *really* want to reimplement.  Do you want to reimplement "GET_PARAMETER" (or "SET_PARAMETER") that applies to the whole server, or "GET_PARAMETER" (or "SET_PARAMETER") that applies to one particular stream (specified by "rtsp://" URL)?

To illustrate, I assume that you want to reimplement "GET_PARAMETER" when applied to one particular stream.  In this case, you'd subclass both "RTSPServer" and "RTSPServer::RTSPClientSession" - like this:

class RTSPServerExtension: public RTSPServer {
public:
  static RTSPServerExtension* createNew(UsageEnvironment& env, Port rtspPort = 554,
                                                      UserAuthenticationDatabase* authDatabase = NULL,
                                                      unsigned reclamationTestSeconds = 65);

protected:
  RTSPServerExtension(UsageEnvironment& env,
                                    int ourSocket, Port ourPort,
                                    UserAuthenticationDatabase* authDatabase,
                                    unsigned reclamationTestSeconds);
      // called only by createNew();
  virtual ~RTSPServerExtension();

protected: // redefined virtual functions
  virtual RTSPClientSession* createNewClientSession(u_int32_t sessionId);

public: // should be protected, but some old compilers complain otherwise
  class RTSPClientSessionExtension: public RTSPServer::RTSPClientSession {
  public:
   RTSPClientSessionExtension(RTSPServer& ourServer, u_int32_t sessionId);
    virtual ~RTSPClientSessionExtension();

  protected: // redefined virtual functions
    virtual void handleCmd_GET_PARAMETER(RTSPClientConnection* ourClientConnection, ServerMediaSubsession* subsession, char const* fullRequestStr);
  };
};


And your implementation would look something like this:

RTSPServerExtension* RTSPServerExtension
::createNew(UsageEnvironment& env, Port rtspPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds) {
  int ourSocket = setUpOurSocket(env, rtspPort);
  if (ourSocket == -1) return NULL;

  return new RTSPServerExtension(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds);
}

RTSPServerExtension::RTSPServerExtension(UsageEnvironment& env,
                                         int ourSocket, Port rtspPort,
                                         UserAuthenticationDatabase* authDatabase,
                                         unsigned reclamationTestSeconds)
  : RTSPServer(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds) {
}

RTSPServerExtension::~RTSPServerExtension() {
}

RTSPServer::RTSPClientSession* RTSPServerExtension::createNewClientSession(u_int32_t sessionId) {
  return new RTSPServerExtension::RTSPClientSessionExtension(*this, sessionId);
}

RTSPServerExtension::RTSPClientSessionExtension
::RTSPClientSessionExtension(RTSPServer& ourServer, u_int32_t sessionId)
  : RTSPClientSession(ourServer, sessionId) {
}

RTSPServerExtension::RTSPClientSessionExtension
::~RTSPClientSessionExtension() {
}

void RTSPServerExtension::RTSPClientSessionExtension
::handleCmd_GET_PARAMETER(RTSPClientConnection* ourClientConnection, ServerMediaSubsession* subsession, char const* fullRequestStr) {
  setRTSPResponse(ourClientConnection, "200 OK", fOurSessionId, "my_special_parameter_value");
}

Then, in your application code, you'd create a new "RTSPServerExtension" by calling
	RTSPServerExtension* myRTSPServer = RTSPServerExtension::createNew( etc. );

Ross Finlayson
Live Networks, Inc.
http://www.live555.com/

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20130812/68057f03/attachment.html>


More information about the live-devel mailing list