INET Framework for OMNeT++/OMNEST
RTPAVProfilePayload32Sender.cc
Go to the documentation of this file.
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