RtspHelper.h

Go to the documentation of this file.
00001 
00034 #pragma once
00035 
00036 // STL
00037 #include <string>
00038 #include <vector>
00039 
00040 // liveMedia
00041 #include <liveMedia.hh>
00042 #include <GroupsockHelper.hh>
00043 
00045 class RtspHelper
00046 {
00047 public:
00048 
00049         static bool createMediaSession(const std::string& sUrl, RTSPClient* pRtspClient, MediaSession** pMediaSession, std::string& sResult, int nTimeOut = -1)
00050         {
00051                 UsageEnvironment* pEnv = &(pRtspClient->envir());
00052 
00053                 const char* szUrl = sUrl.c_str();
00054 
00055                 // Get options response
00056                 char* optionsResponse = pRtspClient->sendOptionsCmd(szUrl, NULL, NULL, NULL, nTimeOut);
00057                 *pEnv << "RTSP Options response: " << optionsResponse << "\r\n";
00058                 delete[] optionsResponse;
00059 
00060                 // Get SDP description
00061                 char* sdpDescription = pRtspClient->describeURL(szUrl, NULL, false, nTimeOut);
00062                 if (sdpDescription == NULL) 
00063                 {
00064                         sResult = "Failed to get a SDP description from URL \"" + sUrl + "\": " + std::string(pEnv->getResultMsg());
00065                         return false;
00066                 }
00067 
00068                 *pEnv << "Opened URL \"" << szUrl << "\", returning a SDP description:\n" << sdpDescription << "\n";
00069                 unsigned statusCode = pRtspClient->describeStatus();
00070                 *pEnv << "Status code: " << statusCode << "\n";
00071 
00072                 // Create a media session object from this SDP description:
00073                 *pMediaSession = MediaSession::createNew(*pEnv, sdpDescription);
00074                 delete[] sdpDescription;
00075                 if (*pMediaSession == NULL) 
00076                 {
00077                         sResult = "Failed to create a MediaSession object from the SDP description: " + std::string(pEnv->getResultMsg());
00078                         return false;
00079                 } 
00080                 else if (!(*pMediaSession)->hasSubsessions()) 
00081                 {
00082                         sResult = "This session has no media subsessions (i.e., \"m=\" lines)";
00083                         return false;
00084                 }
00085                 return true;
00086         }
00087 
00088         static bool createRtpSource(UsageEnvironment* pEnv, MediaSubsession* pSubsession)
00089         {
00090                 if (!pSubsession->initiate()) 
00091                 {
00092                         *pEnv << "Unable to create receiver for \"" << pSubsession->mediumName() << "/" << pSubsession->codecName() << "\" subsession: " << pEnv->getResultMsg() << "\n"; 
00093                         return false;
00094                 } 
00095                 else 
00096                 {
00097                         *pEnv << "Created receiver for \"" << pSubsession->mediumName() << "/" << pSubsession->codecName() << "\" subsession (client ports " << pSubsession->clientPortNum() << "-" << pSubsession->clientPortNum()+1 << ")\n";
00098                         if (pSubsession->rtpSource() != NULL) 
00099                         {
00100                                 //TOREVISE
00101                                 // Because we're saving the incoming data, rather than playing
00102                                 // it in real time, allow an especially large time threshold
00103                                 // (1 second) for reordering misordered incoming packets:
00104                                 unsigned const thresh = 1000000; // 1 second 
00105                                 pSubsession->rtpSource()->setPacketReorderingThresholdTime(thresh);
00106 
00107                                 int socketInputBufferSize = 0;
00108                                 // TOREMOVE: Left over from Live555 examples
00109                                 if (socketInputBufferSize > 0) 
00110                                 {
00111                                         // Set the RTP source's input buffer size as specified:
00112                                         int socketNum = pSubsession->rtpSource()->RTPgs()->socketNum();
00113                                         unsigned curBufferSize = getReceiveBufferSize(*pEnv, socketNum);
00114                                         unsigned newBufferSize = setReceiveBufferTo(*pEnv, socketNum, socketInputBufferSize);
00115                                         *pEnv << "Changed socket receive buffer size for the \"" << pSubsession->mediumName() << "/" << pSubsession->codecName() << "\" subsession from " << curBufferSize << " to " << newBufferSize << " bytes\n";
00116                                 }
00117                         }
00118                         return true;
00119                 }
00120         }
00121 
00122         static bool createRtpSources(UsageEnvironment* pEnv, MediaSession* pSession)
00123         {
00124                 Boolean madeProgress = False;
00125                 MediaSubsessionIterator iter(*pSession);
00126                 MediaSubsession *pSubsession;
00127                 while ((pSubsession = iter.next()) != NULL) 
00128                 {
00129                         if (createRtpSource(pEnv, pSubsession))
00130                         {
00131                                 madeProgress = true;
00132                         }
00133                 }
00134                 return madeProgress;
00135         }
00136 
00137         static bool setupStream( RTSPClient* pRtspClient, MediaSubsession* pSubsession, bool bStreamUsingTCP)
00138         {
00139                 UsageEnvironment* pEnv = &(pRtspClient->envir());
00140                 if (pSubsession->clientPortNum() == 0) return false; // port # was not set
00141 
00142                 if (!pRtspClient->setupMediaSubsession(*pSubsession, False, bStreamUsingTCP)) 
00143                 {
00144                         *pEnv << "Failed to setup \"" << pSubsession->mediumName() << "/" << pSubsession->codecName() << "\" subsession: " << pEnv->getResultMsg() << "\n";
00145                         return false;
00146                 } 
00147                 else 
00148                 {
00149                         *pEnv << "Setup \"" << pSubsession->mediumName() << "/" << pSubsession->codecName()  << "\" subsession (client ports " << pSubsession->clientPortNum()<< "-" << pSubsession->clientPortNum()+1 << ")\n";
00150                         return true;
00151                 }
00152         }
00153         static bool setupStreams(RTSPClient* pRtspClient, MediaSession* pSession, bool bStreamUsingTCP)
00154         {
00155                 //UsageEnvironment* pEnv = &(pSession->envir());
00156                 Boolean madeProgress = False;
00157                 MediaSubsessionIterator iter(*pSession);
00158                 MediaSubsession *pSubsession;
00159                 while ((pSubsession = iter.next()) != NULL) 
00160                 {
00161                         if (setupStream(pRtspClient, pSubsession, bStreamUsingTCP))
00162                         {
00163                                 madeProgress = True;
00164                         }
00165                 }
00166                 return madeProgress;
00167         }
00168 
00169         static void shutdownMediaSession(RTSPClient* pRtspClient, MediaSession* pMediaSession)
00170         {
00171                 if (pMediaSession)
00172                 {
00173                         // Close subsessions
00174                         MediaSubsessionIterator iter(*pMediaSession);
00175                         MediaSubsession* pSubsession;
00176                         while ((pSubsession = iter.next()) != NULL) 
00177                         {
00178                                 Medium::close(pSubsession->sink);
00179                                 pSubsession->sink = NULL;
00180                         }
00181                         // Teardown session
00182                         if (pRtspClient) pRtspClient->teardownMediaSession(*pMediaSession);
00183                         // Close session and client
00184                         Medium::close(pMediaSession);
00185                         if (pRtspClient) Medium::close(pRtspClient);
00186                 }
00187         }
00188 };

Generated on Fri Mar 13 14:12:38 2009 for RTVC by  doxygen 1.5.3