00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00023
00024
00025
00026
00027
00028
00030
00031 #include "liveMedia.hh"
00032 #include "BasicUsageEnvironment.hh"
00033
00034 UsageEnvironment* env;
00035 char const* inputFileName = "test.mpg";
00036 char const* remoteStreamName = "test.sdp";
00037 MPEG1or2Demux* mpegDemux;
00038 FramedSource* audioSource;
00039 FramedSource* videoSource;
00040 RTPSink* audioSink;
00041 RTPSink* videoSink;
00042
00043 char const* programName;
00044
00045
00046
00047 Boolean iFramesOnly = False;
00048
00049 void usage() {
00050 *env << "usage: " << programName
00051 << " <Darwin Streaming Server name or IP address>\n";
00052 exit(1);
00053 }
00054
00055 void play();
00056
00057 int main(int argc, char** argv) {
00058
00059 TaskScheduler* scheduler = BasicTaskScheduler::createNew();
00060 env = BasicUsageEnvironment::createNew(*scheduler);
00061
00062
00063 programName = argv[0];
00064 if (argc != 2) usage();
00065 char const* dssNameOrAddress = argv[1];
00066
00067
00068 DarwinInjector* injector = DarwinInjector::createNew(*env, programName);
00069
00071
00072
00073
00074 struct in_addr dummyDestAddress;
00075 dummyDestAddress.s_addr = 0;
00076 Groupsock rtpGroupsockAudio(*env, dummyDestAddress, 0, 0);
00077 Groupsock rtcpGroupsockAudio(*env, dummyDestAddress, 0, 0);
00078
00079
00080 audioSink = MPEG1or2AudioRTPSink::createNew(*env, &rtpGroupsockAudio);
00081
00082
00083 const unsigned estimatedSessionBandwidthAudio = 160;
00084 const unsigned maxCNAMElen = 100;
00085 unsigned char CNAME[maxCNAMElen+1];
00086 gethostname((char*)CNAME, maxCNAMElen);
00087 CNAME[maxCNAMElen] = '\0';
00088 RTCPInstance* audioRTCP =
00089 RTCPInstance::createNew(*env, &rtcpGroupsockAudio,
00090 estimatedSessionBandwidthAudio, CNAME,
00091 audioSink, NULL );
00092
00093
00094
00095 injector->addStream(audioSink, audioRTCP);
00097
00099
00100
00101
00102 Groupsock rtpGroupsockVideo(*env, dummyDestAddress, 0, 0);
00103 Groupsock rtcpGroupsockVideo(*env, dummyDestAddress, 0, 0);
00104
00105
00106 videoSink = MPEG1or2VideoRTPSink::createNew(*env, &rtpGroupsockVideo);
00107
00108
00109 const unsigned estimatedSessionBandwidthVideo = 4500;
00110 RTCPInstance* videoRTCP =
00111 RTCPInstance::createNew(*env, &rtcpGroupsockVideo,
00112 estimatedSessionBandwidthVideo, CNAME,
00113 videoSink, NULL );
00114
00115
00116
00117 injector->addStream(videoSink, videoRTCP);
00119
00120
00121 if (!injector->setDestination(dssNameOrAddress, remoteStreamName,
00122 programName, "LIVE555 Streaming Media")) {
00123 *env << "injector->setDestination() failed: "
00124 << env->getResultMsg() << "\n";
00125 exit(1);
00126 }
00127
00128 *env << "Play this stream (from the Darwin Streaming Server) using the URL:\n"
00129 << "\trtsp://" << dssNameOrAddress << "/" << remoteStreamName << "\n";
00130
00131
00132 *env << "Beginning streaming...\n";
00133 play();
00134
00135 env->taskScheduler().doEventLoop();
00136
00137 return 0;
00138 }
00139
00140 void afterPlaying(void* clientData) {
00141
00142
00143
00144 if (audioSource->isCurrentlyAwaitingData()
00145 || videoSource->isCurrentlyAwaitingData()) return;
00146
00147
00148
00149 *env << "...done reading from file\n";
00150
00151 audioSink->stopPlaying();
00152 videoSink->stopPlaying();
00153
00154 Medium::close(audioSource);
00155 Medium::close(videoSource);
00156 Medium::close(mpegDemux);
00157
00158
00159
00160 play();
00161 }
00162
00163 void play() {
00164
00165 ByteStreamFileSource* fileSource
00166 = ByteStreamFileSource::createNew(*env, inputFileName);
00167 if (fileSource == NULL) {
00168 *env << "Unable to open file \"" << inputFileName
00169 << "\" as a byte-stream file source\n";
00170 exit(1);
00171 }
00172
00173
00174
00175 mpegDemux = MPEG1or2Demux::createNew(*env, fileSource);
00176 FramedSource* audioES = mpegDemux->newAudioStream();
00177 FramedSource* videoES = mpegDemux->newVideoStream();
00178
00179
00180 audioSource
00181 = MPEG1or2AudioStreamFramer::createNew(*env, audioES);
00182 videoSource
00183 = MPEG1or2VideoStreamFramer::createNew(*env, videoES, iFramesOnly);
00184
00185
00186 *env << "Beginning to read from file...\n";
00187 videoSink->startPlaying(*videoSource, afterPlaying, videoSink);
00188 audioSink->startPlaying(*audioSource, afterPlaying, audioSink);
00189 }