TimeMeasurement.cpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: TimeMeasurement.cpp (S H A R E D) * 00006 * * 00007 * * 00008 * * 00009 * ITEC institute of the University of Klagenfurt (Austria) * 00010 * http://www.itec.uni-klu.ac.at * 00011 * * 00012 * * 00013 * For more information visit the ViTooKi homepage: * 00014 * http://ViTooKi.sourceforge.net * 00015 * vitooki-user@lists.sourceforge.net * 00016 * vitooki-devel@lists.sourceforge.net * 00017 * * 00018 * This file is part of ViTooKi, a free video toolkit. * 00019 * ViTooKi is free software; you can redistribute it and/or * 00020 * modify it under the terms of the GNU General Public License * 00021 * as published by the Free Software Foundation; either version 2 * 00022 * of the License, or (at your option) any later version. * 00023 * * 00024 * This program is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU General Public License * 00030 * along with this program; if not, write to the Free Software * 00031 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 00032 * MA 02111-1307, USA. * 00033 * * 00034 ***********************************************************************/ 00035 00036 /*********************************************************************** 00037 * * 00038 * REVISION HISTORY: * 00039 * * 00040 * * 00041 * * 00042 ***********************************************************************/ 00043 00044 /*********************************************************************** 00045 * Video Session Migration System, 2004 * 00046 * Author: Klaus Schoeffmann * 00047 ************************************************************************/ 00048 00049 00050 #include "TimeMeasurement.hpp" 00051 00052 00053 /***********************************************************************/ 00054 TimeMeasurement::TimeMeasurement() 00055 { 00056 previousSessionDuration = 0; 00057 duration = 0; 00058 sections = new vector<TimeSection*>; 00059 } 00060 00061 /***********************************************************************/ 00062 TimeMeasurement::~TimeMeasurement() 00063 { 00064 Globals::sdebug << "\nimeMeasurement::~TimeMeasurement() cleanup..."; 00065 vector<TimeSection*>::iterator iter = sections->begin(); 00066 while (iter != sections->end()) 00067 { 00068 TimeSection *sect = *iter; 00069 delete sect; 00070 iter++; 00071 } 00072 sections->clear(); 00073 Globals::sdebug << "\nimeMeasurement::~TimeMeasurement() done!"; 00074 } 00075 00076 /***********************************************************************/ 00077 void TimeMeasurement::addNewSection(ulong prebuffertime) 00078 { 00079 Globals::sdebug << "\nTimeMeasurement::addNewSection"; 00080 assert(sections != NULL); 00081 assert(sections->size() >= 0); 00082 Globals::sdebug << "\nbefore new ts"; 00083 int sectionNumber = sections->size(); 00084 Globals::sdebug << "\nsections.size = " << sectionNumber; 00085 Globals::sdebug << "\nprebuffertime = " << prebuffertime; 00086 //TODO: sometimes the proxy crashes exactly on the next line. However, I do not know why??? 00087 TimeSection *ts = new TimeSection(sectionNumber+1, prebuffertime); 00088 Globals::sdebug << "\nafter new ts"; 00089 assert(ts != NULL); 00090 sections->push_back(ts); 00091 Globals::sdebug << "\nTimeMeasurement:: session added"; 00092 } 00093 00094 /***********************************************************************/ 00095 void TimeMeasurement::setPreviousSessionDuration(ulong previousSessionDuration) 00096 { 00097 this->previousSessionDuration = previousSessionDuration; 00098 } 00099 00100 /***********************************************************************/ 00101 void TimeMeasurement::setDuration(ulong duration) 00102 { 00103 this->duration = duration; 00104 } 00105 00106 /***********************************************************************/ 00107 ulong TimeMeasurement::getPreviousSessionDuration() 00108 { 00109 return previousSessionDuration; 00110 } 00111 00112 /***********************************************************************/ 00113 ulong TimeMeasurement::getDuration() 00114 { 00115 return duration; 00116 } 00117 00118 /***********************************************************************/ 00119 void TimeMeasurement::startTS() 00120 { 00121 assert(sections->back() != NULL); 00122 00123 TimeSection *ts = sections->back(); 00124 ts->start(); 00125 } 00126 00127 /***********************************************************************/ 00128 void TimeMeasurement::stopTS() 00129 { 00130 assert(sections->back() != NULL); 00131 00132 TimeSection *ts = sections->back(); 00133 ts->stop(); 00134 } 00135 00136 /***********************************************************************/ 00137 void TimeMeasurement::setTSrequestedFrom(ulong reqfrom) 00138 { 00139 assert(sections->back() != NULL); 00140 00141 //set range-from value for current time-section 00142 vector<TimeSection*>::const_iterator iter = sections->end(); 00143 iter--; 00144 TimeSection *ts = *iter; 00145 ts->setRequestedFrom(reqfrom); 00146 00147 //look if there exists a previous time-section 00148 if (iter != sections->begin()) 00149 { 00150 //set corrected time-TO on previous time-section 00151 iter--; 00152 TimeSection *prevts = *iter; 00153 prevts->setClientReceived(reqfrom - prevts->getRequestedFrom()); 00154 } 00155 00156 Globals::sdebug << "\nTimeMeasurement::setTSrequestedFrom(): " << reqfrom; 00157 } 00158 00159 00160 /***********************************************************************/ 00161 void TimeMeasurement::setTSserverPlayout(ulong playout) 00162 { 00163 assert(sections->back() != NULL); 00164 00165 TimeSection *ts = sections->back(); 00166 ts->setServerPlayout(playout); 00167 } 00168 00169 00170 /***********************************************************************/ 00171 void TimeMeasurement::setTSclientPlayout(ulong playout) 00172 { 00173 assert(sections->back() != NULL); 00174 00175 TimeSection *ts = sections->back(); 00176 ts->setClientPlayout(playout); 00177 } 00178 00179 /***********************************************************************/ 00180 uint TimeMeasurement::getTimeSectionCount() 00181 { 00182 return sections->size(); 00183 } 00184 00185 /***********************************************************************/ 00186 ulong TimeMeasurement::getElapsedTime(uint sectionNr, ulong currserverPlayout, ulong currclientPlayout) 00187 { 00188 assert(sections->back() != NULL); 00189 00190 Globals::sdebug << "\n********************************\n"; 00191 Globals::sdebug << "\nTimeMeasurement::getElapsedTime() sectionNr=" << sectionNr << ", currserverPlayout=" << currserverPlayout << ", currclientPlayout=" << currclientPlayout; 00192 00193 //elapsed time, considering all time-sections 00194 long tmElapsed = 0; 00195 00196 //cumulative client-received 00197 //this value contains the duration of all time-sections, which 00198 //were confirmed by the client 00199 ulong cumClientReceived = 0; 00200 00201 //if there was a section-number specified, iterate 00202 //through the sections only until specified section-number 00203 uint untilSection = sections->size(); 00204 if (sectionNr != 0) 00205 { 00206 untilSection = sectionNr; 00207 } 00208 Globals::sdebug << "\nTimeMeasurement::getElapsedTime(): untilSection=" << untilSection; 00209 00210 //iterate through sections 00211 vector<TimeSection*>::const_iterator iter = sections->begin(); 00212 for (uint i =1; iter != sections->end() && i <= untilSection; iter++, i++) 00213 { 00214 TimeSection *ts = *iter; 00215 long tsElapsed; //elapsed time of time-section 00216 00217 if (ts->getMeasuredStarttime() == 0) 00218 { 00219 cerr << "\nWARNING: getmeasuredstarttime of timesection " << i << " == 0 !!!" << endl; 00220 } 00221 else 00222 { 00223 00224 Globals::sdebug << "\nTimeMeasurement::getElapsedTime()" << i << ": "; 00225 00226 //calculate elapsed time of this time-section 00227 //if we do not have an endtime yet, use current time as end-time 00228 Globals::sdebug << "\n\t measuredendtime=" << ts->getMeasuredEndtime() << " "; 00229 if (ts->getMeasuredEndtime() != 0) 00230 { 00231 tsElapsed = ts->getMeasuredEndtime() - ts->getMeasuredStarttime() - ts->getPrebufferTime(); 00232 } 00233 else 00234 { 00235 tsElapsed = ts->getCurrentMsecs() - ts->getMeasuredStarttime() - ts->getPrebufferTime(); 00236 } 00237 00238 //if session has not been started already, correct value to null 00239 if (tsElapsed < 0) tsElapsed = 0; 00240 00241 //if we have a value confirmed by the player for this section, use this instead of 00242 if (currclientPlayout != 0 && ((iter+1) == sections->end())) 00243 { 00244 tmElapsed = currclientPlayout; 00245 Globals::sdebug << "\nTimeMeasurement::getElapsedTime(): current CLIENT playout chosen"; 00246 } 00247 else if (ts->getClientReceived() != 0) 00248 { 00249 tmElapsed += ts->getClientReceived(); 00250 cumClientReceived += ts->getClientReceived(); 00251 Globals::sdebug << "\nTimeMeasurement::getElapsedTime(): CLIENTRECEIVE(pause) chosen"; 00252 Globals::sdebug << "\t(clientreceived=" << ts->getClientReceived() << " cumclientreceived=" << cumClientReceived << ") "; 00253 } 00254 else if (currserverPlayout != 0 && ((iter+1) == sections->end())) 00255 { 00256 Globals::sdebug << "\n\t currserverPlayout=" << currserverPlayout; 00257 //if we have a value confirmed by the player for the last section, use this instead of 00258 if (i > 1 && cumClientReceived != 0) 00259 { 00260 tmElapsed = cumClientReceived + (currserverPlayout - (*(iter-1))->getServerPlayout()); 00261 cumClientReceived = 0; //do not use this value for later sections 00262 Globals::sdebug << "\nTimeMeasurement::getElapsedTime(): CORRECTED SERVERPLAYOUT chosen"; 00263 Globals::sdebug << "\t corrected clientplayout=" << tmElapsed; 00264 } 00265 else 00266 { 00267 tmElapsed = currserverPlayout; 00268 Globals::sdebug << "\nTimeMeasurement::getElapsedTime(): current SERVER playout chosen"; 00269 } 00270 } 00271 else 00272 { 00273 00274 //if we have a value from the client or the mediaserver, use this instead of 00275 //(attention!: this value is cumulative) 00276 //otherwise use calculation above 00277 if (ts->getClientPlayout() != 0) 00278 { 00279 Globals::sdebug << "\nTimeMeasurement::getElapsedTime(): CLIENT playout chosen"; 00280 Globals::sdebug << "(\t clientplayout=" << ts->getClientPlayout() << ") "; 00281 tmElapsed += ts->getClientPlayout(); 00282 } 00283 else if (ts->getServerPlayout() != 0) 00284 { 00285 Globals::sdebug << "\nTimeMeasurement::getElapsedTime(): SERVER playout chosen"; 00286 Globals::sdebug << "(\t serverplayout=" << ts->getServerPlayout() << ") "; 00287 //on more than one timesections: if we have a previous section, which 00288 //were confirmed by the client, add difference to that confirmed value 00289 if (i > 1 && cumClientReceived != 0) 00290 { 00291 tmElapsed = cumClientReceived + (ts->getServerPlayout() - (*(iter-1))->getServerPlayout()); 00292 cumClientReceived = 0; //do not use this value for later sections 00293 Globals::sdebug << "\n\t corrected clientplayout=" << tmElapsed << " "; 00294 } 00295 else 00296 { 00297 tmElapsed = ts->getServerPlayout(); 00298 } 00299 } 00300 else 00301 { 00302 tmElapsed += tsElapsed; 00303 Globals::sdebug << "\nTimeMeasurement::getElapsedTime(): OWN ESTIMANTION chosen (tmElapsed=" << tmElapsed << ")"; 00304 } 00305 00306 } 00307 } 00308 } 00309 00310 Globals::sdebug << "\nTimeMeasurement::getElapsedTime(): tmElapsed=" << tmElapsed << " prevSD=" << previousSessionDuration; 00311 Globals::sdebug << "\nTimeMeasurement::getElapsedTime(): RESULT=" << (tmElapsed + previousSessionDuration); 00312 Globals::sdebug << "\n********************************\n"; 00313 00314 return tmElapsed + previousSessionDuration; 00315 }