<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"><base href="x-msg://267/"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><blockquote type="cite"><div lang="EN-US" link="blue" vlink="purple" style="font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div class="WordSection1" style="page: WordSection1; "><div style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif; "><b><span style="font-size: 8pt; font-family: 'Courier New'; color: rgb(127, 0, 85); ">class</span></b><span style="font-size: 8pt; font-family: 'Courier New'; "> </span><span style="font-size: 8pt; font-family: 'Courier New'; color: rgb(0, 80, 50); ">RTSPServerExtensions</span><span style="font-size: 8pt; font-family: 'Courier New'; "><span class="Apple-converted-space"> </span>:</span><b><span style="font-size: 8pt; font-family: 'Courier New'; color: rgb(127, 0, 85); ">protected</span></b><span style="font-size: 8pt; font-family: 'Courier New'; "> </span><span style="font-size: 8pt; font-family: 'Courier New'; color: rgb(0, 80, 50); background-color: silver; background-position: initial initial; background-repeat: initial initial; ">RTSPServer</span></div></div></div></blockquote><div><br></div>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.)</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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)?</div><div><br></div><div>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:</div><div><br></div><div><div>class RTSPServerExtension: public RTSPServer {</div><div>public:</div><div>  static RTSPServerExtension* createNew(UsageEnvironment& env, Port rtspPort = 554,</div><div>                                                      UserAuthenticationDatabase* authDatabase = NULL,</div><div>                                                      unsigned reclamationTestSeconds = 65);</div><div><br></div><div>protected:</div><div>  RTSPServerExtension(UsageEnvironment& env,</div><div>                                    int ourSocket, Port ourPort,</div><div>                                    UserAuthenticationDatabase* authDatabase,</div><div>                                    unsigned reclamationTestSeconds);</div><div>      // called only by createNew();</div><div>  virtual ~RTSPServerExtension();</div><div><br></div><div>protected: // redefined virtual functions</div><div>  virtual RTSPClientSession* createNewClientSession(u_int32_t sessionId);</div><div><br></div><div>public: // should be protected, but some old compilers complain otherwise</div><div>  class RTSPClientSessionExtension: public RTSPServer::RTSPClientSession {</div><div>  public:</div><div>   RTSPClientSessionExtension(RTSPServer& ourServer, u_int32_t sessionId);</div><div>    virtual ~RTSPClientSessionExtension();</div><div><br></div><div>  protected: // redefined virtual functions</div><div>    virtual void handleCmd_GET_PARAMETER(RTSPClientConnection* ourClientConnection, ServerMediaSubsession* subsession, char const* fullRequestStr);</div><div>  };</div><div>};</div><div><br></div><div><br></div><div>And your implementation would look something like this:</div><div><br></div><div><div>RTSPServerExtension* RTSPServerExtension</div><div>::createNew(UsageEnvironment& env, Port rtspPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds) {</div><div>  int ourSocket = setUpOurSocket(env, rtspPort);</div><div>  if (ourSocket == -1) return NULL;</div><div><br></div><div>  return new RTSPServerExtension(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds);</div><div>}</div><div><br></div><div>RTSPServerExtension::RTSPServerExtension(UsageEnvironment& env,</div><div>                                         int ourSocket, Port rtspPort,</div><div>                                         UserAuthenticationDatabase* authDatabase,</div><div>                                         unsigned reclamationTestSeconds)</div><div>  : RTSPServer(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds) {</div><div>}</div><div><br></div><div>RTSPServerExtension::~RTSPServerExtension() {</div><div>}</div><div><br></div><div>RTSPServer::RTSPClientSession* RTSPServerExtension::createNewClientSession(u_int32_t sessionId) {</div><div>  return new RTSPServerExtension::RTSPClientSessionExtension(*this, sessionId);</div><div>}</div><div><br></div><div>RTSPServerExtension::RTSPClientSessionExtension</div><div>::RTSPClientSessionExtension(RTSPServer& ourServer, u_int32_t sessionId)</div><div>  : RTSPClientSession(ourServer, sessionId) {</div><div>}</div><div><br></div><div>RTSPServerExtension::RTSPClientSessionExtension</div><div>::~RTSPClientSessionExtension() {</div><div>}</div><div><br></div><div>void RTSPServerExtension::RTSPClientSessionExtension</div><div>::handleCmd_GET_PARAMETER(RTSPClientConnection* ourClientConnection, ServerMediaSubsession* subsession, char const* fullRequestStr) {</div><div>  setRTSPResponse(ourClientConnection, "200 OK", fOurSessionId, "my_special_parameter_value");</div><div>}</div></div></div><div><br></div><div>Then, in your application code, you'd create a new "RTSPServerExtension" by calling</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>RTSPServerExtension* myRTSPServer = RTSPServerExtension::createNew( etc. );</div><br><div apple-content-edited="true">
<span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; ">Ross Finlayson<br>Live Networks, Inc.<br><a href="http://www.live555.com/">http://www.live555.com/</a></span></span>
</div>
<br></body></html>