00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "liveMedia.hh"
00023 #include "BasicUsageEnvironment.hh"
00024 #include "GroupsockHelper.hh"
00025
00026 UsageEnvironment* env;
00027 char const* inputFileName = "test.mpg";
00028 MPEG1or2Demux* mpegDemux;
00029 FramedSource* audioSource;
00030 FramedSource* videoSource;
00031 RTPSink* audioSink;
00032 RTPSink* videoSink;
00033
00034 void play();
00035
00036
00037
00038 #ifdef USE_SSM
00039 Boolean const isSSM = True;
00040 #else
00041 Boolean const isSSM = False;
00042 #endif
00043
00044
00045
00046
00047
00048
00049
00050 Boolean iFramesOnly = False;
00051
00052 int main(int argc, char** argv) {
00053
00054 TaskScheduler* scheduler = BasicTaskScheduler::createNew();
00055 env = BasicUsageEnvironment::createNew(*scheduler);
00056
00057
00058 char const* destinationAddressStr
00059 #ifdef USE_SSM
00060 = "232.255.42.42";
00061 #else
00062 = "239.255.42.42";
00063
00064
00065
00066
00067 #endif
00068 const unsigned short rtpPortNumAudio = 6666;
00069 const unsigned short rtcpPortNumAudio = rtpPortNumAudio+1;
00070 const unsigned short rtpPortNumVideo = 8888;
00071 const unsigned short rtcpPortNumVideo = rtpPortNumVideo+1;
00072 const unsigned char ttl = 7;
00073
00074 struct in_addr destinationAddress;
00075 destinationAddress.s_addr = our_inet_addr(destinationAddressStr);
00076 const Port rtpPortAudio(rtpPortNumAudio);
00077 const Port rtcpPortAudio(rtcpPortNumAudio);
00078 const Port rtpPortVideo(rtpPortNumVideo);
00079 const Port rtcpPortVideo(rtcpPortNumVideo);
00080
00081 Groupsock rtpGroupsockAudio(*env, destinationAddress, rtpPortAudio, ttl);
00082 Groupsock rtcpGroupsockAudio(*env, destinationAddress, rtcpPortAudio, ttl);
00083 Groupsock rtpGroupsockVideo(*env, destinationAddress, rtpPortVideo, ttl);
00084 Groupsock rtcpGroupsockVideo(*env, destinationAddress, rtcpPortVideo, ttl);
00085 #ifdef USE_SSM
00086 rtpGroupsockAudio.multicastSendOnly();
00087 rtcpGroupsockAudio.multicastSendOnly();
00088 rtpGroupsockVideo.multicastSendOnly();
00089 rtcpGroupsockVideo.multicastSendOnly();
00090 #endif
00091
00092
00093 audioSink = MPEG1or2AudioRTPSink::createNew(*env, &rtpGroupsockAudio);
00094
00095
00096 const unsigned estimatedSessionBandwidthAudio = 160;
00097 const unsigned maxCNAMElen = 100;
00098 unsigned char CNAME[maxCNAMElen+1];
00099 gethostname((char*)CNAME, maxCNAMElen);
00100 CNAME[maxCNAMElen] = '\0';
00101 #ifdef IMPLEMENT_RTSP_SERVER
00102 RTCPInstance* audioRTCP =
00103 #endif
00104 RTCPInstance::createNew(*env, &rtcpGroupsockAudio,
00105 estimatedSessionBandwidthAudio, CNAME,
00106 audioSink, NULL , isSSM);
00107
00108
00109
00110 videoSink = MPEG1or2VideoRTPSink::createNew(*env, &rtpGroupsockVideo);
00111
00112
00113 const unsigned estimatedSessionBandwidthVideo = 4500;
00114 #ifdef IMPLEMENT_RTSP_SERVER
00115 RTCPInstance* videoRTCP =
00116 #endif
00117 RTCPInstance::createNew(*env, &rtcpGroupsockVideo,
00118 estimatedSessionBandwidthVideo, CNAME,
00119 videoSink, NULL , isSSM);
00120
00121
00122 #ifdef IMPLEMENT_RTSP_SERVER
00123 RTSPServer* 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 \"testMPEG1or2AudioVideoStreamer\"",
00134 isSSM);
00135 sms->addSubsession(PassiveServerMediaSubsession::createNew(*audioSink, audioRTCP));
00136 sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoSink, videoRTCP));
00137 rtspServer->addServerMediaSession(sms);
00138
00139 char* url = rtspServer->rtspURL(sms);
00140 *env << "Play this stream using the URL \"" << url << "\"\n";
00141 delete[] url;
00142 #endif
00143
00144
00145 *env << "Beginning streaming...\n";
00146 play();
00147
00148 env->taskScheduler().doEventLoop();
00149
00150 return 0;
00151 }
00152
00153 void afterPlaying(void* clientData) {
00154
00155
00156
00157 if (audioSource->isCurrentlyAwaitingData()
00158 || videoSource->isCurrentlyAwaitingData()) return;
00159
00160
00161
00162 *env << "...done reading from file\n";
00163
00164 audioSink->stopPlaying();
00165 videoSink->stopPlaying();
00166
00167 Medium::close(audioSource);
00168 Medium::close(videoSource);
00169 Medium::close(mpegDemux);
00170
00171
00172
00173 play();
00174 }
00175
00176 void play() {
00177
00178 ByteStreamFileSource* fileSource
00179 = ByteStreamFileSource::createNew(*env, inputFileName);
00180 if (fileSource == NULL) {
00181 *env << "Unable to open file \"" << inputFileName
00182 << "\" as a byte-stream file source\n";
00183 exit(1);
00184 }
00185
00186
00187
00188 mpegDemux = MPEG1or2Demux::createNew(*env, fileSource);
00189 FramedSource* audioES = mpegDemux->newAudioStream();
00190 FramedSource* videoES = mpegDemux->newVideoStream();
00191
00192
00193 audioSource
00194 = MPEG1or2AudioStreamFramer::createNew(*env, audioES);
00195 videoSource
00196 = MPEG1or2VideoStreamFramer::createNew(*env, videoES, iFramesOnly);
00197
00198
00199 *env << "Beginning to read from file...\n";
00200 videoSink->startPlaying(*videoSource, afterPlaying, videoSink);
00201 audioSink->startPlaying(*audioSource, afterPlaying, audioSink);
00202 }