|
INET Framework for OMNeT++/OMNEST
|
00001 /*************************************************************************** 00002 RTPAVProfilePayload32Sender.cpp - description 00003 ------------------- 00004 begin : Fri Aug 2 2007 00005 copyright : (C) 2007 by Matthias Oppitz, Ahmed Ayadi 00006 email : <Matthias.Oppitz@gmx.de> <ahmed.ayadi@sophia.inria.fr> 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00025 #include <fstream> 00026 #include <string.h> 00027 #include "RTPPacket.h" 00028 #include "RTPInnerPacket.h" 00029 #include "RTPAVProfilePayload32Sender.h" 00030 #include "RTPMpegPacket_m.h" 00031 00032 Define_Module(RTPAVProfilePayload32Sender); 00033 00034 void RTPAVProfilePayload32Sender::initialize() 00035 { 00036 00037 RTPPayloadSender::initialize(); 00038 00039 _clockRate = 90000; 00040 _payloadType = 32; 00041 } 00042 00043 00044 /* 00045 void RTPAVProfilePayload32Sender::activity() 00046 { 00047 00048 cMessage *msg = receive(); 00049 RTPInnerPacket *rinpIn = check_and_cast<RTPInnerPacket *>(msg); 00050 00051 if (rinpIn->getType() == RTPInnerPacket::RTP_INP_INITIALIZE_SENDER_MODULE) { 00052 initializeSenderModule(rinpIn); 00053 } 00054 else { 00055 error("first messsage to payload sender module must be createSenderModule"); 00056 } 00057 00058 bool moreFrames = true; 00059 00060 00061 do { 00062 00063 cMessage *msgIn; 00064 00065 if (_status == STOPPED) { 00066 msgIn = receiveOn(findGate("profileIn")); 00067 00068 } 00069 else { 00070 msgIn = receive(); 00071 00072 00073 } 00074 00075 if (msgIn->getArrivalGateId() == findGate("profileIn")) { 00076 RTPInnerPacket *rinp = check_and_cast<RTPInnerPacket *>(msgIn); 00077 if (rinp->getType() == RTPInnerPacket::RTP_INP_SENDER_MODULE_CONTROL) { 00078 00079 00080 RTPSenderControlMessage *rscm = (RTPSenderControlMessage *)(rinp->decapsulate()); 00081 00082 00083 if (!opp_strcmp(rscm->getCommand(), "PLAY")) { 00084 00085 play(); 00086 00087 00088 moreFrames = sendPacket(); 00089 00090 00091 } 00092 else if (!opp_strcmp(rscm->getCommand(), "STOP")) { 00093 00094 00095 stop(); 00096 } 00097 else { 00098 ev << "payload sender: unknown sender control message, ignored" << endl; 00099 } 00100 //delete rscm; 00101 } 00102 } 00103 else { 00104 00105 00106 moreFrames = sendPacket(); 00107 } 00108 delete msgIn; 00109 00110 if (!moreFrames) 00111 finish(); 00112 } while (true); 00113 } 00114 */ 00115 00116 void RTPAVProfilePayload32Sender::initializeSenderModule(RTPInnerPacket *rinpIn) 00117 { 00118 ev << "initializeSenderModule Enter"<<endl; 00119 char line[100]; 00120 char unit[100]; 00121 char description[100]; 00122 00123 RTPPayloadSender::initializeSenderModule(rinpIn); 00124 00125 // first line: fps unit description 00126 _inputFileStream.get(line, 100, '\n'); 00127 00128 float fps; 00129 sscanf(line, "%f %s %s", &fps, unit, description); 00130 _framesPerSecond = fps; 00131 00132 _frameNumber = 0; 00133 00134 // get new line character 00135 char c; 00136 _inputFileStream.get(c); 00137 00138 // second line: initial delay unit description 00139 _inputFileStream.get(line, 100, '\n'); 00140 00141 float delay; 00142 sscanf(line, "%f %s %s", &delay, unit, description); 00143 00144 _initialDelay = delay; 00145 00146 // wait initial delay 00147 // cPacket *reminderMessage = new cMessage("next frame"); 00148 // scheduleAt(simTime() + _initialDelay, reminderMessage); 00149 ev << "initializeSenderModule Exit"<<endl; 00150 } 00151 00152 00153 bool RTPAVProfilePayload32Sender::sendPacket() 00154 { 00155 ev << "sendPacket() "<< endl; 00156 // read next frame line 00157 int bits; 00158 char unit[100]; 00159 char description[100]; 00160 00161 _inputFileStream >> bits; 00162 _inputFileStream >> unit; 00163 _inputFileStream.get(description, 100, '\n'); 00164 00165 int pictureType = 0; 00166 00167 if (strchr(description, 'I')) { 00168 pictureType = 1; 00169 } 00170 else if (strchr(description, 'P')) { 00171 pictureType = 2; 00172 } 00173 else if (strchr(description, 'B')) { 00174 pictureType = 3; 00175 } 00176 else if (strchr(description, 'D')) { 00177 pictureType = 4; 00178 } 00179 00180 int bytesRemaining = bits / 8; 00181 00182 if (!_inputFileStream.eof()) { 00183 while (bytesRemaining > 0) { 00184 RTPPacket *rtpPacket = new RTPPacket("RTPPacket"); 00185 RTPMpegPacket *mpegPacket = new RTPMpegPacket("MpegPacket"); 00186 00187 // the only mpeg information we know is the picture type 00188 mpegPacket->setPictureType(pictureType); 00189 00190 // the maximum number of real data bytes 00191 int maxDataSize = _mtu - rtpPacket->getBitLength() - mpegPacket->getBitLength(); 00192 00193 if (bytesRemaining > maxDataSize) { 00194 00195 // we do not know where slices in the 00196 // mpeg picture begin 00197 // so we simulate by assuming a slice 00198 // has a length of 64 bytes 00199 int slicedDataSize = (maxDataSize / 64) * 64; 00200 00201 mpegPacket->addBitLength(slicedDataSize); 00202 00203 00204 rtpPacket->encapsulate(mpegPacket); 00205 00206 bytesRemaining = bytesRemaining - slicedDataSize; 00207 } 00208 else { 00209 mpegPacket->addBitLength(bytesRemaining); 00210 rtpPacket->encapsulate(mpegPacket); 00211 // set marker because this is 00212 // the last packet of the frame 00213 rtpPacket->setMarker(1); 00214 bytesRemaining = 0; 00215 } 00216 00217 rtpPacket->setPayloadType(_payloadType); 00218 rtpPacket->setSequenceNumber(_sequenceNumber); 00219 _sequenceNumber++; 00220 00221 00222 rtpPacket->setTimeStamp(_timeStampBase + (_initialDelay + (1 / _framesPerSecond) * (double)_frameNumber) * _clockRate); 00223 rtpPacket->setSSRC(_ssrc); 00224 00225 00226 RTPInnerPacket *rinpOut = new RTPInnerPacket("dataOut()"); 00227 00228 00229 rinpOut->dataOut(rtpPacket); 00230 00231 send(rinpOut, "profileOut"); 00232 00233 } 00234 _frameNumber++; 00235 00236 _reminderMessage = new cMessage("nextFrame"); 00237 scheduleAt(simTime() + 1.0 / _framesPerSecond, _reminderMessage); 00238 return true; 00239 } 00240 else { 00241 std::cout <<"LastSequenceNumber "<< _sequenceNumber << endl; 00242 return false; 00243 } 00244 ev << "sendPacket() Exit"<< endl; 00245 } 00246