Make WvStreams compile with gcc 4.4.
[wvstreams.git] / utils / wvrateadjust.cc
blob279a0cb4d199d3836f0e95e80b5f42f76681cda3
1 /*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4 *
5 * WvRateAdjust is a WvEncoder that makes sure data comes out of it at a
6 * given average rate.
7 *
8 * See wvrateadjust.h.
9 */
10 #include "wvrateadjust.h"
12 WvRateAdjust::WvRateAdjust(int _sampsize, int _irate_base, int _orate)
13 #if 0
14 : log("RateAdj", WvLog::Debug5)
15 #endif
17 orate_n = _orate;
18 orate_d = 1;
19 match_rate = NULL;
21 init(_sampsize, _irate_base);
25 WvRateAdjust::WvRateAdjust(int _sampsize, int _irate_base,
26 WvRateAdjust *_match_rate)
27 #if 0
28 : log("RateAdj", WvLog::Debug5)
29 #endif
31 match_rate = _match_rate;
32 assert(match_rate);
34 orate_n = match_rate->irate_n;
35 orate_d = match_rate->irate_d;
37 init(_sampsize, _irate_base);
41 void WvRateAdjust::init(int _sampsize, int _irate_base)
43 sampsize = _sampsize;
44 irate_n = _irate_base * 10;
45 irate_d = 10;
46 epoch = wvtime();
47 epoch.tv_sec--;
48 bucket = 0;
52 // we always use all input samples and produce an appropriate number of
53 // output samples.
54 bool WvRateAdjust::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)
56 if (!inbuf.used()) return true;
57 assert((inbuf.used() % sampsize) == 0); // can't deal with partial samples
59 WvTime now = wvtime();
60 unsigned isamps = inbuf.used() / sampsize;
62 // match our output rate to another stream's input rate, if requested
63 if (match_rate)
65 orate_n = match_rate->irate_n;
66 orate_d = match_rate->irate_d;
69 // adjust the input rate estimate
70 if (!epoch.tv_sec)
71 epoch = now;
72 irate_n += isamps * 10;
73 irate_d = msecdiff(wvtime(), epoch) / 100;
74 if (!irate_d)
75 irate_d = 1;
77 #if 0
78 log("irate=%s (%s/%s), orate=%s (%s/%s), bucket=%s\n",
79 getirate(), irate_n, irate_d, getorate(), orate_n, orate_d,
80 bucket);
81 #endif
83 // reduce the rate estimate if it's getting out of control FIXME:
84 // this method is (almost) unbearably cheesy because it's very
85 // "blocky" - it doesn't happen every time, so it'll cause sudden
86 // jumps from one value to the next. Hopefully not a big deal,
87 // since the input rate is supposed to be constant anyway. The
88 // hardcoded constants are also rather weird.
89 if (irate_d > 100) // ten seconds
91 epoch.tv_sec++; // time now starts one second later
92 irate_n = irate_n * (irate_d - 10)/irate_d;
93 irate_d -= 10;
95 #if 0
96 log(" JUMP! new irate=%s (%s/%s)\n", getirate(), irate_n, irate_d);
97 #endif
100 int plus = orate_n * irate_d, minus = irate_n * orate_d;
101 //log("plus=%s, minus=%s, ", plus, minus);
103 unsigned omax = isamps + isamps/2;
104 //log("isamps=%s, omax=%s\n", isamps, omax);
106 const unsigned char *iptr = inbuf.get(isamps * sampsize);
107 unsigned char *ostart, *optr;
109 ostart = optr = outbuf.alloc(omax * sampsize);
111 // copy the buffers using the "Bresenham line-drawing" algorithm.
112 for (unsigned s = 0; s < isamps; s++, iptr += sampsize)
114 bucket += plus;
115 //log("s=%s, bucket=%s (+%s, -%s)\n", s, bucket, plus, minus);
117 while (bucket >= minus)
119 // allocate more buffer space if needed
120 if ((unsigned)(optr - ostart) >= omax * sampsize)
121 ostart = optr = outbuf.alloc(omax * sampsize);
123 for (int i = 0; i < sampsize; i++)
124 optr[i] = iptr[i];
125 optr += sampsize;
126 bucket -= minus;
130 unsigned un = omax*sampsize - (optr - ostart);
131 //log("unalloc %s/%s (%s)\n", un, omax*sampsize, optr-ostart);
132 outbuf.unalloc(un);
134 return true;