Skip to content

Commit

Permalink
Make new GCC compatible with old API
Browse files Browse the repository at this point in the history
  • Loading branch information
mengelbart committed Jan 27, 2025
1 parent 0f9b5cc commit 9c58291
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 6 deletions.
126 changes: 126 additions & 0 deletions pkg/bwe/deprecated_bwe_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package bwe

import (
"errors"
"sync"
"time"

"github.com/pion/interceptor"
"github.com/pion/interceptor/pkg/cc"
"github.com/pion/interceptor/pkg/ccfb"
"github.com/pion/rtcp"
)

// GCCFactory creates a new cc.BandwidthEstimator
func GCCFactory() (cc.BandwidthEstimator, error) {
return &GCC{
lock: sync.Mutex{},
sbwe: NewSendSideController(1_000_000, 100_000, 100_000_000),
rate: 1_000_000,
}, nil

Check warning on line 20 in pkg/bwe/deprecated_bwe_api.go

View check run for this annotation

Codecov / codecov/patch

pkg/bwe/deprecated_bwe_api.go#L15-L20

Added lines #L15 - L20 were not covered by tests
}

// GCC implements cc.BandwidthEstimator
type GCC struct {
lock sync.Mutex
sbwe *SendSideController
rate int
updateCB func(int)
}

// AddStream implements cc.BandwidthEstimator.
// Called by cc.Interceptor
func (g *GCC) AddStream(_ *interceptor.StreamInfo, writer interceptor.RTPWriter) interceptor.RTPWriter {
return writer

Check warning on line 34 in pkg/bwe/deprecated_bwe_api.go

View check run for this annotation

Codecov / codecov/patch

pkg/bwe/deprecated_bwe_api.go#L33-L34

Added lines #L33 - L34 were not covered by tests
}

// Close implements cc.BandwidthEstimator.
// Called by cc.Interceptor
func (g *GCC) Close() error {
// GCC does not need to be closed
return nil

Check warning on line 41 in pkg/bwe/deprecated_bwe_api.go

View check run for this annotation

Codecov / codecov/patch

pkg/bwe/deprecated_bwe_api.go#L39-L41

Added lines #L39 - L41 were not covered by tests
}

// GetStats implements cc.BandwidthEstimator.
// Called by application
func (g *GCC) GetStats() map[string]interface{} {
g.lock.Lock()
defer g.lock.Unlock()
return map[string]interface{}{
"warning": "GetStats is deprecated",
"lossTargetBitrate": 0,
"averageLoss": 0,
"delayTargetBitrate": 0,
"delayMeasurement": 0,
"delayEstimate": 0,
"delayThreshold": 0,
"usage": 0,
"state": 0,
}

Check warning on line 59 in pkg/bwe/deprecated_bwe_api.go

View check run for this annotation

Codecov / codecov/patch

pkg/bwe/deprecated_bwe_api.go#L46-L59

Added lines #L46 - L59 were not covered by tests
}

// GetTargetBitrate implements cc.BandwidthEstimator.
// Called by application
func (g *GCC) GetTargetBitrate() int {
g.lock.Lock()
defer g.lock.Unlock()
return g.rate

Check warning on line 67 in pkg/bwe/deprecated_bwe_api.go

View check run for this annotation

Codecov / codecov/patch

pkg/bwe/deprecated_bwe_api.go#L64-L67

Added lines #L64 - L67 were not covered by tests
}

// OnTargetBitrateChange implements cc.BandwidthEstimator.
// Called by application
func (g *GCC) OnTargetBitrateChange(f func(bitrate int)) {
g.lock.Lock()
defer g.lock.Unlock()
g.updateCB = f

Check warning on line 75 in pkg/bwe/deprecated_bwe_api.go

View check run for this annotation

Codecov / codecov/patch

pkg/bwe/deprecated_bwe_api.go#L72-L75

Added lines #L72 - L75 were not covered by tests
}

// WriteRTCP implements cc.BandwidthEstimator.
// Called by cc.Interceptor
func (g *GCC) WriteRTCP(_ []rtcp.Packet, attr interceptor.Attributes) error {
reports, ok := attr.Get(ccfb.CCFBAttributesKey).([]ccfb.Report)
if !ok {
return errors.New("warning: GCC requires CCFB interceptor to be configured before the CC interceptor")
}
now := time.Now()
for _, report := range reports {
acks, rtt := readReport(report)
g.update(now, rtt, acks)
}
return nil

Check warning on line 90 in pkg/bwe/deprecated_bwe_api.go

View check run for this annotation

Codecov / codecov/patch

pkg/bwe/deprecated_bwe_api.go#L80-L90

Added lines #L80 - L90 were not covered by tests
}

func (g *GCC) update(now time.Time, rtt time.Duration, acks []Acknowledgment) {
g.lock.Lock()
defer g.lock.Unlock()
oldRate := g.rate

g.rate = g.sbwe.OnAcks(now, rtt, acks)

if oldRate != g.rate && g.updateCB != nil {
g.updateCB(g.rate)
}

Check warning on line 102 in pkg/bwe/deprecated_bwe_api.go

View check run for this annotation

Codecov / codecov/patch

pkg/bwe/deprecated_bwe_api.go#L93-L102

Added lines #L93 - L102 were not covered by tests
}

func readReport(report ccfb.Report) ([]Acknowledgment, time.Duration) {
acks := []Acknowledgment{}
latestAcked := Acknowledgment{}
for _, prs := range report.SSRCToPacketReports {
for _, pr := range prs {
ack := Acknowledgment{
SeqNr: pr.SeqNr,
Size: pr.Size,
Departure: pr.Departure,
Arrived: pr.Arrived,
Arrival: pr.Arrival,
ECN: ECN(pr.ECN),
}
if ack.Arrival.After(latestAcked.Arrival) {
latestAcked = ack
}
acks = append(acks, ack)

Check warning on line 121 in pkg/bwe/deprecated_bwe_api.go

View check run for this annotation

Codecov / codecov/patch

pkg/bwe/deprecated_bwe_api.go#L105-L121

Added lines #L105 - L121 were not covered by tests
}
}
rtt := MeasureRTT(report.Departure, report.Arrival, latestAcked.Departure, latestAcked.Arrival)
return acks, rtt

Check warning on line 125 in pkg/bwe/deprecated_bwe_api.go

View check run for this annotation

Codecov / codecov/patch

pkg/bwe/deprecated_bwe_api.go#L124-L125

Added lines #L124 - L125 were not covered by tests
}
20 changes: 14 additions & 6 deletions pkg/cc/interceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package cc

import (
"github.com/pion/interceptor"
"github.com/pion/interceptor/pkg/ccfb"
"github.com/pion/interceptor/pkg/gcc"
"github.com/pion/rtcp"
)
Expand Down Expand Up @@ -38,6 +39,7 @@ type InterceptorFactory struct {
opts []Option
bweFactory func() (BandwidthEstimator, error)
addPeerConnection NewPeerConnectionCallback
ccfbFactory *ccfb.InterceptorFactory
}

// NewInterceptor returns a new CC interceptor factory
Expand All @@ -47,10 +49,15 @@ func NewInterceptor(factory BandwidthEstimatorFactory, opts ...Option) (*Interce
return gcc.NewSendSideBWE()
}
}
ccfbFactory, err := ccfb.NewInterceptor()
if err != nil {
return nil, err
}

Check warning on line 55 in pkg/cc/interceptor.go

View check run for this annotation

Codecov / codecov/patch

pkg/cc/interceptor.go#L52-L55

Added lines #L52 - L55 were not covered by tests
return &InterceptorFactory{
opts: opts,
bweFactory: factory,
addPeerConnection: nil,
ccfbFactory: ccfbFactory,

Check warning on line 60 in pkg/cc/interceptor.go

View check run for this annotation

Codecov / codecov/patch

pkg/cc/interceptor.go#L60

Added line #L60 was not covered by tests
}, nil
}

Expand All @@ -69,28 +76,29 @@ func (f *InterceptorFactory) NewInterceptor(id string) (interceptor.Interceptor,
i := &Interceptor{
NoOp: interceptor.NoOp{},
estimator: bwe,
feedback: make(chan []rtcp.Packet),
close: make(chan struct{}),
}

for _, opt := range f.opts {
if err := opt(i); err != nil {
if err = opt(i); err != nil {

Check warning on line 82 in pkg/cc/interceptor.go

View check run for this annotation

Codecov / codecov/patch

pkg/cc/interceptor.go#L82

Added line #L82 was not covered by tests
return nil, err
}
}

if f.addPeerConnection != nil {
f.addPeerConnection(id, i.estimator)
}
return i, nil

ccfb, err := f.ccfbFactory.NewInterceptor(id)
if err != nil {
return nil, err
}
return interceptor.NewChain([]interceptor.Interceptor{ccfb, i}), nil

Check warning on line 95 in pkg/cc/interceptor.go

View check run for this annotation

Codecov / codecov/patch

pkg/cc/interceptor.go#L91-L95

Added lines #L91 - L95 were not covered by tests
}

// Interceptor implements Google Congestion Control
type Interceptor struct {
interceptor.NoOp
estimator BandwidthEstimator
feedback chan []rtcp.Packet
close chan struct{}
}

// BindRTCPReader lets you modify any incoming RTCP packets. It is called once
Expand Down

0 comments on commit 9c58291

Please sign in to comment.