testProgs/testGSMStreamer.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-2014, Live Networks, Inc.  All rights reserved
00017 // A test program that streams GSM audio via RTP/RTCP
00018 // main program
00019 
00020 // NOTE: This program assumes the existence of a (currently nonexistent)
00021 // function called "createNewGSMAudioSource()".
00022 
00023 #include "liveMedia.hh"
00024 #include "GroupsockHelper.hh"
00025 
00026 #include "BasicUsageEnvironment.hh"
00027 
00029 
00030 // To stream using "source-specific multicast" (SSM), uncomment the following:
00031 //#define USE_SSM 1
00032 #ifdef USE_SSM
00033 Boolean const isSSM = True;
00034 #else
00035 Boolean const isSSM = False;
00036 #endif
00037 
00038 // To set up an internal RTSP server, uncomment the following:
00039 //#define IMPLEMENT_RTSP_SERVER 1
00040 // (Note that this RTSP server works for multicast only)
00041 
00042 #ifdef IMPLEMENT_RTSP_SERVER
00043 RTSPServer* rtspServer;
00044 #endif
00045 
00046 UsageEnvironment* env;
00047 
00048 void afterPlaying(void* clientData); // forward
00049 
00050 // A structure to hold the state of the current session.
00051 // It is used in the "afterPlaying()" function to clean up the session.
00052 struct sessionState_t {
00053   FramedSource* source;
00054   RTPSink* sink;
00055   RTCPInstance* rtcpInstance;
00056   Groupsock* rtpGroupsock;
00057   Groupsock* rtcpGroupsock;
00058 } sessionState;
00059 
00060 void play(); // forward
00061 
00062 int main(int argc, char** argv) {
00063   // Begin by setting up our usage environment:
00064   TaskScheduler* scheduler = BasicTaskScheduler::createNew();
00065   env = BasicUsageEnvironment::createNew(*scheduler);
00066 
00067   // Create 'groupsocks' for RTP and RTCP:
00068   char* destinationAddressStr
00069 #ifdef USE_SSM
00070     = "232.255.42.42";
00071 #else
00072     = "239.255.42.42";
00073   // Note: This is a multicast address.  If you wish to stream using
00074   // unicast instead, then replace this string with the unicast address
00075   // of the (single) destination.  (You may also need to make a similar
00076   // change to the receiver program.)
00077 #endif
00078   const unsigned short rtpPortNum = 6666;
00079   const unsigned short rtcpPortNum = rtpPortNum+1;
00080   const unsigned char ttl = 1; // low, in case routers don't admin scope
00081 
00082   struct in_addr destinationAddress;
00083   destinationAddress.s_addr = our_inet_addr(destinationAddressStr);
00084   const Port rtpPort(rtpPortNum);
00085   const Port rtcpPort(rtcpPortNum);
00086 
00087   sessionState.rtpGroupsock
00088     = new Groupsock(*env, destinationAddress, rtpPort, ttl);
00089   sessionState.rtcpGroupsock
00090     = new Groupsock(*env, destinationAddress, rtcpPort, ttl);
00091 #ifdef USE_SSM
00092   sessionState.rtpGroupsock->multicastSendOnly();
00093   sessionState.rtcpGroupsock->multicastSendOnly();
00094 #endif
00095 
00096   // Create a 'GSM RTP' sink from the RTP 'groupsock':
00097   sessionState.sink
00098     = GSMAudioRTPSink::createNew(*env, sessionState.rtpGroupsock);
00099 
00100   // Create (and start) a 'RTCP instance' for this RTP sink:
00101   const unsigned estimatedSessionBandwidth = 160; // in kbps; for RTCP b/w share
00102   const unsigned maxCNAMElen = 100;
00103   unsigned char CNAME[maxCNAMElen+1];
00104   gethostname((char*)CNAME, maxCNAMElen);
00105   CNAME[maxCNAMElen] = '\0'; // just in case
00106   sessionState.rtcpInstance
00107     = RTCPInstance::createNew(*env, sessionState.rtcpGroupsock,
00108                               estimatedSessionBandwidth, CNAME,
00109                               sessionState.sink, NULL /* we're a server */,
00110                               isSSM);
00111   // Note: This starts RTCP running automatically
00112 
00113 #ifdef IMPLEMENT_RTSP_SERVER
00114   rtspServer = RTSPServer::createNew(*env, 8554);
00115   if (rtspServer == NULL) {
00116     *env << "Failed to create RTSP server: " << env->getResultMsg() << "%s\n";
00117     exit(1);
00118   }
00119   ServerMediaSession* sms
00120     = ServerMediaSession::createNew(*env, "testStream", "GSM input",
00121                 "Session streamed by \"testGSMStreamer\"", isSSM);
00122   sms->addSubsession(PassiveServerMediaSubsession::createNew(*sessionState.sink, sessionState.rtcpInstance));
00123   rtspServer->addServerMediaSession(sms);
00124 
00125   char* url = rtspServer->rtspURL(sms);
00126   *env << "Play this stream using the URL \"" << url << "\"\n";
00127   delete[] url;
00128 #endif
00129 
00130   play();
00131 
00132   env->taskScheduler().doEventLoop(); // does not return
00133   return 0; // only to prevent compiler warning
00134 }
00135 
00136 void play() {
00137   // Open the input source:
00138   extern FramedSource* createNewGSMAudioSource(UsageEnvironment&);
00139   sessionState.source = createNewGSMAudioSource(*env);
00140   if (sessionState.source == NULL) {
00141     *env << "Failed to create GSM source\n";
00142     exit(1);
00143   }
00144 
00145   // Finally, start the streaming:
00146   *env << "Beginning streaming...\n";
00147   sessionState.sink->startPlaying(*sessionState.source, afterPlaying, NULL);
00148 }
00149 
00150 
00151 void afterPlaying(void* /*clientData*/) {
00152   *env << "...done streaming\n";
00153 
00154   sessionState.sink->stopPlaying();
00155 
00156   // End this loop by closing the media:
00157 #ifdef IMPLEMENT_RTSP_SERVER
00158   Medium::close(rtspServer);
00159 #endif
00160   Medium::close(sessionState.rtcpInstance);
00161   Medium::close(sessionState.sink);
00162   delete sessionState.rtpGroupsock;
00163   Medium::close(sessionState.source);
00164   delete sessionState.rtcpGroupsock;
00165 
00166   // And start another loop:
00167   play();
00168 }

Generated on Tue Mar 25 14:35:36 2014 for live by  doxygen 1.5.2