WvStreams
wvrateadjust.cc
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"
11
12WvRateAdjust::WvRateAdjust(int _sampsize, int _irate_base, int _orate)
13#if 0
14 : log("RateAdj", WvLog::Debug5)
15#endif
16{
17 orate_n = _orate;
18 orate_d = 1;
19 match_rate = NULL;
20
21 init(_sampsize, _irate_base);
22}
23
24
25WvRateAdjust::WvRateAdjust(int _sampsize, int _irate_base,
26 WvRateAdjust *_match_rate)
27#if 0
28 : log("RateAdj", WvLog::Debug5)
29#endif
30{
31 match_rate = _match_rate;
32 assert(match_rate);
33
34 orate_n = match_rate->irate_n;
35 orate_d = match_rate->irate_d;
36
37 init(_sampsize, _irate_base);
38}
39
40
41void WvRateAdjust::init(int _sampsize, int _irate_base)
42{
43 sampsize = _sampsize;
44 irate_n = _irate_base * 10;
45 irate_d = 10;
46 epoch = wvtime();
47 epoch.tv_sec--;
48 bucket = 0;
49}
50
51
52// we always use all input samples and produce an appropriate number of
53// output samples.
54bool WvRateAdjust::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)
55{
56 if (!inbuf.used()) return true;
57 assert((inbuf.used() % sampsize) == 0); // can't deal with partial samples
58
59 WvTime now = wvtime();
60 unsigned isamps = inbuf.used() / sampsize;
61
62 // match our output rate to another stream's input rate, if requested
63 if (match_rate)
64 {
65 orate_n = match_rate->irate_n;
66 orate_d = match_rate->irate_d;
67 }
68
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;
76
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
82
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
90 {
91 epoch.tv_sec++; // time now starts one second later
92 irate_n = irate_n * (irate_d - 10)/irate_d;
93 irate_d -= 10;
94
95#if 0
96 log(" JUMP! new irate=%s (%s/%s)\n", getirate(), irate_n, irate_d);
97#endif
98 }
99
100 int plus = orate_n * irate_d, minus = irate_n * orate_d;
101 //log("plus=%s, minus=%s, ", plus, minus);
102
103 unsigned omax = isamps + isamps/2;
104 //log("isamps=%s, omax=%s\n", isamps, omax);
105
106 const unsigned char *iptr = inbuf.get(isamps * sampsize);
107 unsigned char *ostart, *optr;
108
109 ostart = optr = outbuf.alloc(omax * sampsize);
110
111 // copy the buffers using the "Bresenham line-drawing" algorithm.
112 for (unsigned s = 0; s < isamps; s++, iptr += sampsize)
113 {
114 bucket += plus;
115 //log("s=%s, bucket=%s (+%s, -%s)\n", s, bucket, plus, minus);
116
117 while (bucket >= minus)
118 {
119 // allocate more buffer space if needed
120 if ((unsigned)(optr - ostart) >= omax * sampsize)
121 ostart = optr = outbuf.alloc(omax * sampsize);
122
123 for (int i = 0; i < sampsize; i++)
124 optr[i] = iptr[i];
125 optr += sampsize;
126 bucket -= minus;
127 }
128 }
129
130 unsigned un = omax*sampsize - (optr - ostart);
131 //log("unalloc %s/%s (%s)\n", un, omax*sampsize, optr-ostart);
132 outbuf.unalloc(un);
133
134 return true;
135}
136
137
const T * get(size_t count)
Reads exactly the specified number of elements and returns a pointer to a storage location owned by t...
Definition: wvbufbase.h:114
void unalloc(size_t count)
Unallocates exactly the specified number of elements by removing them from the buffer and releasing t...
Definition: wvbufbase.h:421
T * alloc(size_t count)
Allocates exactly the specified number of elements and returns a pointer to an UNINITIALIZED storage ...
Definition: wvbufbase.h:379
size_t used() const
Returns the number of elements in the buffer currently available for reading.
Definition: wvbufbase.h:92
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers.
Definition: wvbuf.h:24
virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)
Template method implementation of encode().
Definition: wvrateadjust.cc:54
Based on (and interchangeable with) struct timeval.
Definition: wvtimeutils.h:18