@@ -43,6 +43,7 @@ type SendSideBWE struct {
4343 feedbackAdapter * cc.FeedbackAdapter
4444
4545 onTargetBitrateChange func (bitrate int )
46+ onLossRateChange func (loss float64 )
4647
4748 lock sync.Mutex
4849 latestStats Stats
@@ -164,6 +165,14 @@ func (e *SendSideBWE) GetTargetBitrate() int {
164165 return e .latestBitrate
165166}
166167
168+ // GetLossRate returns the current packet loss rate in the range [0, 1].
169+ func (e * SendSideBWE ) GetLossRate () float64 {
170+ e .lossController .lock .Lock ()
171+ defer e .lossController .lock .Unlock ()
172+
173+ return e .lossController .averageLoss
174+ }
175+
167176// GetStats returns some internal statistics of the bandwidth estimator
168177func (e * SendSideBWE ) GetStats () map [string ]interface {} {
169178 e .lock .Lock ()
@@ -188,6 +197,12 @@ func (e *SendSideBWE) OnTargetBitrateChange(f func(bitrate int)) {
188197 e .onTargetBitrateChange = f
189198}
190199
200+ // OnLossRateChange sets the callback that is called when the packet loss
201+ // rate changes
202+ func (e * SendSideBWE ) OnLossRateChange (f func (loss float64 )) {
203+ e .onLossRateChange = f
204+ }
205+
191206// isClosed returns true if SendSideBWE is closed
192207func (e * SendSideBWE ) isClosed () bool {
193208 select {
@@ -227,6 +242,11 @@ func (e *SendSideBWE) onDelayUpdate(delayStats DelayStats) {
227242 go e .onTargetBitrateChange (bitrate )
228243 }
229244
245+ // in principle this could update more frequently but this is a convenient place to put this hook.
246+ if e .latestStats .LossStats .AverageLoss != lossStats .AverageLoss && e .onLossRateChange != nil {
247+ go e .onLossRateChange (lossStats .AverageLoss )
248+ }
249+
230250 e .latestStats = Stats {
231251 LossStats : lossStats ,
232252 DelayStats : delayStats ,
0 commit comments