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
IpRetrievalUrl string
EstimatorEnabled bool
EstimatorInitialBitrate int
}
func (WebRTC) Init(cmd *cobra.Command) error {
@ -69,6 +72,18 @@ func (WebRTC) Init(cmd *cobra.Command) error {
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
}
@ -135,4 +150,9 @@ func (s *WebRTC) Set() {
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
registry := &interceptor.Registry{}
congestionController, err := cc.NewInterceptor(func() (cc.BandwidthEstimator, error) {
if bitrate == 0 {
bitrate = 1_000_000
// create bandwidth estimator
estimatorChan := make(chan cc.BandwidthEstimator, 1)
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(
gcc.SendSideBWEInitialBitrate(bitrate),
gcc.SendSideBWEPacer(gcc.NewNoOpPacer()),
)
})
if err != nil {
return nil, nil, err
}
congestionController.OnNewPeerConnection(func(id string, estimator cc.BandwidthEstimator) {
estimatorChan <- estimator
})
estimatorChan := make(chan cc.BandwidthEstimator, 1)
congestionController.OnNewPeerConnection(func(id string, estimator cc.BandwidthEstimator) {
estimatorChan <- estimator
})
registry.Add(congestionController)
if err = webrtc.ConfigureTWCCHeaderExtensionSender(engine, registry); err != nil {
return nil, nil, err
registry.Add(congestionController)
if err = webrtc.ConfigureTWCCHeaderExtensionSender(engine, registry); err != nil {
return nil, nil, err
}
} else {
// no estimator, send nil
estimatorChan <- 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
}
if bitrate == 0 {
// if bitrate is 0, and estimator is enabled, use estimator bitrate
if bitrate == 0 && estimator != nil {
bitrate = estimator.GetTargetBitrate()
}
@ -309,6 +316,11 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, bitrate int,
return nil, err
}
// if estimator is disabled, disable video auto
if !manager.config.EstimatorEnabled {
videoAuto = false
}
// video track
videoTrack, err := NewTrack(logger, videoCodec, connection, WithVideoAuto(videoAuto))
if err != nil {
@ -321,7 +333,7 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, bitrate int,
changeVideoFromBitrate := func(peerBitrate int) {
// 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
if peerBitrate == 0 {
if peerBitrate == 0 && estimator != nil {
peerBitrate = estimator.GetTargetBitrate()
manager.logger.Debug().
Int("peer_bitrate", peerBitrate).
@ -397,24 +409,27 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, bitrate int,
// set initial video bitrate
changeVideoFromBitrate(bitrate)
// use a ticker to get current client target bitrate
go func() {
ticker := time.NewTicker(bitrateCheckInterval)
defer ticker.Stop()
// if estimator is enabled, use it to change video stream
if estimator != nil {
go func() {
// use a ticker to get current client target bitrate
ticker := time.NewTicker(bitrateCheckInterval)
defer ticker.Stop()
for range ticker.C {
targetBitrate := estimator.GetTargetBitrate()
manager.metrics.SetReceiverEstimatedMaximumBitrate(session, float64(targetBitrate))
for range ticker.C {
targetBitrate := estimator.GetTargetBitrate()
manager.metrics.SetReceiverEstimatedMaximumBitrate(session, float64(targetBitrate))
if connection.ConnectionState() == webrtc.PeerConnectionStateClosed {
break
if connection.ConnectionState() == webrtc.PeerConnectionStateClosed {
break
}
if !videoTrack.VideoAuto() {
continue
}
changeVideoFromBitrate(targetBitrate)
}
if !videoTrack.VideoAuto() {
continue
}
changeVideoFromBitrate(targetBitrate)
}
}()
}()
}
// data channel
@ -435,8 +450,15 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, bitrate int,
videoTrack.SetPaused(isPaused)
audioTrack.SetPaused(isPaused)
},
iceTrickle: manager.config.ICETrickle,
setVideoAuto: videoTrack.SetVideoAuto,
iceTrickle: manager.config.ICETrickle,
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,
}

View File

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