Toggle estimator config (#32)

* add estimator to conifg.

* ensure video auto is false when estimator is disabled.
This commit is contained in:
Miroslav Šedivý 2023-02-26 21:54:10 +01:00 committed by GitHub
parent 64abfd0b1a
commit a4a3ff79ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 38 deletions

View File

@ -26,6 +26,9 @@ type WebRTC struct {
NAT1To1IPs []string NAT1To1IPs []string
IpRetrievalUrl string IpRetrievalUrl string
EstimatorEnabled bool
EstimatorInitialBitrate int
} }
func (WebRTC) Init(cmd *cobra.Command) error { func (WebRTC) Init(cmd *cobra.Command) error {
@ -69,6 +72,18 @@ func (WebRTC) Init(cmd *cobra.Command) error {
return err return err
} }
// bandwidth estimator
cmd.PersistentFlags().Bool("webrtc.estimator.enabled", false, "enables the bandwidth estimator")
if err := viper.BindPFlag("webrtc.estimator.enabled", cmd.PersistentFlags().Lookup("webrtc.estimator.enabled")); err != nil {
return err
}
cmd.PersistentFlags().Int("webrtc.estimator.initial_bitrate", 1_000_000, "initial bitrate for the bandwidth estimator")
if err := viper.BindPFlag("webrtc.estimator.initial_bitrate", cmd.PersistentFlags().Lookup("webrtc.estimator.initial_bitrate")); err != nil {
return err
}
return nil return nil
} }
@ -135,4 +150,9 @@ func (s *WebRTC) Set() {
log.Warn().Err(err).Msgf("IP retrieval failed") log.Warn().Err(err).Msgf("IP retrieval failed")
} }
} }
// bandwidth estimator
s.EstimatorEnabled = viper.GetBool("webrtc.estimator.enabled")
s.EstimatorInitialBitrate = viper.GetInt("webrtc.estimator.initial_bitrate")
} }

View File

@ -211,28 +211,34 @@ func (manager *WebRTCManagerCtx) newPeerConnection(bitrate int, codecs []codec.R
// create interceptor registry // create interceptor registry
registry := &interceptor.Registry{} registry := &interceptor.Registry{}
congestionController, err := cc.NewInterceptor(func() (cc.BandwidthEstimator, error) { // create bandwidth estimator
if bitrate == 0 { estimatorChan := make(chan cc.BandwidthEstimator, 1)
bitrate = 1_000_000 if manager.config.EstimatorEnabled {
congestionController, err := cc.NewInterceptor(func() (cc.BandwidthEstimator, error) {
if bitrate == 0 {
bitrate = manager.config.EstimatorInitialBitrate
}
return gcc.NewSendSideBWE(
gcc.SendSideBWEInitialBitrate(bitrate),
gcc.SendSideBWEPacer(gcc.NewNoOpPacer()),
)
})
if err != nil {
return nil, nil, err
} }
return gcc.NewSendSideBWE( congestionController.OnNewPeerConnection(func(id string, estimator cc.BandwidthEstimator) {
gcc.SendSideBWEInitialBitrate(bitrate), estimatorChan <- estimator
gcc.SendSideBWEPacer(gcc.NewNoOpPacer()), })
)
})
if err != nil {
return nil, nil, err
}
estimatorChan := make(chan cc.BandwidthEstimator, 1) registry.Add(congestionController)
congestionController.OnNewPeerConnection(func(id string, estimator cc.BandwidthEstimator) { if err = webrtc.ConfigureTWCCHeaderExtensionSender(engine, registry); err != nil {
estimatorChan <- estimator return nil, nil, err
}) }
} else {
registry.Add(congestionController) // no estimator, send nil
if err = webrtc.ConfigureTWCCHeaderExtensionSender(engine, registry); err != nil { estimatorChan <- nil
return nil, nil, err
} }
if err := webrtc.RegisterDefaultInterceptors(engine, registry); err != nil { if err := webrtc.RegisterDefaultInterceptors(engine, registry); err != nil {
@ -276,7 +282,8 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, bitrate int,
return nil, err return nil, err
} }
if bitrate == 0 { // if bitrate is 0, and estimator is enabled, use estimator bitrate
if bitrate == 0 && estimator != nil {
bitrate = estimator.GetTargetBitrate() bitrate = estimator.GetTargetBitrate()
} }
@ -309,6 +316,11 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, bitrate int,
return nil, err return nil, err
} }
// if estimator is disabled, disable video auto
if !manager.config.EstimatorEnabled {
videoAuto = false
}
// video track // video track
videoTrack, err := NewTrack(logger, videoCodec, connection, WithVideoAuto(videoAuto)) videoTrack, err := NewTrack(logger, videoCodec, connection, WithVideoAuto(videoAuto))
if err != nil { if err != nil {
@ -321,7 +333,7 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, bitrate int,
changeVideoFromBitrate := func(peerBitrate int) { changeVideoFromBitrate := func(peerBitrate int) {
// when switching from manual to auto bitrate estimation, in case the estimator is // when switching from manual to auto bitrate estimation, in case the estimator is
// idle (lastBitrate > maxBitrate), we want to go back to the previous estimated bitrate // idle (lastBitrate > maxBitrate), we want to go back to the previous estimated bitrate
if peerBitrate == 0 { if peerBitrate == 0 && estimator != nil {
peerBitrate = estimator.GetTargetBitrate() peerBitrate = estimator.GetTargetBitrate()
manager.logger.Debug(). manager.logger.Debug().
Int("peer_bitrate", peerBitrate). Int("peer_bitrate", peerBitrate).
@ -397,24 +409,27 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, bitrate int,
// set initial video bitrate // set initial video bitrate
changeVideoFromBitrate(bitrate) changeVideoFromBitrate(bitrate)
// use a ticker to get current client target bitrate // if estimator is enabled, use it to change video stream
go func() { if estimator != nil {
ticker := time.NewTicker(bitrateCheckInterval) go func() {
defer ticker.Stop() // use a ticker to get current client target bitrate
ticker := time.NewTicker(bitrateCheckInterval)
defer ticker.Stop()
for range ticker.C { for range ticker.C {
targetBitrate := estimator.GetTargetBitrate() targetBitrate := estimator.GetTargetBitrate()
manager.metrics.SetReceiverEstimatedMaximumBitrate(session, float64(targetBitrate)) manager.metrics.SetReceiverEstimatedMaximumBitrate(session, float64(targetBitrate))
if connection.ConnectionState() == webrtc.PeerConnectionStateClosed { if connection.ConnectionState() == webrtc.PeerConnectionStateClosed {
break break
}
if !videoTrack.VideoAuto() {
continue
}
changeVideoFromBitrate(targetBitrate)
} }
if !videoTrack.VideoAuto() { }()
continue }
}
changeVideoFromBitrate(targetBitrate)
}
}()
// data channel // data channel
@ -435,8 +450,15 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, bitrate int,
videoTrack.SetPaused(isPaused) videoTrack.SetPaused(isPaused)
audioTrack.SetPaused(isPaused) audioTrack.SetPaused(isPaused)
}, },
iceTrickle: manager.config.ICETrickle, iceTrickle: manager.config.ICETrickle,
setVideoAuto: videoTrack.SetVideoAuto, setVideoAuto: func(videoAuto bool) {
if manager.config.EstimatorEnabled {
videoTrack.SetVideoAuto(videoAuto)
} else {
logger.Warn().Msg("estimator is disabled, cannot change video auto")
videoTrack.SetVideoAuto(false) // ensure video auto is disabled
}
},
getVideoAuto: videoTrack.VideoAuto, getVideoAuto: videoTrack.VideoAuto,
} }

View File

@ -40,6 +40,7 @@ func (h *MessageHandlerCtx) signalRequest(session types.Session, payload *messag
} }
payload.Video = webrtcPeer.GetVideoID() payload.Video = webrtcPeer.GetVideoID()
payload.VideoAuto = webrtcPeer.VideoAuto()
} }
session.Send( session.Send(