Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvsyncstream.cc

Go to the documentation of this file.
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 2002 Net Integration Technologies, Inc. 00004 * 00005 * WvSyncStream throttles its input to the specified bitrate. 00006 * It only becomes readable at periodic intervals. 00007 */ 00008 #include "wvsyncstream.h" 00009 #include "wvtimeutils.h" 00010 00011 WvSyncStream::WvSyncStream(WvStream *_cloned, size_t _bps, 00012 size_t _avgchunk, size_t _maxchunk) : 00013 WvStreamClone(_cloned) 00014 { 00015 init(_bps, _avgchunk, _maxchunk); 00016 } 00017 00018 00019 WvSyncStream::WvSyncStream(WvStream *_cloned, bool _owner, int _srate, 00020 int _bits, int _msec) : WvStreamClone(_cloned) 00021 { 00022 size_t _bps = _srate * _bits / 8; 00023 size_t _avgchunk = _bps * _msec / 1000; 00024 init(_bps, _avgchunk, _avgchunk * 5); // arbitrary choice 00025 disassociate_on_close = ! _owner; 00026 } 00027 00028 00029 WvSyncStream::~WvSyncStream() 00030 { 00031 close(); 00032 } 00033 00034 00035 void WvSyncStream::init(size_t _bps, size_t _avgchunk, size_t _maxchunk) 00036 { 00037 bps = _bps; 00038 avgchunk = _avgchunk; 00039 maxchunk = _maxchunk; 00040 // allow +/- 50% tolerance 00041 // FIXME: this is a purely arbitrary number 00042 int tol = avgchunk / 2; 00043 lowater = avgchunk - tol; 00044 hiwater = avgchunk + tol; 00045 waiting = false; 00046 resettimer(); 00047 00048 force_select(true, false, false); 00049 } 00050 00051 00052 size_t WvSyncStream::uread(void *buf, size_t count) 00053 { 00054 poll(); 00055 if (count > availchunk) 00056 count = availchunk; 00057 if (availchunk == 0) 00058 return 0; // try again later 00059 00060 size_t len = WvStreamClone::uread(buf, count); 00061 availchunk -= len; 00062 usedchunk += len; 00063 return len; 00064 } 00065 00066 00067 bool WvSyncStream::pre_select(SelectInfo &si) 00068 { 00069 if (waiting) 00070 { 00071 poll(); 00072 if (availchunk < lowater) 00073 { 00074 time_t timeout = (hiwater - availchunk) * 1000 / bps + 1; 00075 if (timeout > 0) 00076 { 00077 if (timeout < si.msec_timeout || si.msec_timeout < 0) 00078 si.msec_timeout = timeout; 00079 return false; 00080 } 00081 } 00082 waiting = false; 00083 return true; // we know we had data 00084 } 00085 return WvStreamClone::pre_select(si); 00086 } 00087 00088 00089 bool WvSyncStream::post_select(SelectInfo &si) 00090 { 00091 bool havedata = WvStreamClone::post_select(si); 00092 if (havedata && si.wants.readable) 00093 { 00094 poll(); 00095 if (availchunk < lowater) 00096 { 00097 // not enough data to care about right now 00098 waiting = true; 00099 return false; 00100 } 00101 } 00102 return havedata; 00103 } 00104 00105 00106 void WvSyncStream::poll() 00107 { 00108 // we advance the reference time periodically size to avoid 00109 // overflows during some integer calculations 00110 const int WINDOW = 10; 00111 00112 // how long has it been since we started 00113 struct timeval now; 00114 gettimeofday(& now, NULL); 00115 time_t msec = msecdiff(now, reference); 00116 if (msec > WINDOW * 1000 * 2) 00117 { 00118 // avoid overflow by adjusting reference time 00119 reference.tv_sec += WINDOW; 00120 msec -= WINDOW * 1000; 00121 size_t consume = WINDOW * bps; 00122 if (usedchunk >= consume) 00123 usedchunk -= consume; 00124 else 00125 usedchunk = 0; // got very far behind reading? 00126 } 00127 else if (msec < 0) 00128 { 00129 // reference clock is confused! 00130 resettimer(); 00131 return; 00132 } 00133 00134 // how much can we read? 00135 size_t totalchunk = bps * msec / 1000; 00136 availchunk = totalchunk - usedchunk; 00137 if (availchunk > maxchunk) 00138 { 00139 // resynchronize after a long delay 00140 availchunk = maxchunk; 00141 usedchunk = totalchunk - availchunk; 00142 } 00143 } 00144 00145 00146 void WvSyncStream::resettimer() 00147 { 00148 // make full chunk available immediately 00149 gettimeofday(& reference, NULL); 00150 reference.tv_sec -= 1; 00151 availchunk = hiwater; 00152 usedchunk = bps - availchunk; 00153 }

Generated on Tue Oct 5 01:09:21 2004 for WvStreams by doxygen 1.3.7