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 
12 WvRateAdjust::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 
25 WvRateAdjust::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 
41 void 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.
54 bool 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 
WvBufBaseCommonImpl::get
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
WvBufBaseCommonImpl::alloc
T * alloc(size_t count)
Allocates exactly the specified number of elements and returns a pointer to an UNINITIALIZED storage ...
Definition: wvbufbase.h:379
WvBufBaseCommonImpl::unalloc
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
WvTime
Based on (and interchangeable with) struct timeval.
Definition: wvtimeutils.h:17
WvRateAdjust::_encode
virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)
Template method implementation of encode().
Definition: wvrateadjust.cc:54
WvBufBase< unsigned char >
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers.
Definition: wvbuf.h:22
WvRateAdjust
Definition: wvrateadjust.h:26
WvBufBaseCommonImpl::used
size_t used() const
Returns the number of elements in the buffer currently available for reading.
Definition: wvbufbase.h:92