testProgs/testOnDemandRTSPServer.cpp

Go to the documentation of this file.
00001 /**********
00002 This library is free software; you can redistribute it and/or modify it under
00003 the terms of the GNU Lesser General Public License as published by the
00004 Free Software Foundation; either version 2.1 of the License, or (at your
00005 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
00006 
00007 This library is distributed in the hope that it will be useful, but WITHOUT
00008 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
00010 more details.
00011 
00012 You should have received a copy of the GNU Lesser General Public License
00013 along with this library; if not, write to the Free Software Foundation, Inc.,
00014 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
00015 **********/
00016 // Copyright (c) 1996-2010, Live Networks, Inc.  All rights reserved
00017 // A test program that demonstrates how to stream - via unicast RTP
00018 // - various kinds of file on demand, using a built-in RTSP server.
00019 // main program
00020 
00021 #include "liveMedia.hh"
00022 #include "BasicUsageEnvironment.hh"
00023 
00024 UsageEnvironment* env;
00025 
00026 // To make the second and subsequent client for each stream reuse the same
00027 // input stream as the first client (rather than playing the file from the
00028 // start for each client), change the following "False" to "True":
00029 Boolean reuseFirstSource = False;
00030 
00031 // To stream *only* MPEG-1 or 2 video "I" frames
00032 // (e.g., to reduce network bandwidth),
00033 // change the following "False" to "True":
00034 Boolean iFramesOnly = False;
00035 
00036 static void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,
00037                            char const* streamName, char const* inputFileName); // fwd
00038 
00039 int main(int argc, char** argv) {
00040   // Begin by setting up our usage environment:
00041   TaskScheduler* scheduler = BasicTaskScheduler::createNew();
00042   env = BasicUsageEnvironment::createNew(*scheduler);
00043 
00044   UserAuthenticationDatabase* authDB = NULL;
00045 #ifdef ACCESS_CONTROL
00046   // To implement client access control to the RTSP server, do the following:
00047   authDB = new UserAuthenticationDatabase;
00048   authDB->addUserRecord("username1", "password1"); // replace these with real strings
00049   // Repeat the above with each <username>, <password> that you wish to allow
00050   // access to the server.
00051 #endif
00052 
00053   // Create the RTSP server:
00054   RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554, authDB);
00055   if (rtspServer == NULL) {
00056     *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
00057     exit(1);
00058   }
00059 
00060   char const* descriptionString
00061     = "Session streamed by \"testOnDemandRTSPServer\"";
00062 
00063   // Set up each of the possible streams that can be served by the
00064   // RTSP server.  Each such stream is implemented using a
00065   // "ServerMediaSession" object, plus one or more
00066   // "ServerMediaSubsession" objects for each audio/video substream.
00067 
00068   // A MPEG-4 video elementary stream:
00069   {
00070     char const* streamName = "mpeg4ESVideoTest";
00071     char const* inputFileName = "test.m4e";
00072     ServerMediaSession* sms
00073       = ServerMediaSession::createNew(*env, streamName, streamName,
00074                                       descriptionString);
00075     sms->addSubsession(MPEG4VideoFileServerMediaSubsession
00076                        ::createNew(*env, inputFileName, reuseFirstSource));
00077     rtspServer->addServerMediaSession(sms);
00078 
00079     announceStream(rtspServer, sms, streamName, inputFileName);
00080   }
00081 
00082   // A MPEG-1 or 2 audio+video program stream:
00083   {
00084     char const* streamName = "mpeg1or2AudioVideoTest";
00085     char const* inputFileName = "test.mpg";
00086     // NOTE: This *must* be a Program Stream; not an Elementary Stream
00087     ServerMediaSession* sms
00088       = ServerMediaSession::createNew(*env, streamName, streamName,
00089                                       descriptionString);
00090     MPEG1or2FileServerDemux* demux
00091       = MPEG1or2FileServerDemux::createNew(*env, inputFileName, reuseFirstSource);
00092     sms->addSubsession(demux->newVideoServerMediaSubsession(iFramesOnly));
00093     sms->addSubsession(demux->newAudioServerMediaSubsession());
00094     rtspServer->addServerMediaSession(sms);
00095 
00096     announceStream(rtspServer, sms, streamName, inputFileName);
00097   }
00098 
00099   // A MPEG-1 or 2 video elementary stream:
00100   {
00101     char const* streamName = "mpeg1or2ESVideoTest";
00102     char const* inputFileName = "testv.mpg";
00103     // NOTE: This *must* be a Video Elementary Stream; not a Program Stream
00104     ServerMediaSession* sms
00105       = ServerMediaSession::createNew(*env, streamName, streamName,
00106                                       descriptionString);
00107     sms->addSubsession(MPEG1or2VideoFileServerMediaSubsession
00108                ::createNew(*env, inputFileName, reuseFirstSource, iFramesOnly));
00109     rtspServer->addServerMediaSession(sms);
00110 
00111     announceStream(rtspServer, sms, streamName, inputFileName);
00112   }
00113 
00114   // A MP3 audio stream (actually, any MPEG-1 or 2 audio file will work):
00115   // To stream using 'ADUs' rather than raw MP3 frames, uncomment the following:
00116 //#define STREAM_USING_ADUS 1
00117   // To also reorder ADUs before streaming, uncomment the following:
00118 //#define INTERLEAVE_ADUS 1
00119   // (For more information about ADUs and interleaving,
00120   //  see <http://www.live555.com/rtp-mp3/>)
00121   {
00122     char const* streamName = "mp3AudioTest";
00123     char const* inputFileName = "test.mp3";
00124     ServerMediaSession* sms
00125       = ServerMediaSession::createNew(*env, streamName, streamName,
00126                                       descriptionString);
00127     Boolean useADUs = False;
00128     Interleaving* interleaving = NULL;
00129 #ifdef STREAM_USING_ADUS
00130     useADUs = True;
00131 #ifdef INTERLEAVE_ADUS
00132     unsigned char interleaveCycle[] = {0,2,1,3}; // or choose your own...
00133     unsigned const interleaveCycleSize
00134       = (sizeof interleaveCycle)/(sizeof (unsigned char));
00135     interleaving = new Interleaving(interleaveCycleSize, interleaveCycle);
00136 #endif
00137 #endif
00138     sms->addSubsession(MP3AudioFileServerMediaSubsession
00139                        ::createNew(*env, inputFileName, reuseFirstSource,
00140                                    useADUs, interleaving));
00141     rtspServer->addServerMediaSession(sms);
00142 
00143     announceStream(rtspServer, sms, streamName, inputFileName);
00144   }
00145 
00146   // A WAV audio stream:
00147   {
00148     char const* streamName = "wavAudioTest";
00149     char const* inputFileName = "test.wav";
00150     ServerMediaSession* sms
00151       = ServerMediaSession::createNew(*env, streamName, streamName,
00152                                       descriptionString);
00153     // To convert 16-bit PCM data to 8-bit u-law, prior to streaming,
00154     // change the following to True:
00155     Boolean convertToULaw = False;
00156     sms->addSubsession(WAVAudioFileServerMediaSubsession
00157                ::createNew(*env, inputFileName, reuseFirstSource, convertToULaw));
00158     rtspServer->addServerMediaSession(sms);
00159 
00160     announceStream(rtspServer, sms, streamName, inputFileName);
00161   }
00162 
00163   // An AMR audio stream:
00164   {
00165     char const* streamName = "amrAudioTest";
00166     char const* inputFileName = "test.amr";
00167     ServerMediaSession* sms
00168       = ServerMediaSession::createNew(*env, streamName, streamName,
00169                                       descriptionString);
00170     sms->addSubsession(AMRAudioFileServerMediaSubsession
00171                        ::createNew(*env, inputFileName, reuseFirstSource));
00172     rtspServer->addServerMediaSession(sms);
00173 
00174     announceStream(rtspServer, sms, streamName, inputFileName);
00175   }
00176 
00177   // A 'VOB' file (e.g., from an unencrypted DVD):
00178   {
00179     char const* streamName = "vobTest";
00180     char const* inputFileName = "test.vob";
00181     ServerMediaSession* sms
00182       = ServerMediaSession::createNew(*env, streamName, streamName,
00183                                       descriptionString);
00184     // Note: VOB files are MPEG-2 Program Stream files, but using AC-3 audio
00185     MPEG1or2FileServerDemux* demux
00186       = MPEG1or2FileServerDemux::createNew(*env, inputFileName, reuseFirstSource);
00187     sms->addSubsession(demux->newVideoServerMediaSubsession(iFramesOnly));
00188     sms->addSubsession(demux->newAC3AudioServerMediaSubsession());
00189     rtspServer->addServerMediaSession(sms);
00190 
00191     announceStream(rtspServer, sms, streamName, inputFileName);
00192   }
00193 
00194   // A MPEG-2 Transport Stream:
00195   {
00196     char const* streamName = "mpeg2TransportStreamTest";
00197     char const* inputFileName = "test.ts";
00198     char const* indexFileName = "test.tsx";
00199     ServerMediaSession* sms
00200       = ServerMediaSession::createNew(*env, streamName, streamName,
00201                                       descriptionString);
00202     sms->addSubsession(MPEG2TransportFileServerMediaSubsession
00203                        ::createNew(*env, inputFileName, indexFileName, reuseFirstSource));
00204     rtspServer->addServerMediaSession(sms);
00205 
00206     announceStream(rtspServer, sms, streamName, inputFileName);
00207   }
00208 
00209   // An AAC audio stream (ADTS-format file):
00210   {
00211     char const* streamName = "aacAudioTest";
00212     char const* inputFileName = "test.aac";
00213     ServerMediaSession* sms
00214       = ServerMediaSession::createNew(*env, streamName, streamName,
00215                                       descriptionString);
00216     sms->addSubsession(ADTSAudioFileServerMediaSubsession
00217                        ::createNew(*env, inputFileName, reuseFirstSource));
00218     rtspServer->addServerMediaSession(sms);
00219 
00220     announceStream(rtspServer, sms, streamName, inputFileName);
00221   }
00222 
00223   // A DV video stream:
00224   {
00225     // First, make sure that the RTPSinks' buffers will be large enough to handle the huge size of DV frames (as big as 288000).
00226     OutPacketBuffer::maxSize = 300000;
00227 
00228     char const* streamName = "dvVideoTest";
00229     char const* inputFileName = "test.dv";
00230     ServerMediaSession* sms
00231       = ServerMediaSession::createNew(*env, streamName, streamName,
00232                                       descriptionString);
00233     sms->addSubsession(DVVideoFileServerMediaSubsession
00234                        ::createNew(*env, inputFileName, reuseFirstSource));
00235     rtspServer->addServerMediaSession(sms);
00236 
00237     announceStream(rtspServer, sms, streamName, inputFileName);
00238   }
00239 
00240   env->taskScheduler().doEventLoop(); // does not return
00241 
00242   return 0; // only to prevent compiler warning
00243 }
00244 
00245 static void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,
00246                            char const* streamName, char const* inputFileName) {
00247   char* url = rtspServer->rtspURL(sms);
00248   UsageEnvironment& env = rtspServer->envir();
00249   env << "\n\"" << streamName << "\" stream, from the file \""
00250       << inputFileName << "\"\n";
00251   env << "Play this stream using the URL \"" << url << "\"\n";
00252   delete[] url;
00253 }

Generated on Fri Sep 3 02:35:42 2010 for live by  doxygen 1.5.2