testProgs/testOnDemandRTSPServer.cpp File Reference

#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

UsageEnvironmentenv
Boolean reuseFirstSource = False
Boolean iFramesOnly = False
static char newMatroskaDemuxWatchVariable
static MatroskaFileServerDemuxdemux


Function Documentation

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 }


Variable Documentation

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().

UsageEnvironment* env

Definition at line 24 of file testOnDemandRTSPServer.cpp.

Boolean iFramesOnly = False

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().

Boolean reuseFirstSource = False

Definition at line 29 of file testOnDemandRTSPServer.cpp.

Referenced by main().


Generated on Mon Apr 29 13:31:00 2013 for live by  doxygen 1.5.2