![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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 }
1.5.5