UserPreferences.hpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: UserPreferences.hpp * 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 #ifndef PS_PROXY_USERPREFERENCES_HPP 00045 #define PS_PROXY_USERPREFERENCES_HPP 00046 #include <cstdlib> 00047 #include <cstdio> 00048 #include <cassert> 00049 #include <cfloat> 00050 #include <cstring> 00051 #include <cmath> 00052 00053 #define BORDER_QUALITY 0.1f 00054 #define MAXIMUM_ACCEPTABLE_DELAY 1000 00055 #define DELAY_TO_SERVER 800 00056 #include "VideoESInfo.hpp" 00057 00058 class TerminalCapabilities; 00059 #include "net/Url.hpp" 00060 #include "ContainerInfo.hpp" 00061 00062 typedef struct FeaturePoint{ 00063 int point; 00064 double importance; 00065 FeaturePoint(const FeaturePoint& fp) 00066 { 00067 point=fp.point;importance=fp.importance; 00068 }; 00069 FeaturePoint(const FeaturePoint* fp) 00070 { 00071 assert(fp); 00072 point=fp->point;importance=fp->importance; 00073 }; 00074 FeaturePoint(int val,double imp) { 00075 point=val; 00076 importance=imp; 00077 }; 00078 double calcPointQuality(int val) const{ 00079 if(val==point) 00080 return importance; 00081 return 0.0; 00082 }; 00084 double calcQuality(int val) const{ 00085 if(val<=0 || val>point) 00086 return 0.0; 00087 return ((double)val)/point; 00088 }; 00090 double calcInverseQuality(int val) const{ 00091 if(val<0 || val>point) 00092 return 0.0; 00093 return ((double)(point-val))/point*importance; 00094 }; 00095 static FeaturePoint* create(FILE* fp) 00096 { 00097 if(!fp) 00098 return NULL; 00099 00100 char temp[4960]; 00101 if(fp==stdin) { 00102 printf("\n(value)/importance: "); 00103 fflush(stdout); 00104 } 00105 fgets(temp,4096,fp); 00106 return FeaturePoint::create(temp); 00107 00108 } 00109 static FeaturePoint* create(const char* temp) 00110 { 00111 int val;double imp; 00112 if(2!=sscanf(temp, "(%i)/%lf", &val,&imp)) 00113 return NULL; 00114 return new FeaturePoint(val,imp); 00115 } 00116 char* toString() const{ 00117 char* res=new char[32]; 00118 sprintf(res,"(%i)/%lf",point,importance); 00119 return res; 00120 } 00121 } FeaturePoint; 00122 00123 typedef struct FeatureRange{ 00124 int best; 00125 int min; 00126 int max; 00127 double importance; 00128 FeatureRange(const FeatureRange& df) 00129 { 00130 best=df.best;min=df.min;max=df.max;importance=df.importance; 00131 }; 00132 00133 FeatureRange(const FeatureRange* df) 00134 { 00135 assert(df); 00136 best=df->best;min=df->min;max=df->max;importance=df->importance; 00137 }; 00138 00139 FeatureRange(int mn,int bst,int mx,double imp) 00140 { 00141 assert(mn<=bst && bst<=mx && 0.0<=imp && imp<=1.0); 00142 min=mn;best=bst;max=mx;importance=imp; 00143 }; 00144 double calcQuality(int value) const 00145 { 00146 if(value<min || value>max) 00147 return 0.0; 00148 00149 if(value>=best) { 00150 if(max==best) { 00151 if(value==max) 00152 return importance; 00153 else 00154 return 0.0; 00155 } 00156 return importance*((max-value)*(1.0-BORDER_QUALITY)/(max-best)+BORDER_QUALITY); 00157 } 00158 else { 00159 if(best==min) 00160 if(value==best) 00161 return importance; 00162 else 00163 return 0.0; 00164 return importance*((value-min)*(1.0-BORDER_QUALITY)/(best-min)+BORDER_QUALITY); 00165 } 00166 }; 00167 static FeatureRange* create(FILE* fp) 00168 { 00169 00170 if(!fp) 00171 return NULL; 00172 00173 char temp[4960]; 00174 if(fp==stdin) { 00175 printf("\n(min,medium,max)/importance: "); 00176 fflush(stdout); 00177 } 00178 fgets(temp,4096,fp); 00179 return FeatureRange::create(temp); 00180 00181 }; 00182 static FeatureRange* create(const char* buf) 00183 { 00184 int mn;int bst;int max;double imp; 00185 if(4!=sscanf(buf, "(%i,%i,%i)/%lf",&mn,&bst, &max,&imp)) 00186 return NULL; 00187 return new FeatureRange(mn,bst,max,imp); 00188 }; 00189 char* toString() const{ 00190 char* res=new char[32]; 00191 sprintf(res,"(%i,%i,%i)/%lf",min,best,max,importance); 00192 return res; 00193 } 00194 } FeatureRange; 00195 00196 typedef struct Feature{ 00197 00198 char* url; 00199 int dimX; 00200 int dimY; 00201 int color; 00202 int bitrate; 00203 int numBFrames; 00204 int avgBFrameSize; 00205 double frameRate; 00206 double durationInSec; 00207 int isCached; 00208 int contentCosts; 00209 unsigned long lockedUntilTimePoint; 00210 00211 Feature() 00212 { 00213 url=NULL; 00214 dimX=dimY=color=bitrate=numBFrames=avgBFrameSize=isCached=contentCosts=0; 00215 lockedUntilTimePoint=0; 00216 frameRate=durationInSec=0; 00217 }; 00218 Feature(const VideoESInfo* vid) 00219 { 00220 url=NULL; 00221 bitrate=vid->getAvgBandwidth(); 00222 durationInSec=vid->getDurationInMs()/1000.0; 00223 frameRate=(double)vid->getFPS(); 00224 color= (vid->getHasColor()?1:0); 00225 dimX=vid->getWidth(); 00226 dimY=vid->getHeight(); 00227 if(vid->hasStaticFramePattern()) { 00228 int bFramesBetween=vid->getNum_B_frames(); 00229 numBFrames=(int)(bFramesBetween*vid->getFPS()/(bFramesBetween+1)); 00230 } 00231 else { 00232 // assume every 5th frame to be a B-vop and using 10% data 00233 numBFrames=(int)(vid->getFPS()/5); 00234 } 00235 avgBFrameSize= (int)((vid->getAvgBFrameSize()*bitrate) / numBFrames); 00236 isCached=false; 00237 contentCosts=0; 00238 lockedUntilTimePoint=0; 00239 }; 00240 Feature(const Feature& f) 00241 { 00242 if(f.url) { 00243 url=new char[strlen(f.url)+1]; 00244 strcpy(url,f.url); 00245 } 00246 else 00247 url=NULL; 00248 dimX=f.dimX; 00249 dimY=f.dimY; 00250 color=f.color; 00251 isCached=f.isCached; 00252 bitrate=f.bitrate; 00253 frameRate=f.frameRate; 00254 numBFrames=f.numBFrames; 00255 avgBFrameSize=f.avgBFrameSize; 00256 durationInSec=f.durationInSec; 00257 contentCosts=f.contentCosts; 00258 lockedUntilTimePoint=f.lockedUntilTimePoint; 00259 } 00260 00261 Feature(const Feature* f) 00262 { 00263 if(f->url) { 00264 url=new char[strlen(f->url)+1]; 00265 strcpy(url,f->url); 00266 } 00267 else 00268 url=NULL; 00269 00270 dimX=f->dimX; 00271 dimY=f->dimY; 00272 color=f->color; 00273 isCached=f->isCached; 00274 bitrate=f->bitrate; 00275 frameRate=f->frameRate; 00276 numBFrames=f->numBFrames; 00277 avgBFrameSize=f->avgBFrameSize; 00278 durationInSec=f->durationInSec; 00279 contentCosts=f->contentCosts; 00280 lockedUntilTimePoint=f->lockedUntilTimePoint; 00281 }; 00282 00283 Feature(int dx,int dy,int col,int br, int cached, int ccost,double fr, double dur) 00284 { 00285 dimX=dx; 00286 dimY=dy; 00287 color=col; 00288 isCached=cached; 00289 bitrate=br; 00290 frameRate=fr; 00291 numBFrames=(int)((frameRate-1.0)/2); 00292 avgBFrameSize=(int)(bitrate*0.2/numBFrames); 00293 durationInSec=dur; 00294 contentCosts=ccost; 00295 lockedUntilTimePoint=0; 00296 url=NULL; 00297 }; 00298 00299 Feature(const char* uri, int dx,int dy,int col,int br, int cached, int ccost,double fr, double dur) 00300 { 00301 assert(uri); 00302 url = new char[strlen(uri)+1]; 00303 strcpy(url,uri); 00304 dimX=dx; 00305 dimY=dy; 00306 color=col; 00307 isCached=cached; 00308 bitrate=br; 00309 frameRate=fr; 00310 numBFrames=(int)((frameRate-1.0)/2); 00311 avgBFrameSize=(int)(bitrate*0.2/numBFrames); 00312 durationInSec=dur; 00313 contentCosts=ccost; 00314 lockedUntilTimePoint=0; 00315 }; 00316 00317 ~Feature() 00318 { 00319 if( url) delete[] url; 00320 }; 00321 00322 unsigned long getSizeInBytes() const { 00323 return ((unsigned long)(bitrate*(durationInSec/8.0))); 00324 } 00325 double getAspectRatio() const { 00326 return ((double)dimX)/dimY; 00327 } 00328 bool canReduceBFramesToBitrate(int newbr,double* newFrameRate,int* newBitRate) const{ 00329 assert(newFrameRate && newBitRate); 00330 *newFrameRate=0.0; 00331 *newBitRate=0; 00332 int br_diff=bitrate-newbr; 00333 if(br_diff>0) { 00334 int dropFrames=(int)(floor( ((double)br_diff)/avgBFrameSize)); 00335 if(dropFrames>numBFrames) 00336 return false; 00337 *newFrameRate=numBFrames-dropFrames; 00338 *newBitRate=bitrate-(dropFrames*avgBFrameSize); 00339 return true; 00340 } 00341 return true; 00342 } 00343 bool reduceBFramesToBitrate(int newbr) { 00344 int br_diff=bitrate-newbr; 00345 if(br_diff>0) { 00346 int dropFrames=(int)(floor( ((double)br_diff)/avgBFrameSize)); 00347 if(dropFrames>numBFrames) 00348 return false; 00349 numBFrames-=dropFrames; 00350 bitrate-=(dropFrames*avgBFrameSize); 00351 return true; 00352 } 00353 return true; 00354 } 00355 char* toString() { 00356 char* txt=new char[180]; 00357 sprintf(txt,"(%i,%i,%i,%i,%.2lf/%i(%i bytes)):costs=%i:cached=%i:lockedTill=%lu\r\n", 00358 dimX,dimY,bitrate,color,frameRate,numBFrames,avgBFrameSize, 00359 contentCosts,isCached,lockedUntilTimePoint); 00360 return txt; 00361 } 00362 static Feature* create(FILE* fp) 00363 { 00364 if(!fp) 00365 return NULL; 00366 int dimX,dimY,bitrate,isCached,color,contentCosts; 00367 double durationInSec,frameRate; 00368 char temp[4960]; 00369 00370 if(fp==stdin) { 00371 printf("\ndimX dimY bitrate framerate durationInSec isCached(0 or 1) color(0 or 1) contentcost:"); 00372 fflush(stdout); 00373 } 00374 temp[0]='\0'; 00375 fgets(temp,4096,fp); 00376 int i=sscanf(temp,"%i %i %i %lf %lf %i %i %i", &dimX,&dimY,&bitrate, 00377 &frameRate, &durationInSec, &isCached, &color, &contentCosts); 00378 if(i==8) 00379 return new Feature(dimX,dimY,color,bitrate,isCached, contentCosts, frameRate,durationInSec); 00380 00381 return NULL; 00382 }; 00383 } Feature, Video; 00384 00385 typedef struct dFeatureRange{ 00386 double best; 00387 double min; 00388 double max; 00389 double importance; 00390 00391 dFeatureRange(const dFeatureRange& df) 00392 { 00393 best=df.best;min=df.min;max=df.max;importance=df.importance; 00394 }; 00395 00396 dFeatureRange(const dFeatureRange* df) 00397 { 00398 assert(df); 00399 best=df->best;min=df->min;max=df->max;importance=df->importance; 00400 }; 00401 00402 dFeatureRange(double mn,double bst,double mx,double imp) 00403 { 00404 assert(mn<=bst && bst<=mx && 0.0<=imp && imp<=1.0); 00405 min=mn;best=bst;max=mx;importance=imp; 00406 }; 00407 00408 double calcQuality(double value) const 00409 { 00410 if(value<min || value>max) 00411 return 0.0; 00412 00413 if(value>=best) { 00414 if(fabs(max-best)<0.01) { 00415 if(fabs(value-max)<0.01) 00416 return importance; 00417 else 00418 return 0.0; 00419 } 00420 return importance*((max-value)*(1.0-BORDER_QUALITY)/(max-best)+BORDER_QUALITY);; 00421 } 00422 else { 00423 if(fabs(best-min)<0.01) 00424 if(fabs(value-best)<0.01) 00425 return importance; 00426 else 00427 return 0.0; 00428 return importance*((value-min)*(1.0-BORDER_QUALITY)/(best-min)+BORDER_QUALITY);; 00429 } 00430 }; 00431 static dFeatureRange* create(FILE* fp) 00432 { 00433 00434 if(!fp) 00435 return NULL; 00436 00437 char temp[4960]; 00438 if(fp==stdin) { 00439 printf("\n(min,medium,max)/importance: "); 00440 fflush(stdout); 00441 } 00442 fgets(temp,4096,fp); 00443 return dFeatureRange::create(temp); 00444 00445 }; 00446 static dFeatureRange* create(const char* buf) 00447 { 00448 double mn, bst, max;double imp; 00449 if(4!=sscanf(buf, "(%lf,%lf,%lf)/%lf",&mn,&bst, &max,&imp)) 00450 return NULL; 00451 return new dFeatureRange(mn,bst,max,imp); 00452 }; 00453 char* toString() const { 00454 char* res=new char[64]; 00455 sprintf(res,"(%lf,%lf,%lf)/%lf",min,best,max,importance); 00456 return res; 00457 } 00458 } dFeatureRange; 00459 00460 class UserPreferences 00461 { 00462 //FIXME protected: 00463 public: 00464 FeatureRange dimX; 00465 FeatureRange bitrate; 00466 FeaturePoint delayInMS; 00467 FeaturePoint color; 00468 dFeatureRange frameRate; 00469 double pay; 00470 00471 public: 00472 UserPreferences(const TerminalCapabilities* tc); 00473 UserPreferences(const UserPreferences* s); 00474 00476 UserPreferences(const FeatureRange& dX,const FeatureRange& br, 00477 const FeaturePoint& delay, const FeaturePoint& col, const dFeatureRange& fr,const double& pa); 00478 00480 UserPreferences(const FeatureRange* dX, const FeatureRange* br, 00481 const FeaturePoint* delay, const FeaturePoint* col, const dFeatureRange* fr,const double& pa); 00482 double calcQuality(const Feature* target, int delay) const; 00483 00484 static UserPreferences* create(FILE* fp); 00485 00486 static UserPreferences* create(const char* buf); 00487 00488 void correctBitRate(int dimX, int dimY); 00489 00490 void correctDimension(); 00491 00492 char* toString() const; 00493 00494 static void doTest(); 00495 }; 00496 00497 00498 00499 00500 #endif 00501 00502