Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members
GlobalTimer.cpp
00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: GlobalTimer.cpp * 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 #include "GlobalTimer.hpp" 00045 00046 /* condition represented by cond_block */ 00047 #define COND_NOT_BLOCKED (pauseRefCnt.getUsage() == 0 && prefetchRefCnt.getUsage() == 0) 00048 00049 00050 GlobalTimer::GlobalTimer() { 00051 dprintf_full("GlobalTimer:: Construct\n"); 00052 cond_block.initialize(); 00053 cond_block_mutex.initialize("GlobalTimer-cond_block_mutex"); 00054 time_mutex.initialize("GlobalTimer-time_mutex"); 00055 strcpy(name,"GlobalTimer"); 00056 reset(); 00057 } 00058 00059 00060 GlobalTimer::~GlobalTimer() { 00061 dprintf_full("GlobalTimer::~GlobalTimer\n"); 00062 cond_block.destroy(); 00063 cond_block_mutex.destroy(); 00064 time_mutex.destroy(); 00065 } 00066 00067 00068 void GlobalTimer::reset() { 00069 dprintf_full("GlobalTimer::reset\n"); 00070 00071 cond_block_mutex.lock(); 00072 es=NULL; 00073 firstFrame = true; 00074 wasBlocked = false; 00075 dropUntil = 0; 00076 pauseRefCnt.reset(); 00077 prefetchRefCnt.reset(); 00078 00079 time_mutex.lock(); 00080 now_dtime = 0.0; 00081 start_dtime = 0.0; 00082 actualSec = 0.0; 00083 time_mutex.release(); 00084 00085 cond_block.broadcast(); 00086 cond_block_mutex.release(); 00087 } 00088 00089 00090 void GlobalTimer::initialize() { 00091 reset(); 00092 } 00093 00094 00095 void GlobalTimer::setPaused(bool setPause) { 00096 cond_block_mutex.lock(); 00097 if (setPause) { 00098 pauseRefCnt.increase(); 00099 } else { 00100 wasBlocked = !COND_NOT_BLOCKED; 00101 pauseRefCnt.decrease(); 00102 if (COND_NOT_BLOCKED) 00103 cond_block.broadcast(); 00104 } 00105 dprintf_full("GlobalTimer::setPaused(%s) Number of Pausers now: %i\n", 00106 setPause ? "true" : "false", pauseRefCnt.getUsage()); 00107 cond_block_mutex.release(); 00108 } 00109 00110 00111 void GlobalTimer::setPrefetching(bool setPrefetching) { 00112 cond_block_mutex.lock(); 00113 if (setPrefetching) { 00114 prefetchRefCnt.increase(); 00115 } else { 00116 wasBlocked = !COND_NOT_BLOCKED; 00117 prefetchRefCnt.decrease(); 00118 if (COND_NOT_BLOCKED) 00119 cond_block.broadcast(); 00120 } 00121 dprintf_full("GlobalTimer::setPrefetching(%s) Number of Prefetchers now: %i\n", 00122 setPrefetching ? "true" : "false", prefetchRefCnt.getUsage()); 00123 cond_block_mutex.release(); 00124 } 00125 00126 00127 double GlobalTimer::getActualSec() { 00128 if (start_dtime == 0.0) 00129 return 0.0; 00130 if (!isPaused()) { 00131 time_mutex.lock(); 00132 gettimeofday(&tv,NULL); 00133 now_dtime = tv.tv_sec + tv.tv_usec/1000000.0; 00134 actualSec = now_dtime - start_dtime; 00135 time_mutex.release(); 00136 } 00137 return actualSec; 00138 } 00139 00140 00141 void GlobalTimer::dropFramesUntil(u32 cts) { 00142 dprintf_full("GlobalTimer::dropFramesUntil(cts = %u)\n", cts); 00143 dropUntil = cts; 00144 } 00145 00146 00147 /***************************************************************/ 00148 //called by AudioIO 00149 void GlobalTimer::adjustToTS(int ts, int mediaTimeScale) { 00150 double diff; 00151 00152 assert(mediaTimeScale != 0); 00153 time_mutex.lock(); 00154 gettimeofday(&tv,NULL); 00155 now_dtime = tv.tv_sec + tv.tv_usec/1000000.0; 00156 diff = (start_dtime + (double)ts / (double)mediaTimeScale) - now_dtime; 00157 start_dtime -= diff; 00158 dprintf_full("GlobalTimer::adjustToTS %i (scale %i) adjusts by %i msecs\n",ts,mediaTimeScale,(int)(diff*1000.0)); 00159 time_mutex.release(); 00160 } 00161 00162 00163 void GlobalTimer::adjust(double sec) { 00164 time_mutex.lock(); 00165 gettimeofday(&tv, NULL); 00166 now_dtime = tv.tv_sec + tv.tv_usec/1000000.0; 00167 start_dtime = now_dtime - sec; 00168 time_mutex.release(); 00169 } 00170 00171 00172 /***************************************************************/ 00173 list < Frame * > GlobalTimer::adapt(Frame * frm) { 00174 list < Frame * >tmp; 00175 assert(frm); 00176 if (dropUntil && frm->getAU()->cts < dropUntil) { 00177 dprintf_full("GlobalTimer::adapt() dropUntil = %u, DROPPING frame CTS %u\n", 00178 dropUntil, frm->getAU()->cts); 00179 return tmp; 00180 } 00181 cond_block_mutex.lock(); 00182 while (!COND_NOT_BLOCKED) { 00183 dprintf_full("GlobalTimer(%p)::adapt blocking on CTS %u (Pausers %d, Prefetchers %d)\n", 00184 this, ( (frm&&frm->getAU()) ? frm->getAU()->cts : (unsigned)-1 ), 00185 pauseRefCnt.getUsage(), prefetchRefCnt.getUsage()); 00186 cond_block.condWait(cond_block_mutex.getMutexObject()); 00187 } 00188 00189 if(frm) { 00190 tmp.push_front(frm); 00191 00192 time_mutex.lock(); 00193 gettimeofday(&tv,NULL); 00194 if(wasBlocked) { //adjust base time 00195 wasBlocked = false; 00196 double pause_dtime = now_dtime; //store old dtime 00197 now_dtime = tv.tv_sec + tv.tv_usec/1000000.0; 00198 start_dtime += (now_dtime - pause_dtime); 00199 actualSec = now_dtime - start_dtime; 00200 } 00201 00202 now_dtime = tv.tv_sec + tv.tv_usec/1000000.0; 00203 if (firstFrame) { 00204 firstFrame = false; 00205 start_dtime = now_dtime; 00206 } 00207 actualSec = now_dtime - start_dtime; 00208 dprintf_full("GlobalTimer::adapt forwarding frame CTS %u at time %2.3f\n", 00209 ( (frm&&frm->getAU()) ? frm->getAU()->cts : (unsigned)-1 ), 00210 actualSec); 00211 time_mutex.release(); 00212 } 00213 cond_block_mutex.release(); 00214 return tmp; 00215 } 00216