00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "liveMedia.hh"
00021 #include "GroupsockHelper.hh"
00022
00023 #include "BasicUsageEnvironment.hh"
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifdef USE_SSM
00035 Boolean const isSSM = True;
00036 #else
00037 Boolean const isSSM = False;
00038 #endif
00039
00040
00041
00042
00043
00044 #ifdef IMPLEMENT_RTSP_SERVER
00045 RTSPServer* rtspServer;
00046 #endif
00047
00048 UsageEnvironment* env;
00049
00050
00051
00052 struct sessionState_t {
00053 FramedSource* source;
00054 RTPSink* sink;
00055 RTCPInstance* rtcpInstance;
00056 Groupsock* rtpGroupsock;
00057 Groupsock* rtcpGroupsock;
00058 } sessionState;
00059
00060 char const* inputFileName = "test.mp3";
00061
00062 void play();
00063
00064 int main(int argc, char** argv) {
00065
00066 TaskScheduler* scheduler = BasicTaskScheduler::createNew();
00067 env = BasicUsageEnvironment::createNew(*scheduler);
00068
00069
00070 char const* destinationAddressStr
00071 #ifdef USE_SSM
00072 = "232.255.42.42";
00073 #else
00074 = "239.255.42.42";
00075
00076
00077
00078
00079 #endif
00080 const unsigned short rtpPortNum = 6666;
00081 const unsigned short rtcpPortNum = rtpPortNum+1;
00082 const unsigned char ttl = 1;
00083
00084 struct in_addr destinationAddress;
00085 destinationAddress.s_addr = our_inet_addr(destinationAddressStr);
00086 const Port rtpPort(rtpPortNum);
00087 const Port rtcpPort(rtcpPortNum);
00088
00089 sessionState.rtpGroupsock
00090 = new Groupsock(*env, destinationAddress, rtpPort, ttl);
00091 sessionState.rtcpGroupsock
00092 = new Groupsock(*env, destinationAddress, rtcpPort, ttl);
00093 #ifdef USE_SSM
00094 sessionState.rtpGroupsock->multicastSendOnly();
00095 sessionState.rtcpGroupsock->multicastSendOnly();
00096 #endif
00097
00098
00099 #ifdef STREAM_USING_ADUS
00100 unsigned char rtpPayloadFormat = 96;
00101 sessionState.sink
00102 = MP3ADURTPSink::createNew(*env, sessionState.rtpGroupsock,
00103 rtpPayloadFormat);
00104 #else
00105 sessionState.sink
00106 = MPEG1or2AudioRTPSink::createNew(*env, sessionState.rtpGroupsock);
00107 #endif
00108
00109
00110 const unsigned estimatedSessionBandwidth = 160;
00111 const unsigned maxCNAMElen = 100;
00112 unsigned char CNAME[maxCNAMElen+1];
00113 gethostname((char*)CNAME, maxCNAMElen);
00114 CNAME[maxCNAMElen] = '\0';
00115 sessionState.rtcpInstance
00116 = RTCPInstance::createNew(*env, sessionState.rtcpGroupsock,
00117 estimatedSessionBandwidth, CNAME,
00118 sessionState.sink, NULL ,
00119 isSSM);
00120
00121
00122 #ifdef IMPLEMENT_RTSP_SERVER
00123 rtspServer = RTSPServer::createNew(*env);
00124
00125
00126
00127 if (rtspServer == NULL) {
00128 *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
00129 exit(1);
00130 }
00131 ServerMediaSession* sms
00132 = ServerMediaSession::createNew(*env, "testStream", inputFileName,
00133 "Session streamed by \"testMP3Streamer\"", isSSM);
00134 sms->addSubsession(PassiveServerMediaSubsession::createNew(*sessionState.sink, sessionState.rtcpInstance));
00135 rtspServer->addServerMediaSession(sms);
00136
00137 char* url = rtspServer->rtspURL(sms);
00138 *env << "Play this stream using the URL \"" << url << "\"\n";
00139 delete[] url;
00140 #endif
00141
00142 play();
00143
00144 env->taskScheduler().doEventLoop();
00145 return 0;
00146 }
00147
00148 void afterPlaying(void* clientData);
00149
00150 void play() {
00151
00152 sessionState.source = MP3FileSource::createNew(*env, inputFileName);
00153 if (sessionState.source == NULL) {
00154 *env << "Unable to open file \"" << inputFileName
00155 << "\" as a MP3 file source\n";
00156 exit(1);
00157 }
00158
00159 #ifdef STREAM_USING_ADUS
00160
00161 sessionState.source
00162 = ADUFromMP3Source::createNew(*env, sessionState.source);
00163 if (sessionState.source == NULL) {
00164 *env << "Unable to create a MP3->ADU filter for the source\n";
00165 exit(1);
00166 }
00167
00168 #ifdef INTERLEAVE_ADUS
00169
00170 unsigned char interleaveCycle[] = {0,2,1,3};
00171 unsigned const interleaveCycleSize
00172 = (sizeof interleaveCycle)/(sizeof (unsigned char));
00173 Interleaving interleaving(interleaveCycleSize, interleaveCycle);
00174 sessionState.source
00175 = MP3ADUinterleaver::createNew(*env, interleaving, sessionState.source);
00176 if (sessionState.source == NULL) {
00177 *env << "Unable to create an ADU interleaving filter for the source\n";
00178 exit(1);
00179 }
00180 #endif
00181 #endif
00182
00183
00184 *env << "Beginning streaming...\n";
00185 sessionState.sink->startPlaying(*sessionState.source, afterPlaying, NULL);
00186 }
00187
00188
00189 void afterPlaying(void* ) {
00190 *env << "...done streaming\n";
00191
00192 sessionState.sink->stopPlaying();
00193
00194
00195 Medium::close(sessionState.source);
00196
00197
00198 play();
00199 }