2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * WvRateAdjust is a WvEncoder that makes sure data comes out of it at a
10 #include "wvrateadjust.h"
12 WvRateAdjust::WvRateAdjust(int _sampsize
, int _irate_base
, int _orate
)
14 : log("RateAdj", WvLog::Debug5
)
21 init(_sampsize
, _irate_base
);
25 WvRateAdjust::WvRateAdjust(int _sampsize
, int _irate_base
,
26 WvRateAdjust
*_match_rate
)
28 : log("RateAdj", WvLog::Debug5
)
31 match_rate
= _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
)
44 irate_n
= _irate_base
* 10;
52 // we always use all input samples and produce an appropriate number of
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
65 orate_n
= match_rate
->irate_n
;
66 orate_d
= match_rate
->irate_d
;
69 // adjust the input rate estimate
72 irate_n
+= isamps
* 10;
73 irate_d
= msecdiff(wvtime(), epoch
) / 100;
78 log("irate=%s (%s/%s), orate=%s (%s/%s), bucket=%s\n",
79 getirate(), irate_n
, irate_d
, getorate(), orate_n
, orate_d
,
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
;
96 log(" JUMP! new irate=%s (%s/%s)\n", getirate(), irate_n
, irate_d
);
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
)
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
++)
130 unsigned un
= omax
*sampsize
- (optr
- ostart
);
131 //log("unalloc %s/%s (%s)\n", un, omax*sampsize, optr-ostart);