<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><base href="x-msg://1815/"><style><!--
/* Font Definitions */
@font-face
        {font-family:Helvetica;
        panose-1:2 11 6 4 2 2 2 2 2 4;}
@font-face
        {font-family:Helvetica;
        panose-1:2 11 6 4 2 2 2 2 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.apple-style-span
        {mso-style-name:apple-style-span;}
span.apple-tab-span
        {mso-style-name:apple-tab-span;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-US link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in'><p class=MsoNormal><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> live-devel-bounces@ns.live555.com [mailto:live-devel-bounces@ns.live555.com] <b>On Behalf Of </b>Ross Finlayson<br><b>Sent:</b> Saturday, November 26, 2011 1:35 PM<br><b>To:</b> LIVE555 Streaming Media - development & use<br><b>Subject:</b> Re: [Live-devel] problems moving to asynchronous rtsp interface<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p><div><blockquote style='margin-top:5.0pt;margin-bottom:5.0pt'><div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'>I just started trying to upgrade our code to use the asynchronous interface and I am a bit perplexed at the mix of C and C++.  In other libraries the callbacks generally have a void pointer to clientData or ‘instance’ or something like that which allows me to pass the ‘this’ pointer, cast it, to the class and access all the particular instances’ members.  In the openRTSP and PlayCommon code I see the signatures for the callbacks are hard coded to foo(RTSPClient::responsehandler*,int,char*).<o:p></o:p></span></p></div></div></blockquote><div><p class=MsoNormal><o:p> </o:p></p></div><p class=MsoNormal>The "openRTSP.cpp"/"playCommon.cpp" code, unfortunately, does not provide the greatest example of how to use the asynchronous "RTSPClient" interface, precisely because it uses a single, global "RTSPClient*" variable (called "ourRTSPClient").  (Also, because "playCommon.cpp" shares code with a separate application called "playSIP".)<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>The key thing to note is that the "RTSPClient:responseHandler()" functions all have a "RTSPClient*" as their first parameter.  When the response handler gets called, its first parameter will be (a pointer to) the "RTSPClient" object that made the request.  In our "playCommon.cpp" code, the first parameter to our response handler functions ends up not being needed, because its value will - in this case - be the same as our global variable "ourRTSPClient".  In your case, however, you will want to use this first parameter, because it will tell you which particular "RTSPClient" object made the request.<o:p></o:p></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>>> I realized that and am working on the subclass from RTSPClient idea. Because there is a LOT of other instance data, just like in the openRTSP example, thre is a LOT of global information.  But I am finding that the RTSPClient was not really designed to be subclassed. The gotcha I have now is, although it does nothing but set values in it’s constructor, I cannot instanitiate my subclass without an initializer for the RTSPClient base class, but then I cannot call setBaseURL() for example, later when I know all the info.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p></div><div><p class=MsoNormal><o:p> </o:p></p><div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'>For example. This is what causes the ourRTSPClient in the example to be a Global variable. I need to have this as a class member variable, and perhaps do something like this….<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'> <o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:9.5pt;font-family:Consolas'>getOptions(RTSPClient::responseHandler* afterFunc, void* clientData) {</span><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:9.5pt;font-family:Consolas'>       myClass * instancePTR = (myClass *) clientData;</span><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:9.5pt;font-family:Consolas'>              instancePTR->ourClient_->sendOptionsCommand(instancePTR, ourAuthenticator, clientData);</span><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:9.5pt;font-family:Consolas'>        }  </span><span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'><o:p></o:p></span></p></div></div><div><p class=MsoNormal><o:p> </o:p></p></div><p class=MsoNormal>No, this won't work, because the signature of your call to "RTSPClient::sendOptionsCommand()" is all wrong.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Instead, don't define or call a "getOptions()" function at all.  Instead just call:<o:p></o:p></p></div><div><p class=MsoNormal><span class=apple-tab-span>            </span>instancePTR->ourClient->sendOptionsCommand(continueAfterOPTIONS, ourAuthenticator);<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>And then, when the "continueAfterOPTIONS()" response handler later gets called, its first parameter will be "instancePTR->ourClient" - i.e., a "RTSPClient*".<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>If you need more information from this "RTSPClient*" pointer (e.g., in your case, to identify it's "myClass*" parent), then you can do so by subclassing "RTSPClient", and putting the information that you want in a subclass member field.<o:p></o:p></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>See above why this is difficult.<o:p></o:p></span></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal><br><br><o:p></o:p></p><div><div><p class=MsoNormal><span style='font-size:9.5pt;font-family:Consolas'>What is the best way to use these callbacks in a multi threaded (multiple UsageEnvironments) c++ program.?</span><o:p></o:p></p></div></div><div><p class=MsoNormal><o:p> </o:p></p></div></div><p class=MsoNormal style='margin-bottom:12.0pt'>You do realize, I hope, that the use of the asynchronous "RTSPClient" interface makes it even less necessary to use multiple threads.  (If you use the asynchronous interface, you can access multiple RTSP streams concurrently from a single thread (running a single event loop).)  But if you insist on using multiple threads (something that I still don't recommend, even though it's possible), you can do so provided that you use a separate "TaskScheduler" and "UsageEnvironment" for each.  Note that - if you wish - you can call "->envir()" on your response handlers' "RTSPClient*" first parameter, if you need to find out which "UsageEnvironment" - and thus which thread - it is using.<o:p></o:p></p><p class=MsoNormal style='margin-bottom:12.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal style='margin-bottom:12.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Yes but I am trying to upgrade to the newer interface without breaking everthing all at once.  Especially under the threat of impending removal!<o:p></o:p></span></p><p class=MsoNormal style='margin-bottom:12.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><div><p class=MsoNormal><span class=apple-style-span><span style='font-size:13.5pt;font-family:"Helvetica","sans-serif";color:black'>Ross Finlayson</span></span><span style='font-size:13.5pt;font-family:"Helvetica","sans-serif";color:black'><br><span class=apple-style-span>Live Networks, Inc.</span><br><span class=apple-style-span><a href="http://www.live555.com/">http://www.live555.com/</a></span></span> <o:p></o:p></p></div><p class=MsoNormal><o:p> </o:p></p></div></body></html>