mirror of
https://github.com/livekit/livekit.git
synced 2026-03-29 09:19:53 +00:00
config for streamtracker (#1255)
This commit is contained in:
@@ -140,8 +140,23 @@ type AudioConfig struct {
|
||||
SmoothIntervals uint32 `yaml:"smooth_intervals"`
|
||||
}
|
||||
|
||||
type StreamTrackerConfig struct {
|
||||
SamplesRequired uint32 `yaml:"samples_required"`
|
||||
CyclesRequired uint32 `yaml:"cycles_required"`
|
||||
CycleDuration time.Duration `yaml:"cycle_duration"`
|
||||
BitrateReportInterval time.Duration `yaml:"bitrate_report_interval"`
|
||||
}
|
||||
|
||||
type StreamTrackersConfig struct {
|
||||
Video []StreamTrackerConfig `yaml:"video"`
|
||||
Screenshare []StreamTrackerConfig `yaml:"screenshare"`
|
||||
ExemptedLayersVideo []int32 `yaml:"exempted_layers_video"`
|
||||
ExemptedLayersScreenshare []int32 `yaml:"exempted_layers_screenshare"`
|
||||
}
|
||||
|
||||
type VideoConfig struct {
|
||||
DynacastPauseDelay time.Duration `yaml:"dynacast_pause_delay,omitempty"`
|
||||
DynacastPauseDelay time.Duration `yaml:"dynacast_pause_delay,omitempty"`
|
||||
StreamTracker StreamTrackersConfig `yaml:"stream_tracker,omitempty"`
|
||||
}
|
||||
|
||||
type RoomConfig struct {
|
||||
@@ -254,6 +269,50 @@ func NewConfig(confString string, strictMode bool, c *cli.Context, baseFlags []c
|
||||
},
|
||||
Video: VideoConfig{
|
||||
DynacastPauseDelay: 5 * time.Second,
|
||||
StreamTracker: StreamTrackersConfig{
|
||||
ExemptedLayersScreenshare: []int32{0},
|
||||
ExemptedLayersVideo: []int32{},
|
||||
Screenshare: []StreamTrackerConfig{
|
||||
{
|
||||
SamplesRequired: 1,
|
||||
CyclesRequired: 1,
|
||||
CycleDuration: 2 * time.Second,
|
||||
BitrateReportInterval: 4 * time.Second,
|
||||
},
|
||||
{
|
||||
SamplesRequired: 1,
|
||||
CyclesRequired: 1,
|
||||
CycleDuration: 2 * time.Second,
|
||||
BitrateReportInterval: 4 * time.Second,
|
||||
},
|
||||
{
|
||||
SamplesRequired: 1,
|
||||
CyclesRequired: 1,
|
||||
CycleDuration: 2 * time.Second,
|
||||
BitrateReportInterval: 4 * time.Second,
|
||||
},
|
||||
},
|
||||
Video: []StreamTrackerConfig{
|
||||
{
|
||||
SamplesRequired: 1,
|
||||
CyclesRequired: 4,
|
||||
CycleDuration: 500 * time.Millisecond,
|
||||
BitrateReportInterval: 1 * time.Second,
|
||||
},
|
||||
{
|
||||
SamplesRequired: 5,
|
||||
CyclesRequired: 20,
|
||||
CycleDuration: 500 * time.Millisecond,
|
||||
BitrateReportInterval: 1 * time.Second,
|
||||
},
|
||||
{
|
||||
SamplesRequired: 5,
|
||||
CyclesRequired: 20,
|
||||
CycleDuration: 500 * time.Millisecond,
|
||||
BitrateReportInterval: 1 * time.Second,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Redis: redisLiveKit.RedisConfig{},
|
||||
Room: RoomConfig{
|
||||
|
||||
@@ -234,6 +234,7 @@ func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track *webrtc.Tra
|
||||
t.params.TrackInfo,
|
||||
LoggerWithCodecMime(t.params.Logger, mime),
|
||||
twcc,
|
||||
t.params.VideoConfig.StreamTracker,
|
||||
sfu.WithPliThrottleConfig(t.params.PLIThrottleConfig),
|
||||
sfu.WithAudioConfig(t.params.AudioConfig),
|
||||
sfu.WithLoadBalanceThreshold(20),
|
||||
|
||||
@@ -171,6 +171,7 @@ func NewWebRTCReceiver(
|
||||
trackInfo *livekit.TrackInfo,
|
||||
logger logger.Logger,
|
||||
twcc *twcc.Responder,
|
||||
trackerConfig config.StreamTrackersConfig,
|
||||
opts ...ReceiverOpts,
|
||||
) *WebRTCReceiver {
|
||||
w := &WebRTCReceiver{
|
||||
@@ -188,7 +189,7 @@ func NewWebRTCReceiver(
|
||||
isRED: IsRedCodec(track.Codec().MimeType),
|
||||
}
|
||||
|
||||
w.streamTrackerManager = NewStreamTrackerManager(logger, trackInfo, w.isSVC)
|
||||
w.streamTrackerManager = NewStreamTrackerManager(logger, trackInfo, w.isSVC, trackerConfig)
|
||||
w.streamTrackerManager.OnAvailableLayersChanged(w.downTrackLayerChange)
|
||||
w.streamTrackerManager.OnBitrateAvailabilityChanged(w.downTrackBitrateAvailabilityChange)
|
||||
|
||||
|
||||
@@ -3,69 +3,24 @@ package sfu
|
||||
import (
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/livekit/livekit-server/pkg/config"
|
||||
"github.com/livekit/livekit-server/pkg/sfu/buffer"
|
||||
"github.com/livekit/protocol/livekit"
|
||||
"github.com/livekit/protocol/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
ExemptedLayersScreenshare = []int32{0}
|
||||
ExemptedLayersVideo = []int32{}
|
||||
)
|
||||
|
||||
var (
|
||||
ConfigVideo = []StreamTrackerParams{
|
||||
{
|
||||
SamplesRequired: 1,
|
||||
CyclesRequired: 4,
|
||||
CycleDuration: 500 * time.Millisecond,
|
||||
BitrateReportInterval: 1 * time.Second,
|
||||
},
|
||||
{
|
||||
SamplesRequired: 5,
|
||||
CyclesRequired: 20,
|
||||
CycleDuration: 500 * time.Millisecond,
|
||||
BitrateReportInterval: 1 * time.Second,
|
||||
},
|
||||
{
|
||||
SamplesRequired: 5,
|
||||
CyclesRequired: 20,
|
||||
CycleDuration: 500 * time.Millisecond,
|
||||
BitrateReportInterval: 1 * time.Second,
|
||||
},
|
||||
}
|
||||
|
||||
// be very forgiving for screen share to account for cases like static screen where there could be only one packet per second
|
||||
ConfigScreenshare = []StreamTrackerParams{
|
||||
{
|
||||
SamplesRequired: 1,
|
||||
CyclesRequired: 1,
|
||||
CycleDuration: 2 * time.Second,
|
||||
BitrateReportInterval: 4 * time.Second,
|
||||
},
|
||||
{
|
||||
SamplesRequired: 1,
|
||||
CyclesRequired: 1,
|
||||
CycleDuration: 2 * time.Second,
|
||||
BitrateReportInterval: 4 * time.Second,
|
||||
},
|
||||
{
|
||||
SamplesRequired: 1,
|
||||
CyclesRequired: 1,
|
||||
CycleDuration: 2 * time.Second,
|
||||
BitrateReportInterval: 4 * time.Second,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type StreamTrackerManager struct {
|
||||
logger logger.Logger
|
||||
trackInfo *livekit.TrackInfo
|
||||
isSVC bool
|
||||
maxPublishedLayer int32
|
||||
|
||||
configVideo []StreamTrackerParams
|
||||
configScreenshare []StreamTrackerParams
|
||||
exemptedLayersVideo []int32
|
||||
exemptedLayersScreenshare []int32
|
||||
|
||||
lock sync.RWMutex
|
||||
|
||||
trackers [DefaultMaxLayerSpatial + 1]*StreamTracker
|
||||
@@ -80,12 +35,32 @@ type StreamTrackerManager struct {
|
||||
onMaxLayerChanged func(maxLayer int32)
|
||||
}
|
||||
|
||||
func NewStreamTrackerManager(logger logger.Logger, trackInfo *livekit.TrackInfo, isSVC bool) *StreamTrackerManager {
|
||||
func NewStreamTrackerManager(logger logger.Logger, trackInfo *livekit.TrackInfo, isSVC bool, trackerConfig config.StreamTrackersConfig) *StreamTrackerManager {
|
||||
s := &StreamTrackerManager{
|
||||
logger: logger,
|
||||
trackInfo: trackInfo,
|
||||
isSVC: isSVC,
|
||||
maxPublishedLayer: 0,
|
||||
logger: logger,
|
||||
trackInfo: trackInfo,
|
||||
isSVC: isSVC,
|
||||
maxPublishedLayer: 0,
|
||||
exemptedLayersVideo: trackerConfig.ExemptedLayersVideo,
|
||||
exemptedLayersScreenshare: trackerConfig.ExemptedLayersScreenshare,
|
||||
}
|
||||
|
||||
for _, layer := range trackerConfig.Video {
|
||||
s.configVideo = append(s.configVideo, StreamTrackerParams{
|
||||
SamplesRequired: layer.SamplesRequired,
|
||||
CyclesRequired: layer.CyclesRequired,
|
||||
CycleDuration: layer.CycleDuration,
|
||||
BitrateReportInterval: layer.BitrateReportInterval,
|
||||
})
|
||||
}
|
||||
|
||||
for _, layer := range trackerConfig.Screenshare {
|
||||
s.configScreenshare = append(s.configScreenshare, StreamTrackerParams{
|
||||
SamplesRequired: layer.SamplesRequired,
|
||||
CyclesRequired: layer.CyclesRequired,
|
||||
CycleDuration: layer.CycleDuration,
|
||||
BitrateReportInterval: layer.BitrateReportInterval,
|
||||
})
|
||||
}
|
||||
|
||||
for _, layer := range s.trackInfo.Layers {
|
||||
@@ -114,17 +89,17 @@ func (s *StreamTrackerManager) OnMaxLayerChanged(f func(maxLayer int32)) {
|
||||
func (s *StreamTrackerManager) AddTracker(layer int32) *StreamTracker {
|
||||
var params StreamTrackerParams
|
||||
if s.trackInfo.Source == livekit.TrackSource_SCREEN_SHARE {
|
||||
if int(layer) >= len(ConfigScreenshare) {
|
||||
if int(layer) >= len(s.configScreenshare) {
|
||||
return nil
|
||||
}
|
||||
|
||||
params = ConfigScreenshare[layer]
|
||||
params = s.configScreenshare[layer]
|
||||
} else {
|
||||
if int(layer) >= len(ConfigVideo) {
|
||||
if int(layer) >= len(s.configVideo) {
|
||||
return nil
|
||||
}
|
||||
|
||||
params = ConfigVideo[layer]
|
||||
params = s.configVideo[layer]
|
||||
}
|
||||
params.Logger = s.logger.WithValues("layer", layer)
|
||||
tracker := NewStreamTracker(params)
|
||||
@@ -420,9 +395,9 @@ func (s *StreamTrackerManager) removeAvailableLayer(layer int32) {
|
||||
exempt := false
|
||||
var sourceExemptedLayers []int32
|
||||
if s.trackInfo.Source == livekit.TrackSource_SCREEN_SHARE {
|
||||
sourceExemptedLayers = ExemptedLayersScreenshare
|
||||
sourceExemptedLayers = s.exemptedLayersScreenshare
|
||||
} else {
|
||||
sourceExemptedLayers = ExemptedLayersVideo
|
||||
sourceExemptedLayers = s.exemptedLayersVideo
|
||||
}
|
||||
for _, l := range sourceExemptedLayers {
|
||||
if layer == l {
|
||||
|
||||
Reference in New Issue
Block a user