1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
package gcc
import (
"time"
"github.com/pion/interceptor/internal/cc"
)
type rateCalculator struct {
window time.Duration
}
func newRateCalculator(window time.Duration) *rateCalculator {
return &rateCalculator{
window: window,
}
}
func (c *rateCalculator) run(in <-chan []cc.Acknowledgment, onRateUpdate func(int)) {
var history []cc.Acknowledgment
init := false
sum := 0
for acks := range in {
for _, next := range acks {
if next.Arrival.IsZero() {
// Ignore packet if it didn't arrive
continue
}
history = append(history, next)
sum += next.Size
if !init {
init = true
// Don't know any timeframe here, only arrival of last packet,
// which is by definition in the window that ends with the last
// arrival time
onRateUpdate(next.Size * 8)
continue
}
del := 0
for _, ack := range history {
deadline := next.Arrival.Add(-c.window)
if !ack.Arrival.Before(deadline) {
break
}
del++
sum -= ack.Size
}
history = history[del:]
if len(history) == 0 {
onRateUpdate(0)
continue
}
dt := next.Arrival.Sub(history[0].Arrival)
bits := 8 * sum
rate := int(float64(bits) / dt.Seconds())
onRateUpdate(rate)
}
}
}
|