User Manual, Developers Guide and API Documentation

VideoTelephony.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <APPLICATIONS/session/server/VideoTelephony.hpp>
00029 #include <WNS/distribution/Norm.hpp>
00030 
00031 using namespace applications::session::server;
00032 
00033 STATIC_FACTORY_REGISTER_WITH_CREATOR(applications::session::server::VideoTelephony,
00034                      applications::session::Session,
00035                      "server.VideoTelephony", wns::PyConfigViewCreator);
00036 
00037 VideoTelephony::VideoTelephony(const wns::pyconfig::View& _pyco)  :
00038   Session(_pyco),
00039   i(0),
00040   j(0),
00041   limit(1000),
00042   idx (0),
00043 
00044   fracI(0.0),
00045   kI(1),
00046   pI(0.0),
00047   nI(0.0),
00048   dI(1.0),
00049   logNormValueI(0.0),
00050   meanI(0.0),
00051   varianceI(1.0),
00052   yI(0.0),
00053   mI(0.0),
00054   sqrValueI(0.0),
00055 
00056   fracB(0.0),
00057   kB(1),
00058   pB(0.0),
00059   nB(0.0),
00060   dB(1.0),
00061   logNormValueB(0.0),
00062   meanB(0.0),
00063   varianceB(1.0),
00064   yB(0.0),
00065   mB(0.0),
00066   sqrValueB(0.0),
00067 
00068   fracP(0.0),
00069   kP(1),
00070   pP(0.0),
00071   nP(0.0),
00072   dP(1.0),
00073   logNormValueP(0.0),
00074   meanP(0.0),
00075   varianceP(1.0),
00076   yP(0.0),
00077   mP(0.0),
00078   sqrValueP(0.0),
00079 
00080   mean(0.0),
00081   n(0),
00082   distribution(NULL),
00083   logNormDisI(NULL),
00084   logNormDisB(NULL),
00085   logNormDisP(NULL),
00086   distributionValue(0.0),
00087   normMean(0.0),
00088   variance(0.0),
00089 
00090   stateTransitionDistribution(NULL),
00091   cnCounter(0),
00092   bFrameCounter(1),
00093   gopCounter(1),
00094   newGOP(true)
00095 {
00096   wns::pyconfig::View sTVConfig(_pyco, "stateTransition");
00097   std::string sTVName = sTVConfig.get<std::string>("__plugin__");
00098   stateTransitionDistribution = wns::distribution::DistributionFactory::creator(sTVName)->create(sTVConfig);
00099 
00100   settlingTime = _pyco.get<wns::simulator::Time>("settlingTime");
00101 
00102   byteFlag = _pyco.get<bool>("params.byteFlag");
00103 
00104   logMeanI = _pyco.get<double>("params.meanI");
00105   logStdI = _pyco.get<double>("params.stdI");
00106   hurstI = _pyco.get<double>("params.hurstI");
00107   phiI = _pyco.get<double>("params.phiI");
00108   thetaI = _pyco.get<double>("params.thetaI");
00109 
00110   logMeanP = _pyco.get<double>("params.meanP");
00111   logStdP = _pyco.get<double>("params.stdP");
00112   hurstP = _pyco.get<double>("params.hurstP");
00113   phiP = _pyco.get<double>("params.phiP");
00114   thetaP = _pyco.get<double>("params.thetaP");
00115 
00116   logMeanB = _pyco.get<double>("params.meanB");
00117   logStdB = _pyco.get<double>("params.stdB");
00118   hurstB = _pyco.get<double>("params.hurstB");
00119   phiB = _pyco.get<double>("params.phiB");
00120   thetaB = _pyco.get<double>("params.thetaB");
00121 
00122   voicePacketIat = _pyco.get<wns::simulator::Time>("voicePacketIat");
00123   voicePacketSize = _pyco.get<Bit>("voicePacketSize");
00124   /* Packet size includes 12 bytes RTP header. */
00125   voicePacketSize = voicePacketSize + 96;
00126 
00127   comfortNoisePacketSize = _pyco.get<Bit>("comfortNoisePacketSize");
00128   /* Packet size includes 12 bytes RTP header. */
00129   comfortNoisePacketSize = comfortNoisePacketSize + 96;
00130 
00131   comfortNoise = _pyco.get<bool>("comfortNoise");
00132 
00133   MESSAGE_BEGIN(NORMAL, logger, m, "APPL: Starting new session with voiceparameters: ");
00134   m << "voicePacketSize = " << voicePacketSize;
00135   m << ", voicePacketIat = " << voicePacketIat;
00136   m << ", comfortNoisePacketSize = " << comfortNoisePacketSize;
00137   MESSAGE_END();
00138 
00139   videoFrameRate = _pyco.get<int>("params.frameRate");
00140   videoPacketIat = 1 / double(videoFrameRate);
00141 
00142   MESSAGE_BEGIN(NORMAL, logger, m, "APPL: Starting new session with video parameters: ");
00143   m << "videoFrameRate = " << videoFrameRate;
00144   m << ", videoPacketIat = " << videoPacketIat;
00145   MESSAGE_END();
00146 
00147   calculateSLRangeDependency();
00148 
00149   state = running;
00150 
00151   /* only for probing */
00152   sessionType = videotelephony;
00153 
00154   packetFrom = "server.VideoTelephony";
00155 }
00156 
00157 VideoTelephony::~VideoTelephony()
00158 {
00159   if (stateTransitionDistribution != NULL)
00160     delete stateTransitionDistribution;
00161   stateTransitionDistribution = NULL;
00162 
00163   autocorrI.clear();
00164   phiInew.clear();
00165   phiIold.clear();
00166   xI.clear();
00167 
00168   autocorrB.clear();
00169   phiBnew.clear();
00170   phiBold.clear();
00171   xB.clear();
00172 
00173   autocorrP.clear();
00174   phiPnew.clear();
00175   phiPold.clear();
00176   xP.clear();
00177 }
00178 
00179 void
00180 VideoTelephony::onData(const wns::osi::PDUPtr& _pdu)
00181 {
00182   assureType(_pdu.getPtr(), applications::session::PDU*);
00183 
00184   receivedPacketNumber = static_cast<applications::session::PDU*>(_pdu.getPtr())->getPacketNumber();
00185 
00186   MESSAGE_SINGLE(NORMAL, logger, "APPL: receivedPacketNumber = " << receivedPacketNumber << ".");
00187 
00188   applications::session::Session::incomingProbesCalculation(_pdu);
00189 
00190   if((receivedPacketNumber == 1) && (state != sessionended))
00191     {
00192       firstPacketDelay = packetDelay;
00193 
00194       /* Video */
00195       onTimeout(frametimeout);
00196 
00197       /* Voice */
00198       onTimeout(sendtimeout);
00199       voiceState = inactive;
00200       cnCounter = 1;
00201       setTimeout(statetransitiontimeout, 0.02);
00202     }
00203 }
00204 
00205 void
00206 VideoTelephony::onTimeout(const Timeout& _t)
00207 {
00208   /* Voice */
00209   if(_t == sendtimeout)
00210     {
00211       MESSAGE_SINGLE(NORMAL, logger, "APPL: Sending voicepacket!");
00212 
00213       applications::session::Session::iatProbesCalculation();
00214 
00215       packetSize = voicePacketSize;
00216 
00217       applications::session::PDU* applicationPDU = new applications::session::PDU(Bit(voicePacketSize), pyco);
00218       applicationPDU->setCreationTime(wns::simulator::getEventScheduler()->getTime());
00219 
00220       ++packetNumber;
00221       applicationPDU->setPacketNumber(packetNumber, packetFrom);
00222       MESSAGE_SINGLE(NORMAL, logger, "APPL: PacketNumber = " << packetNumber << ".");
00223 
00224       wns::osi::PDUPtr pdu(applicationPDU);
00225       applications::session::Session::outgoingProbesCalculation(pdu);
00226 
00227       connection->sendData(pdu);
00228     }
00229   else if(_t == receivetimeout)
00230     {
00231       /* Comfort noise packets will be send to fill the silence */
00232       MESSAGE_SINGLE(NORMAL, logger, "APPL: Sending comfort noise packet!");
00233 
00234       applications::session::Session::iatProbesCalculation();
00235 
00236       packetSize = comfortNoisePacketSize;
00237 
00238       applications::session::PDU* applicationPDU = new applications::session::PDU(Bit(comfortNoisePacketSize), pyco);
00239       applicationPDU->setCreationTime(wns::simulator::getEventScheduler()->getTime());
00240 
00241       ++packetNumber;
00242       applicationPDU->setPacketNumber(packetNumber, packetFrom);
00243       MESSAGE_SINGLE(NORMAL, logger, "APPL: PacketNumber = " << packetNumber << ".");
00244 
00245       wns::osi::PDUPtr pdu(applicationPDU);
00246       applications::session::Session::outgoingProbesCalculation(pdu);
00247 
00248       connection->sendData(pdu);
00249     }
00250   else if(_t == statetransitiontimeout)
00251     {
00252       /* Transition between active (speech) state and inactive (silent/pause) state. */
00253       double stateTransitionValue = (*stateTransitionDistribution)();
00254 
00255       MESSAGE_SINGLE(NORMAL, logger, "APPL: State transition. TransitionValue = " << stateTransitionValue << ".");
00256 
00257       if(stateTransitionValue <= 0.01 && voiceState == inactive)
00258     {
00259       cnCounter = 0;
00260       onTimeout(sendtimeout);
00261 
00262       voiceState = active;
00263     }
00264       else if(stateTransitionValue > 0.01 && voiceState == inactive)
00265     {
00266       if(cnCounter == 8)
00267         {
00268           cnCounter = 1;
00269           onTimeout(receivetimeout);
00270         }
00271       else
00272         {
00273           cnCounter += 1;
00274         }
00275     }
00276       else if(stateTransitionValue <= 0.01 && voiceState == active)
00277     {
00278       cnCounter = 1;
00279       onTimeout(receivetimeout);
00280 
00281       voiceState = inactive;
00282     }
00283       else if(stateTransitionValue > 0.01 && voiceState == active)
00284     {
00285       onTimeout(sendtimeout);
00286     }
00287 
00288       setTimeout(statetransitiontimeout, 0.02);
00289     }
00290   /* Video */
00291   else if(_t == frametimeout)
00292     {
00293       if(newGOP == false)
00294     {
00295       if(bFrameCounter <= 2)
00296         {
00297           /* B-Frame */
00298           MESSAGE_SINGLE(NORMAL, logger, "APPL: B-FRAME!");
00299 
00300           bFrameCounter += 1;
00301 
00302           setTimeout(frametimeout, videoPacketIat);
00303 
00304           logNormalProjectedFarima(xB, phiBold, yB, phiB, thetaB, mB, sqrValueB,
00305                        varianceB, kB, logMeanB, logStdB);
00306         }
00307       else
00308         {
00309           /* P-Frame */
00310           bFrameCounter = 1;
00311 
00312           if(gopCounter < 4)
00313         {
00314           MESSAGE_SINGLE(NORMAL, logger, "APPL: P-FRAME!");
00315 
00316           logNormalProjectedFarima(xP, phiPold, yP, phiP, thetaP, mP, sqrValueP,
00317                        varianceP, kP, logMeanP, logStdP);
00318 
00319           gopCounter += 1;
00320           setTimeout(frametimeout, videoPacketIat);
00321         }
00322           else
00323         {
00324           gopCounter = 1;
00325           newGOP = true;
00326           onTimeout(frametimeout);
00327         }
00328         }
00329     }
00330       else
00331     {
00332       /* I-Frame */
00333       MESSAGE_SINGLE(NORMAL, logger, "APPL: I-FRAME!");
00334 
00335       logNormalProjectedFarima(xI, phiIold, yI, phiI, thetaI, mI, sqrValueI,
00336                    varianceI, kI, logMeanI, logStdI);
00337 
00338       newGOP = false;
00339       setTimeout(frametimeout, videoPacketIat);
00340     }
00341     }
00342   else if(_t == probetimeout)
00343     {
00344       applications::session::Session::onTimeout(_t);
00345     }
00346   else
00347     {
00348       assure(false, "APPL: Unknown timout type =" << _t);
00349     }
00350 }
00351 
00352 
00353 void
00354 VideoTelephony::calculateSLRangeDependency()
00355 {
00356   /* Callculation of the short- and longrangedependencies.
00357      For detailed discription see diplomathesis of Cem Mengi 10.07.2006:
00358      "Conception and implementation of traffic Models for VoIP and Videotelephony". */
00359   MESSAGE_SINGLE(NORMAL, logger, "APPL: Callculation of the short- and longrange dependencies!");
00360 
00361   fracI = hurstI - 0.5;
00362   fracP = hurstP - 0.5;
00363   fracB = hurstB - 0.5;
00364 
00365   autocorrI.push_back(1.0);
00366   autocorrP.push_back(1.0);
00367   autocorrB.push_back(1.0);
00368 
00369   /* This distribution is just used one time and deleted after that.
00370      Next time a new distribution is used.*/
00371   logNormDisI = new wns::distribution::Norm(meanI, varianceI);
00372   logNormValueI = (*logNormDisI)();
00373   xI.push_back(logNormValueI);
00374 
00375   logNormDisP = new wns::distribution::Norm(meanP, varianceP);
00376   logNormValueP = (*logNormDisP)();
00377   xP.push_back(logNormValueP);
00378 
00379   logNormDisB = new wns::distribution::Norm(meanB, varianceB);
00380   logNormValueB = (*logNormDisB)();
00381   xB.push_back(logNormValueB);
00382 
00383   delete logNormDisI;
00384   logNormDisI = NULL;
00385 
00386   delete logNormDisP;
00387   logNormDisP = NULL;
00388 
00389   delete logNormDisB;
00390   logNormDisB = NULL;
00391 
00392   for(i = 1; i < limit; i++)
00393     {
00394       autocorrI.push_back(autocorrI[i - 1] * ((static_cast<float>(i - 1) + fracI)/ (static_cast<float>(i) - fracI)));
00395       autocorrP.push_back(autocorrP[i - 1] * ((static_cast<float>(i - 1) + fracP)/ (static_cast<float>(i) - fracP)));
00396       autocorrB.push_back(autocorrB[i - 1] * ((static_cast<float>(i - 1) + fracB)/ (static_cast<float>(i) - fracB)));
00397 
00398       pI = 0;
00399       pP = 0;
00400       pB = 0;
00401 
00402       for(j = 1; j <= (i-1); j++)
00403     {
00404       pI = pI + phiIold[j - 1] * autocorrI[i - j];
00405       pP = pP + phiPold[j - 1] * autocorrP[i - j];
00406       pB = pB + phiBold[j - 1] * autocorrB[i - j];
00407     }
00408 
00409       dI = dI - ((nI * nI) / dI);
00410       nI = autocorrI[i] - pI;
00411       dP = dP - ((nP * nP) / dP);
00412       nP = autocorrP[i] - pP;
00413       dB = dB - ((nB * nB) / dB);
00414       nB = autocorrB[i] - pB;
00415 
00416       phiInew.push_back(nI / dI);
00417       phiPnew.push_back(nP / dP);
00418       phiBnew.push_back(nB / dB);
00419 
00420       idx = i;
00421 
00422       meanI = phiInew[0] * xI[0];
00423       meanP = phiPnew[0] * xP[0];
00424       meanB = phiBnew[0] * xB[0];
00425 
00426       for(idx = i; idx > 1; idx--)
00427     {
00428 
00429       phiInew.push_front(phiIold[idx - 2] - (phiInew[i - idx] * phiIold[i - idx]));
00430       phiPnew.push_front(phiPold[idx - 2] - (phiPnew[i - idx] * phiPold[i - idx]));
00431       phiBnew.push_front(phiBold[idx - 2] - (phiBnew[i - idx] * phiBold[i - idx]));
00432 
00433       meanI = meanI + (phiInew[0] * xI[i - idx + 1]);
00434       meanP = meanP + (phiPnew[0] * xP[i - idx + 1]);
00435       meanB = meanB + (phiBnew[0] * xB[i - idx + 1]);
00436 
00437     }
00438 
00439       varianceI = (1 - pow(phiInew[i - 1], 2)) * varianceI;
00440       varianceP = (1 - pow(phiPnew[i - 1], 2)) * varianceP;
00441       varianceB = (1 - pow(phiBnew[i - 1], 2)) * varianceB;
00442 
00443       /* This distribution is just used one time and deleted after that.
00444      Next time a new distribution is used.*/
00445       logNormDisI = new wns::distribution::Norm(meanI, varianceI);
00446       logNormValueI = (*logNormDisI)();
00447       xI.push_back(logNormValueI);
00448 
00449       logNormDisP = new wns::distribution::Norm(meanP, varianceP);
00450       logNormValueP = (*logNormDisP)();
00451       xP.push_back(logNormValueP);
00452 
00453       logNormDisB = new wns::distribution::Norm(meanB, varianceB);
00454       logNormValueB = (*logNormDisB)();
00455       xB.push_back(logNormValueB);
00456 
00457       phiIold.clear();
00458       phiPold.clear();
00459       phiBold.clear();
00460       phiIold = phiInew;
00461       phiPold = phiPnew;
00462       phiBold = phiBnew;
00463       phiInew.clear();
00464       phiPnew.clear();
00465       phiBnew.clear();
00466 
00467       delete logNormDisI;
00468       logNormDisI = NULL;
00469 
00470       delete logNormDisP;
00471       logNormDisP = NULL;
00472 
00473       delete logNormDisB;
00474       logNormDisB = NULL;
00475 
00476     }
00477 
00478   xI.pop_front();
00479   xP.pop_front();
00480   xB.pop_front();
00481 
00482   autocorrI.clear();
00483   autocorrP.clear();
00484   autocorrB.clear();
00485 }
00486 
00487 
00488 void
00489 VideoTelephony::logNormalProjectedFarima(std::deque<double> _x, std::deque<double> _phiold, double _y,
00490                      double _phi, double _theta, double _m, double _sqrValue,
00491                      double _variance, int _k, double _logMean, double _logStd)
00492 {
00493   mean = 0;
00494   n = 0;
00495   while(n < limit - 1)
00496     {
00497       mean = mean + _x[n] * _phiold[limit - n - 2];
00498 
00499       n = n + 1;
00500     }
00501   _variance = (1 - pow(_phiold[limit - 2], 2)) * _variance;
00502 
00503   distribution = new wns::distribution::Norm(mean, _variance);
00504   distributionValue = (*distribution)();
00505   _x.push_back(distributionValue);
00506 
00507   _y = _x[limit - 1];
00508 
00509   _m = _m + _y;
00510 
00511   _sqrValue = _sqrValue + pow(_y, 2);
00512 
00513   normMean = _m / static_cast<int>((float)(_k + 1));
00514 
00515   variance = (_sqrValue - (pow(_m, 2) / static_cast<int>((float)(_k + 1)))) / static_cast<int>((float)(_k));
00516 
00517   packetSize = exp(_logMean + (_logStd * ((_y - normMean) / sqrt(variance)))) + 1;
00518   if(byteFlag == true)
00519     {
00520       packetSize *= 8.0;
00521     }
00522 
00523   _x.pop_front();
00524   _k = _k + 1;
00525 
00526   delete distribution;
00527   distribution = NULL;
00528 
00529   applications::session::PDU* applicationPDU = new applications::session::PDU(Bit(packetSize), pyco);
00530   applicationPDU->setCreationTime(wns::simulator::getEventScheduler()->getTime());
00531 
00532   ++packetNumber;
00533   applicationPDU->setPacketNumber(packetNumber, packetFrom);
00534   MESSAGE_SINGLE(NORMAL, logger, "APPL: PacketNumber = " << packetNumber << ".");
00535 
00536   wns::osi::PDUPtr pdu(applicationPDU);
00537   applications::session::Session::outgoingProbesCalculation(pdu);
00538 
00539   connection->sendData(pdu);
00540 }

Generated on Sun May 27 03:32:16 2012 for openWNS by  doxygen 1.5.5