#include "liveMedia.hh"#include "BasicUsageEnvironment.hh"Include dependency graph for testOnDemandRTSPServer.cpp:

Go to the source code of this file.
Functions | |
| static void | announceStream (RTSPServer *rtspServer, ServerMediaSession *sms, char const *streamName, char const *inputFileName) |
| static void | onMatroskaDemuxCreation (MatroskaFileServerDemux *newDemux, void *) |
| int | main (int argc, char **argv) |
Variables | |
| UsageEnvironment * | env |
| Boolean | reuseFirstSource = False |
| Boolean | iFramesOnly = False |
| static char | newMatroskaDemuxWatchVariable |
| static MatroskaFileServerDemux * | demux |
| static void announceStream | ( | RTSPServer * | rtspServer, | |
| ServerMediaSession * | sms, | |||
| char const * | streamName, | |||
| char const * | inputFileName | |||
| ) | [static] |
Definition at line 373 of file testOnDemandRTSPServer.cpp.
References env, Medium::envir(), rtspServer, and RTSPServer::rtspURL().
Referenced by main().
00374 { 00375 char* url = rtspServer->rtspURL(sms); 00376 UsageEnvironment& env = rtspServer->envir(); 00377 env << "\n\"" << streamName << "\" stream, from the file \"" 00378 << inputFileName << "\"\n"; 00379 env << "Play this stream using the URL \"" << url << "\"\n"; 00380 delete[] url; 00381 }
| int main | ( | int | argc, | |
| char ** | argv | |||
| ) |
Definition at line 46 of file testOnDemandRTSPServer.cpp.
References RTSPServer::addServerMediaSession(), ServerMediaSession::addSubsession(), UserAuthenticationDatabase::addUserRecord(), announceStream(), MatroskaFileServerDemux::createNew(), MPEG1or2FileServerDemux::createNew(), ServerMediaSession::createNew(), RTSPServer::createNew(), BasicUsageEnvironment::createNew(), BasicTaskScheduler::createNew(), demux, TaskScheduler::doEventLoop(), env, exit, False, UsageEnvironment::getResultMsg(), RTSPServer::httpServerPortNum(), iFramesOnly, inputFileName, OutPacketBuffer::maxSize, newMatroskaDemuxWatchVariable, MatroskaFileServerDemux::newServerMediaSubsession(), NULL, onMatroskaDemuxCreation(), reuseFirstSource, rtspServer, RTSPServer::rtspURL(), RTSPServer::setUpTunnelingOverHTTP(), UsageEnvironment::taskScheduler(), and True.
00046 { 00047 // Begin by setting up our usage environment: 00048 TaskScheduler* scheduler = BasicTaskScheduler::createNew(); 00049 env = BasicUsageEnvironment::createNew(*scheduler); 00050 00051 UserAuthenticationDatabase* authDB = NULL; 00052 #ifdef ACCESS_CONTROL 00053 // To implement client access control to the RTSP server, do the following: 00054 authDB = new UserAuthenticationDatabase; 00055 authDB->addUserRecord("username1", "password1"); // replace these with real strings 00056 // Repeat the above with each <username>, <password> that you wish to allow 00057 // access to the server. 00058 #endif 00059 00060 // Create the RTSP server: 00061 RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554, authDB); 00062 if (rtspServer == NULL) { 00063 *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n"; 00064 exit(1); 00065 } 00066 00067 char const* descriptionString 00068 = "Session streamed by \"testOnDemandRTSPServer\""; 00069 00070 // Set up each of the possible streams that can be served by the 00071 // RTSP server. Each such stream is implemented using a 00072 // "ServerMediaSession" object, plus one or more 00073 // "ServerMediaSubsession" objects for each audio/video substream. 00074 00075 // A MPEG-4 video elementary stream: 00076 { 00077 char const* streamName = "mpeg4ESVideoTest"; 00078 char const* inputFileName = "test.m4e"; 00079 ServerMediaSession* sms 00080 = ServerMediaSession::createNew(*env, streamName, streamName, 00081 descriptionString); 00082 sms->addSubsession(MPEG4VideoFileServerMediaSubsession 00083 ::createNew(*env, inputFileName, reuseFirstSource)); 00084 rtspServer->addServerMediaSession(sms); 00085 00086 announceStream(rtspServer, sms, streamName, inputFileName); 00087 } 00088 00089 // A H.264 video elementary stream: 00090 { 00091 char const* streamName = "h264ESVideoTest"; 00092 char const* inputFileName = "test.264"; 00093 ServerMediaSession* sms 00094 = ServerMediaSession::createNew(*env, streamName, streamName, 00095 descriptionString); 00096 sms->addSubsession(H264VideoFileServerMediaSubsession 00097 ::createNew(*env, inputFileName, reuseFirstSource)); 00098 rtspServer->addServerMediaSession(sms); 00099 00100 announceStream(rtspServer, sms, streamName, inputFileName); 00101 } 00102 00103 // A MPEG-1 or 2 audio+video program stream: 00104 { 00105 char const* streamName = "mpeg1or2AudioVideoTest"; 00106 char const* inputFileName = "test.mpg"; 00107 // NOTE: This *must* be a Program Stream; not an Elementary Stream 00108 ServerMediaSession* sms 00109 = ServerMediaSession::createNew(*env, streamName, streamName, 00110 descriptionString); 00111 MPEG1or2FileServerDemux* demux 00112 = MPEG1or2FileServerDemux::createNew(*env, inputFileName, reuseFirstSource); 00113 sms->addSubsession(demux->newVideoServerMediaSubsession(iFramesOnly)); 00114 sms->addSubsession(demux->newAudioServerMediaSubsession()); 00115 rtspServer->addServerMediaSession(sms); 00116 00117 announceStream(rtspServer, sms, streamName, inputFileName); 00118 } 00119 00120 // A MPEG-1 or 2 video elementary stream: 00121 { 00122 char const* streamName = "mpeg1or2ESVideoTest"; 00123 char const* inputFileName = "testv.mpg"; 00124 // NOTE: This *must* be a Video Elementary Stream; not a Program Stream 00125 ServerMediaSession* sms 00126 = ServerMediaSession::createNew(*env, streamName, streamName, 00127 descriptionString); 00128 sms->addSubsession(MPEG1or2VideoFileServerMediaSubsession 00129 ::createNew(*env, inputFileName, reuseFirstSource, iFramesOnly)); 00130 rtspServer->addServerMediaSession(sms); 00131 00132 announceStream(rtspServer, sms, streamName, inputFileName); 00133 } 00134 00135 // A MP3 audio stream (actually, any MPEG-1 or 2 audio file will work): 00136 // To stream using 'ADUs' rather than raw MP3 frames, uncomment the following: 00137 //#define STREAM_USING_ADUS 1 00138 // To also reorder ADUs before streaming, uncomment the following: 00139 //#define INTERLEAVE_ADUS 1 00140 // (For more information about ADUs and interleaving, 00141 // see <http://www.live555.com/rtp-mp3/>) 00142 { 00143 char const* streamName = "mp3AudioTest"; 00144 char const* inputFileName = "test.mp3"; 00145 ServerMediaSession* sms 00146 = ServerMediaSession::createNew(*env, streamName, streamName, 00147 descriptionString); 00148 Boolean useADUs = False; 00149 Interleaving* interleaving = NULL; 00150 #ifdef STREAM_USING_ADUS 00151 useADUs = True; 00152 #ifdef INTERLEAVE_ADUS 00153 unsigned char interleaveCycle[] = {0,2,1,3}; // or choose your own... 00154 unsigned const interleaveCycleSize 00155 = (sizeof interleaveCycle)/(sizeof (unsigned char)); 00156 interleaving = new Interleaving(interleaveCycleSize, interleaveCycle); 00157 #endif 00158 #endif 00159 sms->addSubsession(MP3AudioFileServerMediaSubsession 00160 ::createNew(*env, inputFileName, reuseFirstSource, 00161 useADUs, interleaving)); 00162 rtspServer->addServerMediaSession(sms); 00163 00164 announceStream(rtspServer, sms, streamName, inputFileName); 00165 } 00166 00167 // A WAV audio stream: 00168 { 00169 char const* streamName = "wavAudioTest"; 00170 char const* inputFileName = "test.wav"; 00171 ServerMediaSession* sms 00172 = ServerMediaSession::createNew(*env, streamName, streamName, 00173 descriptionString); 00174 // To convert 16-bit PCM data to 8-bit u-law, prior to streaming, 00175 // change the following to True: 00176 Boolean convertToULaw = False; 00177 sms->addSubsession(WAVAudioFileServerMediaSubsession 00178 ::createNew(*env, inputFileName, reuseFirstSource, convertToULaw)); 00179 rtspServer->addServerMediaSession(sms); 00180 00181 announceStream(rtspServer, sms, streamName, inputFileName); 00182 } 00183 00184 // An AMR audio stream: 00185 { 00186 char const* streamName = "amrAudioTest"; 00187 char const* inputFileName = "test.amr"; 00188 ServerMediaSession* sms 00189 = ServerMediaSession::createNew(*env, streamName, streamName, 00190 descriptionString); 00191 sms->addSubsession(AMRAudioFileServerMediaSubsession 00192 ::createNew(*env, inputFileName, reuseFirstSource)); 00193 rtspServer->addServerMediaSession(sms); 00194 00195 announceStream(rtspServer, sms, streamName, inputFileName); 00196 } 00197 00198 // A 'VOB' file (e.g., from an unencrypted DVD): 00199 { 00200 char const* streamName = "vobTest"; 00201 char const* inputFileName = "test.vob"; 00202 ServerMediaSession* sms 00203 = ServerMediaSession::createNew(*env, streamName, streamName, 00204 descriptionString); 00205 // Note: VOB files are MPEG-2 Program Stream files, but using AC-3 audio 00206 MPEG1or2FileServerDemux* demux 00207 = MPEG1or2FileServerDemux::createNew(*env, inputFileName, reuseFirstSource); 00208 sms->addSubsession(demux->newVideoServerMediaSubsession(iFramesOnly)); 00209 sms->addSubsession(demux->newAC3AudioServerMediaSubsession()); 00210 rtspServer->addServerMediaSession(sms); 00211 00212 announceStream(rtspServer, sms, streamName, inputFileName); 00213 } 00214 00215 // A MPEG-2 Transport Stream: 00216 { 00217 char const* streamName = "mpeg2TransportStreamTest"; 00218 char const* inputFileName = "test.ts"; 00219 char const* indexFileName = "test.tsx"; 00220 ServerMediaSession* sms 00221 = ServerMediaSession::createNew(*env, streamName, streamName, 00222 descriptionString); 00223 sms->addSubsession(MPEG2TransportFileServerMediaSubsession 00224 ::createNew(*env, inputFileName, indexFileName, reuseFirstSource)); 00225 rtspServer->addServerMediaSession(sms); 00226 00227 announceStream(rtspServer, sms, streamName, inputFileName); 00228 } 00229 00230 // An AAC audio stream (ADTS-format file): 00231 { 00232 char const* streamName = "aacAudioTest"; 00233 char const* inputFileName = "test.aac"; 00234 ServerMediaSession* sms 00235 = ServerMediaSession::createNew(*env, streamName, streamName, 00236 descriptionString); 00237 sms->addSubsession(ADTSAudioFileServerMediaSubsession 00238 ::createNew(*env, inputFileName, reuseFirstSource)); 00239 rtspServer->addServerMediaSession(sms); 00240 00241 announceStream(rtspServer, sms, streamName, inputFileName); 00242 } 00243 00244 // A DV video stream: 00245 { 00246 // First, make sure that the RTPSinks' buffers will be large enough to handle the huge size of DV frames (as big as 288000). 00247 OutPacketBuffer::maxSize = 300000; 00248 00249 char const* streamName = "dvVideoTest"; 00250 char const* inputFileName = "test.dv"; 00251 ServerMediaSession* sms 00252 = ServerMediaSession::createNew(*env, streamName, streamName, 00253 descriptionString); 00254 sms->addSubsession(DVVideoFileServerMediaSubsession 00255 ::createNew(*env, inputFileName, reuseFirstSource)); 00256 rtspServer->addServerMediaSession(sms); 00257 00258 announceStream(rtspServer, sms, streamName, inputFileName); 00259 } 00260 00261 // A AC3 video elementary stream: 00262 { 00263 char const* streamName = "ac3AudioTest"; 00264 char const* inputFileName = "test.ac3"; 00265 ServerMediaSession* sms 00266 = ServerMediaSession::createNew(*env, streamName, streamName, 00267 descriptionString); 00268 00269 sms->addSubsession(AC3AudioFileServerMediaSubsession 00270 ::createNew(*env, inputFileName, reuseFirstSource)); 00271 00272 rtspServer->addServerMediaSession(sms); 00273 00274 announceStream(rtspServer, sms, streamName, inputFileName); 00275 } 00276 00277 // A Matroska ('.mkv') file, with video+audio+subtitle streams: 00278 { 00279 char const* streamName = "matroskaFileTest"; 00280 char const* inputFileName = "test.mkv"; 00281 ServerMediaSession* sms 00282 = ServerMediaSession::createNew(*env, streamName, streamName, 00283 descriptionString); 00284 00285 newMatroskaDemuxWatchVariable = 0; 00286 MatroskaFileServerDemux::createNew(*env, inputFileName, onMatroskaDemuxCreation, NULL); 00287 env->taskScheduler().doEventLoop(&newMatroskaDemuxWatchVariable); 00288 00289 Boolean sessionHasTracks = False; 00290 ServerMediaSubsession* smss; 00291 while ((smss = demux->newServerMediaSubsession()) != NULL) { 00292 sms->addSubsession(smss); 00293 sessionHasTracks = True; 00294 } 00295 if (sessionHasTracks) { 00296 rtspServer->addServerMediaSession(sms); 00297 } 00298 // otherwise, because the stream has no tracks, we don't add a ServerMediaSession to the server. 00299 00300 announceStream(rtspServer, sms, streamName, inputFileName); 00301 } 00302 00303 // A WebM ('.webm') file, with video(VP8)+audio(Vorbis) streams: 00304 // (Note: ".webm' files are special types of Matroska files, so we use the same code as the Matroska ('.mkv') file code above.) 00305 { 00306 char const* streamName = "webmFileTest"; 00307 char const* inputFileName = "test.webm"; 00308 ServerMediaSession* sms 00309 = ServerMediaSession::createNew(*env, streamName, streamName, 00310 descriptionString); 00311 00312 newMatroskaDemuxWatchVariable = 0; 00313 MatroskaFileServerDemux::createNew(*env, inputFileName, onMatroskaDemuxCreation, NULL); 00314 env->taskScheduler().doEventLoop(&newMatroskaDemuxWatchVariable); 00315 00316 Boolean sessionHasTracks = False; 00317 ServerMediaSubsession* smss; 00318 while ((smss = demux->newServerMediaSubsession()) != NULL) { 00319 sms->addSubsession(smss); 00320 sessionHasTracks = True; 00321 } 00322 if (sessionHasTracks) { 00323 rtspServer->addServerMediaSession(sms); 00324 } 00325 // otherwise, because the stream has no tracks, we don't add a ServerMediaSession to the server. 00326 00327 announceStream(rtspServer, sms, streamName, inputFileName); 00328 } 00329 00330 // A MPEG-2 Transport Stream, coming from a live UDP (raw-UDP or RTP/UDP) source: 00331 { 00332 char const* streamName = "mpeg2TransportStreamFromUDPSourceTest"; 00333 char const* inputAddressStr = "239.255.42.42"; 00334 // This causes the server to take its input from the stream sent by the "testMPEG2TransportStreamer" demo application. 00335 // (Note: If the input UDP source is unicast rather than multicast, then change this to NULL.) 00336 portNumBits const inputPortNum = 1234; 00337 // This causes the server to take its input from the stream sent by the "testMPEG2TransportStreamer" demo application. 00338 Boolean const inputStreamIsRawUDP = False; 00339 ServerMediaSession* sms 00340 = ServerMediaSession::createNew(*env, streamName, streamName, 00341 descriptionString); 00342 sms->addSubsession(MPEG2TransportUDPServerMediaSubsession 00343 ::createNew(*env, inputAddressStr, inputPortNum, inputStreamIsRawUDP)); 00344 rtspServer->addServerMediaSession(sms); 00345 00346 char* url = rtspServer->rtspURL(sms); 00347 *env << "\n\"" << streamName << "\" stream, from a UDP Transport Stream input source \n\t("; 00348 if (inputAddressStr != NULL) { 00349 *env << "IP multicast address " << inputAddressStr << ","; 00350 } else { 00351 *env << "unicast;"; 00352 } 00353 *env << " port " << inputPortNum << ")\n"; 00354 *env << "Play this stream using the URL \"" << url << "\"\n"; 00355 delete[] url; 00356 } 00357 00358 // Also, attempt to create a HTTP server for RTSP-over-HTTP tunneling. 00359 // Try first with the default HTTP port (80), and then with the alternative HTTP 00360 // port numbers (8000 and 8080). 00361 00362 if (rtspServer->setUpTunnelingOverHTTP(80) || rtspServer->setUpTunnelingOverHTTP(8000) || rtspServer->setUpTunnelingOverHTTP(8080)) { 00363 *env << "\n(We use port " << rtspServer->httpServerPortNum() << " for optional RTSP-over-HTTP tunneling.)\n"; 00364 } else { 00365 *env << "\n(RTSP-over-HTTP tunneling is not available.)\n"; 00366 } 00367 00368 env->taskScheduler().doEventLoop(); // does not return 00369 00370 return 0; // only to prevent compiler warning 00371 }
| static void onMatroskaDemuxCreation | ( | MatroskaFileServerDemux * | newDemux, | |
| void * | ||||
| ) | [static] |
Definition at line 41 of file testOnDemandRTSPServer.cpp.
References demux, and newMatroskaDemuxWatchVariable.
Referenced by createNewSMS(), and main().
00041 { 00042 demux = newDemux; 00043 newMatroskaDemuxWatchVariable = 1; 00044 }
MatroskaFileServerDemux* demux [static] |
Definition at line 40 of file testOnDemandRTSPServer.cpp.
Referenced by MPEG1or2Demux::continueReadProcessing(), VP8VideoMatroskaFileServerMediaSubsession::createNew(), VorbisAudioMatroskaFileServerMediaSubsession::createNew(), T140TextMatroskaFileServerMediaSubsession::createNew(), MPEG1or2DemuxedServerMediaSubsession::createNew(), MP3AudioMatroskaFileServerMediaSubsession::createNew(), H264VideoMatroskaFileServerMediaSubsession::createNew(), AC3AudioMatroskaFileServerMediaSubsession::createNew(), AACAudioMatroskaFileServerMediaSubsession::createNew(), createNewSMS(), MPEG1or2Demux::handleClosure(), main(), MatroskaFile::newDemux(), onMatroskaDemuxCreation(), MatroskaFile::removeDemux(), and MatroskaFile::~MatroskaFile().
Definition at line 24 of file testOnDemandRTSPServer.cpp.
Definition at line 34 of file testOnDemandRTSPServer.cpp.
char newMatroskaDemuxWatchVariable [static] |
Definition at line 39 of file testOnDemandRTSPServer.cpp.
Referenced by createNewSMS(), main(), and onMatroskaDemuxCreation().
1.5.2