![]() |
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/client/VideoTelephony.hpp> 00029 #include <WNS/distribution/Norm.hpp> 00030 00031 using namespace applications::session::client; 00032 00033 STATIC_FACTORY_REGISTER_WITH_CREATOR(applications::session::client::VideoTelephony, 00034 applications::session::Session, 00035 "client.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 videoparameters: "); 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 sessionDelay = (*sessionDelayDistribution)(); 00155 MESSAGE_SINGLE(NORMAL, logger, "APPL: Delay before session starts: " << sessionDelay << ".\n"); 00156 00157 setTimeout(connectiontimeout, sessionDelay); 00158 setTimeout(probetimeout, windowSize); 00159 } 00160 00161 00162 VideoTelephony::~VideoTelephony() 00163 { 00164 if (stateTransitionDistribution != NULL) 00165 delete stateTransitionDistribution; 00166 stateTransitionDistribution = NULL; 00167 00168 autocorrI.clear(); 00169 phiInew.clear(); 00170 phiIold.clear(); 00171 xI.clear(); 00172 00173 autocorrB.clear(); 00174 phiBnew.clear(); 00175 phiBold.clear(); 00176 xB.clear(); 00177 00178 autocorrP.clear(); 00179 phiPnew.clear(); 00180 phiPold.clear(); 00181 xP.clear(); 00182 } 00183 00184 void 00185 VideoTelephony::onData(const wns::osi::PDUPtr& _pdu) 00186 { 00187 assureType(_pdu.getPtr(), applications::session::PDU*); 00188 00189 receivedPacketNumber = static_cast<applications::session::PDU*>(_pdu.getPtr())->getPacketNumber(); 00190 00191 MESSAGE_SINGLE(NORMAL, logger, "APPL: receivedPacketNumber = " << receivedPacketNumber << "."); 00192 00193 applications::session::Session::incomingProbesCalculation(_pdu); 00194 00195 if((receivedPacketNumber == 1) && (state != sessionended)) 00196 { 00197 /* Voice */ 00198 onTimeout(sendtimeout); 00199 voiceState = active; 00200 setTimeout(statetransitiontimeout, 0.02); 00201 00202 /* Video */ 00203 onTimeout(frametimeout); 00204 00205 state = running; 00206 } 00207 } 00208 00209 void 00210 VideoTelephony::onTimeout(const Timeout& _t) 00211 { 00212 /* Voice */ 00213 if(_t == sendtimeout) 00214 { 00215 MESSAGE_SINGLE(NORMAL, logger, "APPL: Sending voicepacket!"); 00216 00217 applications::session::Session::iatProbesCalculation(); 00218 00219 packetSize = voicePacketSize; 00220 00221 applications::session::PDU* applicationPDU = new applications::session::PDU(Bit(voicePacketSize), pyco); 00222 applicationPDU->setCreationTime(wns::simulator::getEventScheduler()->getTime()); 00223 00224 ++packetNumber; 00225 applicationPDU->setPacketNumber(packetNumber, packetFrom); 00226 MESSAGE_SINGLE(NORMAL, logger, "APPL: PacketNumber = " << packetNumber << "."); 00227 00228 wns::osi::PDUPtr pdu(applicationPDU); 00229 applications::session::Session::outgoingProbesCalculation(pdu); 00230 00231 connection->sendData(pdu); 00232 } 00233 else if(_t == receivetimeout) 00234 { 00235 /* Comfort noise packets will be send to fill the silence */ 00236 MESSAGE_SINGLE(NORMAL, logger, "APPL: Sending comfort noise packet!"); 00237 00238 applications::session::Session::iatProbesCalculation(); 00239 00240 packetSize = comfortNoisePacketSize; 00241 00242 applications::session::PDU* applicationPDU = new applications::session::PDU(Bit(comfortNoisePacketSize), pyco); 00243 applicationPDU->setCreationTime(wns::simulator::getEventScheduler()->getTime()); 00244 00245 ++packetNumber; 00246 applicationPDU->setPacketNumber(packetNumber, packetFrom); 00247 MESSAGE_SINGLE(NORMAL, logger, "APPL: PacketNumber = " << packetNumber << "."); 00248 00249 wns::osi::PDUPtr pdu(applicationPDU); 00250 applications::session::Session::outgoingProbesCalculation(pdu); 00251 00252 connection->sendData(pdu); 00253 } 00254 else if(_t == statetransitiontimeout) 00255 { 00256 /* Transition between active (speech) state and inactive (silent/pause) state. */ 00257 double stateTransitionValue = (*stateTransitionDistribution)(); 00258 00259 MESSAGE_SINGLE(NORMAL, logger, "APPL: State transition. TransitionValue = " << stateTransitionValue << "."); 00260 00261 if(stateTransitionValue <= 0.01 && voiceState == inactive) 00262 { 00263 cnCounter = 0; 00264 onTimeout(sendtimeout); 00265 00266 voiceState = active; 00267 } 00268 else if(stateTransitionValue > 0.01 && voiceState == inactive) 00269 { 00270 if(cnCounter == 8) 00271 { 00272 cnCounter = 1; 00273 onTimeout(receivetimeout); 00274 } 00275 else 00276 { 00277 cnCounter += 1; 00278 } 00279 } 00280 else if(stateTransitionValue <= 0.01 && voiceState == active) 00281 { 00282 cnCounter = 1; 00283 onTimeout(receivetimeout); 00284 00285 voiceState = inactive; 00286 } 00287 else if(stateTransitionValue > 0.01 && voiceState == active) 00288 { 00289 onTimeout(sendtimeout); 00290 } 00291 00292 setTimeout(statetransitiontimeout, 0.02); 00293 } 00294 /* Video */ 00295 else if(_t == frametimeout) 00296 { 00297 if(newGOP == false) 00298 { 00299 if(bFrameCounter <= 2) 00300 { 00301 /* B-Frame */ 00302 MESSAGE_SINGLE(NORMAL, logger, "APPL: B-FRAME!"); 00303 00304 bFrameCounter += 1; 00305 00306 setTimeout(frametimeout, videoPacketIat); 00307 00308 logNormalProjectedFarima(xB, phiBold, yB, phiB, thetaB, mB, sqrValueB, 00309 varianceB, kB, logMeanB, logStdB); 00310 } 00311 else 00312 { 00313 /* P-Frame */ 00314 bFrameCounter = 1; 00315 00316 if(gopCounter < 4) 00317 { 00318 MESSAGE_SINGLE(NORMAL, logger, "APPL: P-FRAME!"); 00319 00320 logNormalProjectedFarima(xP, phiPold, yP, phiP, thetaP, mP, sqrValueP, 00321 varianceP, kP, logMeanP, logStdP); 00322 00323 gopCounter += 1; 00324 setTimeout(frametimeout, videoPacketIat); 00325 } 00326 else 00327 { 00328 gopCounter = 1; 00329 newGOP = true; 00330 onTimeout(frametimeout); 00331 } 00332 } 00333 } 00334 else 00335 { 00336 /* I-Frame */ 00337 MESSAGE_SINGLE(NORMAL, logger, "APPL: I-FRAME!"); 00338 00339 VideoTelephony::logNormalProjectedFarima(xI, phiIold, yI, phiI, thetaI, mI, sqrValueI, 00340 varianceI, kI, logMeanI, logStdI); 00341 00342 newGOP = false; 00343 setTimeout(frametimeout, videoPacketIat); 00344 } 00345 } 00346 else if(_t == connectiontimeout) 00347 { 00348 packetFrom = "client.VideoTelephony"; 00349 00350 /* Open connection */ 00351 binding->initBinding(); 00352 } 00353 else if(_t == probetimeout) 00354 { 00355 applications::session::Session::onTimeout(_t); 00356 } 00357 else if(_t == calltimeout) 00358 { 00359 /* Start with calling the server. */ 00360 applications::session::PDU* applicationPDU = new applications::session::PDU(Bit(comfortNoisePacketSize), pyco); 00361 applicationPDU->setCreationTime(wns::simulator::getEventScheduler()->getTime()); 00362 00363 packetSize = comfortNoisePacketSize; 00364 00365 packetNumber = 1; 00366 applicationPDU->setPacketNumber(packetNumber, packetFrom); 00367 MESSAGE_SINGLE(NORMAL, logger, "APPL: PacketNumber = " << packetNumber << "."); 00368 00369 wns::osi::PDUPtr pdu(applicationPDU); 00370 applications::session::Session::outgoingProbesCalculation(pdu); 00371 00372 connection->sendData(pdu); 00373 00374 state = idle; 00375 } 00376 else 00377 { 00378 assure(false, "APPL: Unknown timout type =" << _t); 00379 } 00380 } 00381 00382 00383 void 00384 VideoTelephony::onConnectionEstablished(wns::service::tl::Connection* _connection) 00385 { 00386 /* Connection is ready, so start sending after session start delay. */ 00387 connection = _connection; 00388 establishedAt = wns::simulator::getEventScheduler()->getTime(); 00389 00390 MESSAGE_SINGLE(NORMAL, logger, "APPL: Connection established!"); 00391 00392 onTimeout(calltimeout); 00393 } 00394 00395 00396 void 00397 VideoTelephony::calculateSLRangeDependency() 00398 { 00399 /* Callculation of the short- and longrangedependencies. 00400 For detailed discription see diplomathesis of Cem Mengi 10.07.2006: 00401 "Conception and implementation of traffic Models for VoIP and Videotelephony". */ 00402 MESSAGE_SINGLE(NORMAL, logger, "APPL: Callculation of the short- and longrange dependencies!"); 00403 00404 fracI = hurstI - 0.5; 00405 fracP = hurstP - 0.5; 00406 fracB = hurstB - 0.5; 00407 00408 autocorrI.push_back(1.0); 00409 autocorrP.push_back(1.0); 00410 autocorrB.push_back(1.0); 00411 00412 /* This distribution is just used one time and deleted after that. 00413 Next time a new distribution is used.*/ 00414 logNormDisI = new wns::distribution::Norm(meanI, varianceI); 00415 logNormValueI = (*logNormDisI)(); 00416 xI.push_back(logNormValueI); 00417 00418 logNormDisP = new wns::distribution::Norm(meanP, varianceP); 00419 logNormValueP = (*logNormDisP)(); 00420 xP.push_back(logNormValueP); 00421 00422 logNormDisB = new wns::distribution::Norm(meanB, varianceB); 00423 logNormValueB = (*logNormDisB)(); 00424 xB.push_back(logNormValueB); 00425 00426 delete logNormDisI; 00427 logNormDisI = NULL; 00428 00429 delete logNormDisP; 00430 logNormDisP = NULL; 00431 00432 delete logNormDisB; 00433 logNormDisB = NULL; 00434 00435 for(i = 1; i < limit; i++) 00436 { 00437 autocorrI.push_back(autocorrI[i - 1] * ((static_cast<float>(i - 1) + fracI)/ (static_cast<float>(i) - fracI))); 00438 autocorrP.push_back(autocorrP[i - 1] * ((static_cast<float>(i - 1) + fracP)/ (static_cast<float>(i) - fracP))); 00439 autocorrB.push_back(autocorrB[i - 1] * ((static_cast<float>(i - 1) + fracB)/ (static_cast<float>(i) - fracB))); 00440 00441 pI = 0; 00442 pP = 0; 00443 pB = 0; 00444 00445 for(j = 1; j <= (i-1); j++) 00446 { 00447 pI = pI + phiIold[j - 1] * autocorrI[i - j]; 00448 pP = pP + phiPold[j - 1] * autocorrP[i - j]; 00449 pB = pB + phiBold[j - 1] * autocorrB[i - j]; 00450 } 00451 00452 dI = dI - ((nI * nI) / dI); 00453 nI = autocorrI[i] - pI; 00454 dP = dP - ((nP * nP) / dP); 00455 nP = autocorrP[i] - pP; 00456 dB = dB - ((nB * nB) / dB); 00457 nB = autocorrB[i] - pB; 00458 00459 phiInew.push_back(nI / dI); 00460 phiPnew.push_back(nP / dP); 00461 phiBnew.push_back(nB / dB); 00462 00463 idx = i; 00464 00465 meanI = phiInew[0] * xI[0]; 00466 meanP = phiPnew[0] * xP[0]; 00467 meanB = phiBnew[0] * xB[0]; 00468 00469 for(idx = i; idx > 1; idx--) 00470 { 00471 00472 phiInew.push_front(phiIold[idx - 2] - (phiInew[i - idx] * phiIold[i - idx])); 00473 phiPnew.push_front(phiPold[idx - 2] - (phiPnew[i - idx] * phiPold[i - idx])); 00474 phiBnew.push_front(phiBold[idx - 2] - (phiBnew[i - idx] * phiBold[i - idx])); 00475 00476 meanI = meanI + (phiInew[0] * xI[i - idx + 1]); 00477 meanP = meanP + (phiPnew[0] * xP[i - idx + 1]); 00478 meanB = meanB + (phiBnew[0] * xB[i - idx + 1]); 00479 00480 } 00481 00482 varianceI = (1 - pow(phiInew[i - 1], 2)) * varianceI; 00483 varianceP = (1 - pow(phiPnew[i - 1], 2)) * varianceP; 00484 varianceB = (1 - pow(phiBnew[i - 1], 2)) * varianceB; 00485 00486 /* This distribution is just used one time and deleted after that. 00487 Next time a new distribution is used.*/ 00488 logNormDisI = new wns::distribution::Norm(meanI, varianceI); 00489 logNormValueI = (*logNormDisI)(); 00490 xI.push_back(logNormValueI); 00491 00492 logNormDisP = new wns::distribution::Norm(meanP, varianceP); 00493 logNormValueP = (*logNormDisP)(); 00494 xP.push_back(logNormValueP); 00495 00496 logNormDisB = new wns::distribution::Norm(meanB, varianceB); 00497 logNormValueB = (*logNormDisB)(); 00498 xB.push_back(logNormValueB); 00499 00500 phiIold.clear(); 00501 phiPold.clear(); 00502 phiBold.clear(); 00503 phiIold = phiInew; 00504 phiPold = phiPnew; 00505 phiBold = phiBnew; 00506 phiInew.clear(); 00507 phiPnew.clear(); 00508 phiBnew.clear(); 00509 00510 delete logNormDisI; 00511 logNormDisI = NULL; 00512 00513 delete logNormDisP; 00514 logNormDisP = NULL; 00515 00516 delete logNormDisB; 00517 logNormDisB = NULL; 00518 00519 } 00520 00521 xI.pop_front(); 00522 xP.pop_front(); 00523 xB.pop_front(); 00524 00525 autocorrI.clear(); 00526 autocorrP.clear(); 00527 autocorrB.clear(); 00528 } 00529 00530 00531 void 00532 VideoTelephony::logNormalProjectedFarima(std::deque<double> _x, std::deque<double> _phiold, double _y, 00533 double _phi, double _theta, double _m, double _sqrValue, 00534 double _variance, int _k, double _logMean, double _logStd) 00535 { 00536 mean = 0; 00537 n = 0; 00538 while(n < limit - 1) 00539 { 00540 mean = mean + _x[n] * _phiold[limit - n - 2]; 00541 00542 n = n + 1; 00543 } 00544 _variance = (1 - pow(_phiold[limit - 2], 2)) * _variance; 00545 00546 distribution = new wns::distribution::Norm(mean, _variance); 00547 distributionValue = (*distribution)(); 00548 _x.push_back(distributionValue); 00549 00550 _y = _x[limit - 1]; 00551 00552 _m = _m + _y; 00553 00554 _sqrValue = _sqrValue + pow(_y, 2); 00555 00556 normMean = _m / static_cast<int>((float)(_k + 1)); 00557 00558 variance = (_sqrValue - (pow(_m, 2) / static_cast<int>((float)(_k + 1)))) / static_cast<int>((float)(_k)); 00559 00560 packetSize = exp(_logMean + (_logStd * ((_y - normMean) / sqrt(variance)))) + 1; 00561 00562 if(byteFlag == true) 00563 { 00564 packetSize *= 8.0; 00565 } 00566 00567 _x.pop_front(); 00568 _k = _k + 1; 00569 00570 delete distribution; 00571 distribution = NULL; 00572 00573 applications::session::PDU* applicationPDU = new applications::session::PDU(Bit(packetSize), pyco); 00574 applicationPDU->setCreationTime(wns::simulator::getEventScheduler()->getTime()); 00575 00576 ++packetNumber; 00577 applicationPDU->setPacketNumber(packetNumber, packetFrom); 00578 MESSAGE_SINGLE(NORMAL, logger, "APPL: PacketNumber = " << packetNumber << "."); 00579 00580 wns::osi::PDUPtr pdu(applicationPDU); 00581 applications::session::Session::outgoingProbesCalculation(pdu); 00582 00583 connection->sendData(pdu); 00584 }
1.5.5