00001
00034 #pragma once
00035
00036
00037 #include <string>
00038 #include <vector>
00039
00040
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
00056 char* optionsResponse = pRtspClient->sendOptionsCmd(szUrl, NULL, NULL, NULL, nTimeOut);
00057 *pEnv << "RTSP Options response: " << optionsResponse << "\r\n";
00058 delete[] optionsResponse;
00059
00060
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
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
00101
00102
00103
00104 unsigned const thresh = 1000000;
00105 pSubsession->rtpSource()->setPacketReorderingThresholdTime(thresh);
00106
00107 int socketInputBufferSize = 0;
00108
00109 if (socketInputBufferSize > 0)
00110 {
00111
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;
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
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
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
00182 if (pRtspClient) pRtspClient->teardownMediaSession(*pMediaSession);
00183
00184 Medium::close(pMediaSession);
00185 if (pRtspClient) Medium::close(pRtspClient);
00186 }
00187 }
00188 };