Chaging VideoLayers -> VideoLayer (#1591)

There was mixed used. It is a struct. So, it is a singular.
Change all the places I could find. There may be more, but can be
changed when spotted.
This commit is contained in:
Raja Subramanian
2023-04-08 12:39:02 +05:30
committed by GitHub
parent e03f75d6a1
commit 4969b57c09
9 changed files with 420 additions and 422 deletions

View File

@@ -11,12 +11,12 @@ const (
)
var (
InvalidLayers = VideoLayer{
InvalidLayer = VideoLayer{
Spatial: InvalidLayerSpatial,
Temporal: InvalidLayerTemporal,
}
DefaultMaxLayers = VideoLayer{
DefaultMaxLayer = VideoLayer{
Spatial: DefaultMaxLayerSpatial,
Temporal: DefaultMaxLayerTemporal,
}

View File

@@ -137,7 +137,7 @@ type DownTrackStreamAllocatorListener interface {
OnSubscriptionChanged(dt *DownTrack)
// subscribed max video layer changed
OnSubscribedLayersChanged(dt *DownTrack, layers buffer.VideoLayer)
OnSubscribedLayerChanged(dt *DownTrack, layers buffer.VideoLayer)
// stream resumed
OnResume(dt *DownTrack)
@@ -259,7 +259,7 @@ func NewDownTrack(
codec: codecs[0].RTPCodecCapability,
}
d.forwarder = NewForwarder(d.kind, d.logger, d.receiver.GetReferenceLayerRTPTimestamp)
d.forwarder.OnParkedLayersExpired(func() {
d.forwarder.OnParkedLayerExpired(func() {
if sal := d.getStreamAllocatorListener(); sal != nil {
sal.OnSubscriptionChanged(d)
}
@@ -599,10 +599,8 @@ func (d *DownTrack) WriteRTP(extPkt *buffer.ExtPacket, layer int32) error {
if extPkt.KeyFrame {
d.isNACKThrottled.Store(false)
if extPkt.KeyFrame {
d.rtpStats.UpdateKeyFrame(1)
d.logger.Debugw("forwarding key frame", "layer", layer)
}
d.rtpStats.UpdateKeyFrame(1)
d.logger.Debugw("forwarding key frame", "layer", layer)
// SVC-TODO - no need for key frame always when using SVC
locked, _ := d.forwarder.CheckSync()
@@ -716,17 +714,17 @@ func (d *DownTrack) WritePaddingRTP(bytesToSend int, paddingOnMute bool) int {
// Mute enables or disables media forwarding - subscriber triggered
func (d *DownTrack) Mute(muted bool) {
changed, maxLayers := d.forwarder.Mute(muted)
d.handleMute(muted, false, changed, maxLayers)
changed, maxLayer := d.forwarder.Mute(muted)
d.handleMute(muted, false, changed, maxLayer)
}
// PubMute enables or disables media forwarding - publisher side
func (d *DownTrack) PubMute(pubMuted bool) {
changed, maxLayers := d.forwarder.PubMute(pubMuted)
d.handleMute(pubMuted, true, changed, maxLayers)
changed, maxLayer := d.forwarder.PubMute(pubMuted)
d.handleMute(pubMuted, true, changed, maxLayer)
}
func (d *DownTrack) handleMute(muted bool, isPub bool, changed bool, maxLayers buffer.VideoLayer) {
func (d *DownTrack) handleMute(muted bool, isPub bool, changed bool, maxLayer buffer.VideoLayer) {
if !changed {
return
}
@@ -761,7 +759,7 @@ func (d *DownTrack) handleMute(muted bool, isPub bool, changed bool, maxLayers b
// client might need to be notified to start layers
// before locking can happen in the forwarder.
//
notifyLayer = maxLayers.Spatial
notifyLayer = maxLayer.Spatial
}
d.onMaxSubscribedLayerChanged(d, notifyLayer)
}
@@ -860,12 +858,12 @@ func (d *DownTrack) CloseWithFlush(flush bool) {
}
func (d *DownTrack) SetMaxSpatialLayer(spatialLayer int32) {
changed, maxLayers, currentLayers := d.forwarder.SetMaxSpatialLayer(spatialLayer)
changed, maxLayer, currentLayer := d.forwarder.SetMaxSpatialLayer(spatialLayer)
if !changed {
return
}
if d.onMaxSubscribedLayerChanged != nil && d.kind == webrtc.RTPCodecTypeVideo && maxLayers.SpatialGreaterThanOrEqual(currentLayers) {
if d.onMaxSubscribedLayerChanged != nil && d.kind == webrtc.RTPCodecTypeVideo && maxLayer.SpatialGreaterThanOrEqual(currentLayer) {
//
// Notify when new max is
// 1. Equal to current -> already locked to the new max
@@ -873,27 +871,27 @@ func (d *DownTrack) SetMaxSpatialLayer(spatialLayer int32) {
// a. is higher than previous max -> client may need to start higher layer before forwarder can lock
// b. is lower than previous max -> client can stop higher layer(s)
//
d.onMaxSubscribedLayerChanged(d, maxLayers.Spatial)
d.onMaxSubscribedLayerChanged(d, maxLayer.Spatial)
}
if sal := d.getStreamAllocatorListener(); sal != nil {
sal.OnSubscribedLayersChanged(d, maxLayers)
sal.OnSubscribedLayerChanged(d, maxLayer)
}
}
func (d *DownTrack) SetMaxTemporalLayer(temporalLayer int32) {
changed, maxLayers, _ := d.forwarder.SetMaxTemporalLayer(temporalLayer)
changed, maxLayer, _ := d.forwarder.SetMaxTemporalLayer(temporalLayer)
if !changed {
return
}
if sal := d.getStreamAllocatorListener(); sal != nil {
sal.OnSubscribedLayersChanged(d, maxLayers)
sal.OnSubscribedLayerChanged(d, maxLayer)
}
}
func (d *DownTrack) MaxLayers() buffer.VideoLayer {
return d.forwarder.MaxLayers()
func (d *DownTrack) MaxLayer() buffer.VideoLayer {
return d.forwarder.MaxLayer()
}
func (d *DownTrack) GetState() DownTrackState {
@@ -1566,7 +1564,7 @@ func (d *DownTrack) DebugInfo() map[string]interface{} {
"Bound": d.bound.Load(),
"Muted": d.forwarder.IsMuted(),
"PubMuted": d.forwarder.IsPubMuted(),
"CurrentSpatialLayer": d.forwarder.CurrentLayers().Spatial,
"CurrentSpatialLayer": d.forwarder.CurrentLayer().Spatial,
"Stats": stats,
}
}

View File

@@ -20,10 +20,10 @@ import (
// Forwarder
const (
FlagPauseOnDowngrade = true
FlagFilterRTX = true
TransitionCostSpatial = 10
ParkedLayersWaitDuration = 2 * time.Second
FlagPauseOnDowngrade = true
FlagFilterRTX = true
TransitionCostSpatial = 10
ParkedLayerWaitDuration = 2 * time.Second
)
// -------------------------------------------------------------------
@@ -64,9 +64,9 @@ type VideoAllocation struct {
BandwidthDelta int64
BandwidthNeeded int64
Bitrates Bitrates
TargetLayers buffer.VideoLayer
TargetLayer buffer.VideoLayer
RequestLayerSpatial int32
MaxLayers buffer.VideoLayer
MaxLayer buffer.VideoLayer
DistanceToDesired float64
}
@@ -78,9 +78,9 @@ func (v VideoAllocation) String() string {
v.BandwidthDelta,
v.BandwidthNeeded,
v.Bitrates,
v.TargetLayers,
v.TargetLayer,
v.RequestLayerSpatial,
v.MaxLayers,
v.MaxLayer,
v.DistanceToDesired,
)
}
@@ -88,9 +88,9 @@ func (v VideoAllocation) String() string {
var (
VideoAllocationDefault = VideoAllocation{
PauseReason: VideoPauseReasonFeedDry, // start with no feed till feed is seen
TargetLayers: buffer.InvalidLayers,
TargetLayer: buffer.InvalidLayer,
RequestLayerSpatial: buffer.InvalidLayerSpatial,
MaxLayers: buffer.InvalidLayers,
MaxLayer: buffer.InvalidLayer,
}
)
@@ -102,10 +102,10 @@ type VideoAllocationProvisional struct {
maxSeenLayer buffer.VideoLayer
availableLayers []int32
Bitrates Bitrates
maxLayers buffer.VideoLayer
currentLayers buffer.VideoLayer
parkedLayers buffer.VideoLayer
allocatedLayers buffer.VideoLayer
maxLayer buffer.VideoLayer
currentLayer buffer.VideoLayer
parkedLayer buffer.VideoLayer
allocatedLayer buffer.VideoLayer
}
// -------------------------------------------------------------------
@@ -165,7 +165,7 @@ type Forwarder struct {
lastSSRC uint32
referenceLayerSpatial int32
parkedLayersTimer *time.Timer
parkedLayerTimer *time.Timer
provisional *VideoAllocationProvisional
@@ -177,7 +177,7 @@ type Forwarder struct {
codecMunger codecmunger.CodecMunger
onParkedLayersExpired func()
onParkedLayerExpired func()
}
func NewForwarder(
@@ -228,18 +228,18 @@ func (f *Forwarder) SetMaxTemporalLayerSeen(maxTemporalLayerSeen int32) {
f.logger.Debugw("setting max temporal layer seen", "maxTemporalLayerSeen", maxTemporalLayerSeen)
}
func (f *Forwarder) OnParkedLayersExpired(fn func()) {
func (f *Forwarder) OnParkedLayerExpired(fn func()) {
f.lock.Lock()
defer f.lock.Unlock()
f.onParkedLayersExpired = fn
f.onParkedLayerExpired = fn
}
func (f *Forwarder) getOnParkedLayersExpired() func() {
func (f *Forwarder) getOnParkedLayerExpired() func() {
f.lock.RLock()
defer f.lock.RUnlock()
return f.onParkedLayersExpired
return f.onParkedLayerExpired
}
func (f *Forwarder) DetermineCodec(codec webrtc.RTPCodecCapability, extensions []webrtc.RTPHeaderExtensionParameter) {
@@ -374,12 +374,12 @@ func (f *Forwarder) PubMute(pubMuted bool) (bool, buffer.VideoLayer) {
f.resyncLocked()
}
} else {
// Do not resync on publisher mute as forwarding can continue on unmute using same layers.
// Do not resync on publisher mute as forwarding can continue on unmute using same layer.
// On unmute, park current layers as streaming can continue without a key frame when publisher starts the stream.
targetLayer := f.vls.GetTarget()
if !pubMuted && targetLayer.IsValid() && f.vls.GetCurrent().Spatial == targetLayer.Spatial {
f.setupParkedLayers(targetLayer)
f.vls.SetCurrent(buffer.InvalidLayers)
f.setupParkedLayer(targetLayer)
f.vls.SetCurrent(buffer.InvalidLayer)
}
}
@@ -405,7 +405,7 @@ func (f *Forwarder) SetMaxSpatialLayer(spatialLayer int32) (bool, buffer.VideoLa
defer f.lock.Unlock()
if f.kind == webrtc.RTPCodecTypeAudio {
return false, buffer.InvalidLayers, buffer.InvalidLayers
return false, buffer.InvalidLayer, buffer.InvalidLayer
}
existingMax := f.vls.GetMax()
@@ -416,7 +416,7 @@ func (f *Forwarder) SetMaxSpatialLayer(spatialLayer int32) (bool, buffer.VideoLa
f.logger.Debugw("setting max spatial layer", "layer", spatialLayer)
f.vls.SetMaxSpatial(spatialLayer)
f.clearParkedLayers()
f.clearParkedLayer()
return true, f.vls.GetMax(), f.vls.GetCurrent()
}
@@ -426,7 +426,7 @@ func (f *Forwarder) SetMaxTemporalLayer(temporalLayer int32) (bool, buffer.Video
defer f.lock.Unlock()
if f.kind == webrtc.RTPCodecTypeAudio {
return false, buffer.InvalidLayers, buffer.InvalidLayers
return false, buffer.InvalidLayer, buffer.InvalidLayer
}
existingMax := f.vls.GetMax()
@@ -437,26 +437,26 @@ func (f *Forwarder) SetMaxTemporalLayer(temporalLayer int32) (bool, buffer.Video
f.logger.Debugw("setting max temporal layer", "layer", temporalLayer)
f.vls.SetMaxTemporal(temporalLayer)
f.clearParkedLayers()
f.clearParkedLayer()
return true, f.vls.GetMax(), f.vls.GetCurrent()
}
func (f *Forwarder) MaxLayers() buffer.VideoLayer {
func (f *Forwarder) MaxLayer() buffer.VideoLayer {
f.lock.RLock()
defer f.lock.RUnlock()
return f.vls.GetMax()
}
func (f *Forwarder) CurrentLayers() buffer.VideoLayer {
func (f *Forwarder) CurrentLayer() buffer.VideoLayer {
f.lock.RLock()
defer f.lock.RUnlock()
return f.vls.GetCurrent()
}
func (f *Forwarder) TargetLayers() buffer.VideoLayer {
func (f *Forwarder) TargetLayer() buffer.VideoLayer {
f.lock.RLock()
defer f.lock.RUnlock()
@@ -526,9 +526,9 @@ func (f *Forwarder) AllocateOptimal(availableLayers []int32, brs Bitrates, allow
alloc := VideoAllocation{
PauseReason: VideoPauseReasonNone,
Bitrates: brs,
TargetLayers: buffer.InvalidLayers,
TargetLayer: buffer.InvalidLayer,
RequestLayerSpatial: requestSpatial,
MaxLayers: maxLayer,
MaxLayer: maxLayer,
}
optimalBandwidthNeeded := getOptimalBandwidthNeeded(f.muted, f.pubMuted, maxSeenLayer.Spatial, brs, maxLayer)
if optimalBandwidthNeeded == 0 {
@@ -542,7 +542,7 @@ func (f *Forwarder) AllocateOptimal(availableLayers []int32, brs Bitrates, allow
if allowOvershoot && f.vls.IsOvershootOkay() && maxSeenLayer.Spatial > maxSpatial {
maxSpatial = maxSeenLayer.Spatial
}
alloc.TargetLayers = buffer.VideoLayer{
alloc.TargetLayer = buffer.VideoLayer{
Spatial: int32(math.Min(float64(maxSeenLayer.Spatial), float64(maxSpatial))),
Temporal: maxLayer.Temporal,
}
@@ -558,13 +558,13 @@ func (f *Forwarder) AllocateOptimal(availableLayers []int32, brs Bitrates, allow
case f.pubMuted:
alloc.PauseReason = VideoPauseReasonPubMuted
// leave it at current layers for opportunistic resume
alloc.TargetLayers = currentLayer
alloc.RequestLayerSpatial = alloc.TargetLayers.Spatial
alloc.TargetLayer = currentLayer
alloc.RequestLayerSpatial = alloc.TargetLayer.Spatial
case parkedLayer.IsValid():
// if parked on a layer, let it continue
alloc.TargetLayers = parkedLayer
alloc.RequestLayerSpatial = alloc.TargetLayers.Spatial
alloc.TargetLayer = parkedLayer
alloc.RequestLayerSpatial = alloc.TargetLayer.Spatial
case len(availableLayers) == 0:
// feed may be dry
@@ -573,8 +573,8 @@ func (f *Forwarder) AllocateOptimal(availableLayers []int32, brs Bitrates, allow
// Covers the cases of
// 1. mis-detection of layer stop - can continue streaming
// 2. current layer resuming - can latch on when it starts
alloc.TargetLayers = currentLayer
alloc.RequestLayerSpatial = alloc.TargetLayers.Spatial
alloc.TargetLayer = currentLayer
alloc.RequestLayerSpatial = alloc.TargetLayer.Spatial
} else {
// opportunistically latch on to anything
opportunisticAlloc()
@@ -595,18 +595,18 @@ func (f *Forwarder) AllocateOptimal(availableLayers []int32, brs Bitrates, allow
if !isCurrentLayerAvailable && currentLayer.IsValid() {
// current layer maybe stopped, move to highest available
for _, l := range availableLayers {
if l > alloc.TargetLayers.Spatial {
alloc.TargetLayers.Spatial = l
if l > alloc.TargetLayer.Spatial {
alloc.TargetLayer.Spatial = l
}
}
alloc.TargetLayers.Temporal = maxLayer.Temporal
alloc.TargetLayer.Temporal = maxLayer.Temporal
alloc.RequestLayerSpatial = alloc.TargetLayers.Spatial
alloc.RequestLayerSpatial = alloc.TargetLayer.Spatial
} else {
requestLayerSpatial := int32(math.Min(float64(maxLayer.Spatial), float64(maxSeenLayer.Spatial)))
if currentLayer.IsValid() && requestLayerSpatial == requestSpatial && currentLayer.Spatial == requestSpatial {
// current is locked to desired, stay there
alloc.TargetLayers = buffer.VideoLayer{
alloc.TargetLayer = buffer.VideoLayer{
Spatial: requestSpatial,
Temporal: maxLayer.Temporal,
}
@@ -619,11 +619,11 @@ func (f *Forwarder) AllocateOptimal(availableLayers []int32, brs Bitrates, allow
}
}
if !alloc.TargetLayers.IsValid() {
alloc.TargetLayers = buffer.InvalidLayers
if !alloc.TargetLayer.IsValid() {
alloc.TargetLayer = buffer.InvalidLayer
alloc.RequestLayerSpatial = buffer.InvalidLayerSpatial
}
if alloc.TargetLayers.IsValid() {
if alloc.TargetLayer.IsValid() {
alloc.BandwidthRequested = optimalBandwidthNeeded
}
alloc.BandwidthDelta = alloc.BandwidthRequested - f.lastAllocation.BandwidthRequested
@@ -633,7 +633,7 @@ func (f *Forwarder) AllocateOptimal(availableLayers []int32, brs Bitrates, allow
f.vls.GetMaxSeen(),
availableLayers,
brs,
alloc.TargetLayers,
alloc.TargetLayer,
f.vls.GetMax(),
)
@@ -645,45 +645,45 @@ func (f *Forwarder) ProvisionalAllocatePrepare(availableLayers []int32, Bitrates
defer f.lock.Unlock()
f.provisional = &VideoAllocationProvisional{
allocatedLayers: buffer.InvalidLayers,
muted: f.muted,
pubMuted: f.pubMuted,
maxSeenLayer: f.vls.GetMaxSeen(),
Bitrates: Bitrates,
maxLayers: f.vls.GetMax(),
currentLayers: f.vls.GetCurrent(),
parkedLayers: f.vls.GetParked(),
allocatedLayer: buffer.InvalidLayer,
muted: f.muted,
pubMuted: f.pubMuted,
maxSeenLayer: f.vls.GetMaxSeen(),
Bitrates: Bitrates,
maxLayer: f.vls.GetMax(),
currentLayer: f.vls.GetCurrent(),
parkedLayer: f.vls.GetParked(),
}
f.provisional.availableLayers = make([]int32, len(availableLayers))
copy(f.provisional.availableLayers, availableLayers)
}
func (f *Forwarder) ProvisionalAllocate(availableChannelCapacity int64, layers buffer.VideoLayer, allowPause bool, allowOvershoot bool) int64 {
func (f *Forwarder) ProvisionalAllocate(availableChannelCapacity int64, layer buffer.VideoLayer, allowPause bool, allowOvershoot bool) int64 {
f.lock.Lock()
defer f.lock.Unlock()
if f.provisional.muted ||
f.provisional.pubMuted ||
f.provisional.maxSeenLayer.Spatial == buffer.InvalidLayerSpatial ||
!f.provisional.maxLayers.IsValid() ||
((!allowOvershoot || !f.vls.IsOvershootOkay()) && layers.GreaterThan(f.provisional.maxLayers)) {
!f.provisional.maxLayer.IsValid() ||
((!allowOvershoot || !f.vls.IsOvershootOkay()) && layer.GreaterThan(f.provisional.maxLayer)) {
return 0
}
requiredBitrate := f.provisional.Bitrates[layers.Spatial][layers.Temporal]
requiredBitrate := f.provisional.Bitrates[layer.Spatial][layer.Temporal]
if requiredBitrate == 0 {
return 0
}
alreadyAllocatedBitrate := int64(0)
if f.provisional.allocatedLayers.IsValid() {
alreadyAllocatedBitrate = f.provisional.Bitrates[f.provisional.allocatedLayers.Spatial][f.provisional.allocatedLayers.Temporal]
if f.provisional.allocatedLayer.IsValid() {
alreadyAllocatedBitrate = f.provisional.Bitrates[f.provisional.allocatedLayer.Spatial][f.provisional.allocatedLayer.Temporal]
}
// a layer under maximum fits, take it
if !layers.GreaterThan(f.provisional.maxLayers) && requiredBitrate <= (availableChannelCapacity+alreadyAllocatedBitrate) {
f.provisional.allocatedLayers = layers
if !layer.GreaterThan(f.provisional.maxLayer) && requiredBitrate <= (availableChannelCapacity+alreadyAllocatedBitrate) {
f.provisional.allocatedLayer = layer
return requiredBitrate - alreadyAllocatedBitrate
}
@@ -695,8 +695,8 @@ func (f *Forwarder) ProvisionalAllocate(availableChannelCapacity int64, layers b
// 2. a layer above maximum which may or may not fit, but overshoot is allowed.
// In any of those cases, take the lowest possible layer if pause is not allowed
//
if !allowPause && (!f.provisional.allocatedLayers.IsValid() || !layers.GreaterThan(f.provisional.allocatedLayers)) {
f.provisional.allocatedLayers = layers
if !allowPause && (!f.provisional.allocatedLayer.IsValid() || !layer.GreaterThan(f.provisional.allocatedLayer)) {
f.provisional.allocatedLayer = layer
return requiredBitrate - alreadyAllocatedBitrate
}
@@ -727,14 +727,14 @@ func (f *Forwarder) ProvisionalAllocateGetCooperativeTransition(allowOvershoot b
defer f.lock.Unlock()
if f.provisional.muted || f.provisional.pubMuted {
f.provisional.allocatedLayers = buffer.InvalidLayers
f.provisional.allocatedLayer = buffer.InvalidLayer
if f.provisional.pubMuted {
// leave it at current for opportunistic forwarding, there is still bandwidth saving with publisher mute
f.provisional.allocatedLayers = f.provisional.currentLayers
f.provisional.allocatedLayer = f.provisional.currentLayer
}
return VideoTransition{
From: f.vls.GetTarget(),
To: f.provisional.allocatedLayers,
To: f.provisional.allocatedLayer,
BandwidthDelta: 0 - f.lastAllocation.BandwidthRequested,
}
}
@@ -743,12 +743,12 @@ func (f *Forwarder) ProvisionalAllocateGetCooperativeTransition(allowOvershoot b
targetLayer := f.vls.GetTarget()
if targetLayer.IsValid() {
// what is the highest that is available
maximalLayers := buffer.InvalidLayers
maximalLayer := buffer.InvalidLayer
maximalBandwidthRequired := int64(0)
for s := f.provisional.maxLayers.Spatial; s >= 0; s-- {
for t := f.provisional.maxLayers.Temporal; t >= 0; t-- {
for s := f.provisional.maxLayer.Spatial; s >= 0; s-- {
for t := f.provisional.maxLayer.Temporal; t >= 0; t-- {
if f.provisional.Bitrates[s][t] != 0 {
maximalLayers = buffer.VideoLayer{Spatial: s, Temporal: t}
maximalLayer = buffer.VideoLayer{Spatial: s, Temporal: t}
maximalBandwidthRequired = f.provisional.Bitrates[s][t]
break
}
@@ -759,11 +759,11 @@ func (f *Forwarder) ProvisionalAllocateGetCooperativeTransition(allowOvershoot b
}
}
if maximalLayers.IsValid() {
if !targetLayer.GreaterThan(maximalLayers) && f.provisional.Bitrates[targetLayer.Spatial][targetLayer.Temporal] != 0 {
// currently streaming and maybe wanting an upgrade (targetLayer <= maximalLayers),
if maximalLayer.IsValid() {
if !targetLayer.GreaterThan(maximalLayer) && f.provisional.Bitrates[targetLayer.Spatial][targetLayer.Temporal] != 0 {
// currently streaming and maybe wanting an upgrade (targetLayer <= maximalLayer),
// just preserve current target in the cooperative scheme of things
f.provisional.allocatedLayers = targetLayer
f.provisional.allocatedLayer = targetLayer
return VideoTransition{
From: targetLayer,
To: targetLayer,
@@ -771,12 +771,12 @@ func (f *Forwarder) ProvisionalAllocateGetCooperativeTransition(allowOvershoot b
}
}
if targetLayer.GreaterThan(maximalLayers) {
// maximalLayers < targetLayer, make the down move
f.provisional.allocatedLayers = maximalLayers
if targetLayer.GreaterThan(maximalLayer) {
// maximalLayer < targetLayer, make the down move
f.provisional.allocatedLayer = maximalLayer
return VideoTransition{
From: targetLayer,
To: maximalLayers,
To: maximalLayer,
BandwidthDelta: maximalBandwidthRequired - f.lastAllocation.BandwidthRequested,
}
}
@@ -787,7 +787,7 @@ func (f *Forwarder) ProvisionalAllocateGetCooperativeTransition(allowOvershoot b
minSpatial, maxSpatial int32,
minTemporal, maxTemporal int32,
) (buffer.VideoLayer, int64) {
layers := buffer.InvalidLayers
layers := buffer.InvalidLayer
bw := int64(0)
for s := minSpatial; s <= maxSpatial; s++ {
for t := minTemporal; t <= maxTemporal; t++ {
@@ -812,14 +812,14 @@ func (f *Forwarder) ProvisionalAllocateGetCooperativeTransition(allowOvershoot b
// NOTE: a layer in feed could have paused and there could be other options than going back to minimal,
// but the cooperative scheme knocks things back to minimal
targetLayer, bandwidthRequired = findNextLayer(
0, f.provisional.maxLayers.Spatial,
0, f.provisional.maxLayers.Temporal,
0, f.provisional.maxLayer.Spatial,
0, f.provisional.maxLayer.Temporal,
)
// could not find a minimal layer, overshoot if allowed
if bandwidthRequired == 0 && f.provisional.maxLayers.IsValid() && allowOvershoot && f.vls.IsOvershootOkay() {
if bandwidthRequired == 0 && f.provisional.maxLayer.IsValid() && allowOvershoot && f.vls.IsOvershootOkay() {
targetLayer, bandwidthRequired = findNextLayer(
f.provisional.maxLayers.Spatial+1, buffer.DefaultMaxLayerSpatial,
f.provisional.maxLayer.Spatial+1, buffer.DefaultMaxLayerSpatial,
0, buffer.DefaultMaxLayerTemporal,
)
}
@@ -827,14 +827,14 @@ func (f *Forwarder) ProvisionalAllocateGetCooperativeTransition(allowOvershoot b
// if nothing available, just leave target at current to enable opportunistic forwarding in case current resumes
if !targetLayer.IsValid() {
if f.provisional.parkedLayers.IsValid() {
targetLayer = f.provisional.parkedLayers
if f.provisional.parkedLayer.IsValid() {
targetLayer = f.provisional.parkedLayer
} else {
targetLayer = f.provisional.currentLayers
targetLayer = f.provisional.currentLayer
}
}
f.provisional.allocatedLayers = targetLayer
f.provisional.allocatedLayer = targetLayer
return VideoTransition{
From: f.vls.GetTarget(),
To: targetLayer,
@@ -863,21 +863,21 @@ func (f *Forwarder) ProvisionalAllocateGetBestWeightedTransition() VideoTransiti
targetLayer := f.vls.GetTarget()
if f.provisional.muted || f.provisional.pubMuted {
f.provisional.allocatedLayers = buffer.InvalidLayers
f.provisional.allocatedLayer = buffer.InvalidLayer
if f.provisional.pubMuted {
// leave it at current for opportunistic forwarding, there is still bandwidth saving with publisher mute
f.provisional.allocatedLayers = f.provisional.currentLayers
f.provisional.allocatedLayer = f.provisional.currentLayer
}
return VideoTransition{
From: targetLayer,
To: f.provisional.allocatedLayers,
To: f.provisional.allocatedLayer,
BandwidthDelta: 0 - f.lastAllocation.BandwidthRequested,
}
}
maxReachableLayerTemporal := buffer.InvalidLayerTemporal
for t := f.provisional.maxLayers.Temporal; t >= 0; t-- {
for s := f.provisional.maxLayers.Spatial; s >= 0; s-- {
for t := f.provisional.maxLayer.Temporal; t >= 0; t-- {
for s := f.provisional.maxLayer.Spatial; s >= 0; s-- {
if f.provisional.Bitrates[s][t] != 0 {
maxReachableLayerTemporal = t
break
@@ -892,21 +892,21 @@ func (f *Forwarder) ProvisionalAllocateGetBestWeightedTransition() VideoTransiti
// feed has gone dry, just leave target at current to enable opportunistic forwarding in case current resumes.
// Note that this is giving back bits and opportunistic forwarding resuming might trigger congestion again,
// but that should be handled by stream allocator.
if f.provisional.parkedLayers.IsValid() {
f.provisional.allocatedLayers = f.provisional.parkedLayers
if f.provisional.parkedLayer.IsValid() {
f.provisional.allocatedLayer = f.provisional.parkedLayer
} else {
f.provisional.allocatedLayers = f.provisional.currentLayers
f.provisional.allocatedLayer = f.provisional.currentLayer
}
return VideoTransition{
From: targetLayer,
To: f.provisional.allocatedLayers,
To: f.provisional.allocatedLayer,
BandwidthDelta: 0 - f.lastAllocation.BandwidthRequested,
}
}
// starting from minimum to target, find transition which gives the best
// transition taking into account bits saved vs cost of such a transition
bestLayers := buffer.InvalidLayers
bestLayer := buffer.InvalidLayer
bestBandwidthDelta := int64(0)
bestValue := float32(0)
for s := int32(0); s <= targetLayer.Spatial; s++ {
@@ -932,15 +932,15 @@ func (f *Forwarder) ProvisionalAllocateGetBestWeightedTransition() VideoTransiti
if value > bestValue || (value == bestValue && BandwidthDelta > bestBandwidthDelta) {
bestValue = value
bestBandwidthDelta = BandwidthDelta
bestLayers = buffer.VideoLayer{Spatial: s, Temporal: t}
bestLayer = buffer.VideoLayer{Spatial: s, Temporal: t}
}
}
}
f.provisional.allocatedLayers = bestLayers
f.provisional.allocatedLayer = bestLayer
return VideoTransition{
From: targetLayer,
To: bestLayers,
To: bestLayer,
BandwidthDelta: bestBandwidthDelta,
}
}
@@ -954,24 +954,24 @@ func (f *Forwarder) ProvisionalAllocateCommit() VideoAllocation {
f.provisional.pubMuted,
f.provisional.maxSeenLayer.Spatial,
f.provisional.Bitrates,
f.provisional.maxLayers,
f.provisional.maxLayer,
)
alloc := VideoAllocation{
BandwidthRequested: 0,
BandwidthDelta: -f.lastAllocation.BandwidthRequested,
Bitrates: f.provisional.Bitrates,
BandwidthNeeded: optimalBandwidthNeeded,
TargetLayers: f.provisional.allocatedLayers,
RequestLayerSpatial: f.provisional.allocatedLayers.Spatial,
MaxLayers: f.provisional.maxLayers,
TargetLayer: f.provisional.allocatedLayer,
RequestLayerSpatial: f.provisional.allocatedLayer.Spatial,
MaxLayer: f.provisional.maxLayer,
DistanceToDesired: getDistanceToDesired(
f.provisional.muted,
f.provisional.pubMuted,
f.provisional.maxSeenLayer,
f.provisional.availableLayers,
f.provisional.Bitrates,
f.provisional.allocatedLayers,
f.provisional.maxLayers,
f.provisional.allocatedLayer,
f.provisional.maxLayer,
),
}
@@ -983,46 +983,46 @@ func (f *Forwarder) ProvisionalAllocateCommit() VideoAllocation {
alloc.PauseReason = VideoPauseReasonPubMuted
case optimalBandwidthNeeded == 0:
if f.provisional.allocatedLayers.IsValid() {
if f.provisional.allocatedLayer.IsValid() {
// overshoot
alloc.BandwidthRequested = f.provisional.Bitrates[f.provisional.allocatedLayers.Spatial][f.provisional.allocatedLayers.Temporal]
alloc.BandwidthRequested = f.provisional.Bitrates[f.provisional.allocatedLayer.Spatial][f.provisional.allocatedLayer.Temporal]
alloc.BandwidthDelta = alloc.BandwidthRequested - f.lastAllocation.BandwidthRequested
} else {
alloc.PauseReason = VideoPauseReasonFeedDry
// leave target at current for opportunistic forwarding
if f.provisional.currentLayers.IsValid() && f.provisional.currentLayers.Spatial <= f.provisional.maxLayers.Spatial {
f.provisional.allocatedLayers = f.provisional.currentLayers
alloc.TargetLayers = f.provisional.allocatedLayers
alloc.RequestLayerSpatial = alloc.TargetLayers.Spatial
if f.provisional.currentLayer.IsValid() && f.provisional.currentLayer.Spatial <= f.provisional.maxLayer.Spatial {
f.provisional.allocatedLayer = f.provisional.currentLayer
alloc.TargetLayer = f.provisional.allocatedLayer
alloc.RequestLayerSpatial = alloc.TargetLayer.Spatial
}
}
default:
if f.provisional.allocatedLayers.IsValid() {
alloc.BandwidthRequested = f.provisional.Bitrates[f.provisional.allocatedLayers.Spatial][f.provisional.allocatedLayers.Temporal]
if f.provisional.allocatedLayer.IsValid() {
alloc.BandwidthRequested = f.provisional.Bitrates[f.provisional.allocatedLayer.Spatial][f.provisional.allocatedLayer.Temporal]
}
alloc.BandwidthDelta = alloc.BandwidthRequested - f.lastAllocation.BandwidthRequested
if f.provisional.allocatedLayers.GreaterThan(f.provisional.maxLayers) ||
if f.provisional.allocatedLayer.GreaterThan(f.provisional.maxLayer) ||
alloc.BandwidthRequested >= getOptimalBandwidthNeeded(
f.provisional.muted,
f.provisional.pubMuted,
f.provisional.maxSeenLayer.Spatial,
f.provisional.Bitrates,
f.provisional.maxLayers,
f.provisional.maxLayer,
) {
// could be greater than optimal if overshooting
alloc.IsDeficient = false
} else {
alloc.IsDeficient = true
if !f.provisional.allocatedLayers.IsValid() {
if !f.provisional.allocatedLayer.IsValid() {
alloc.PauseReason = VideoPauseReasonBandwidth
}
}
}
f.clearParkedLayers()
f.clearParkedLayer()
return f.updateAllocation(alloc, "cooperative")
}
@@ -1077,9 +1077,9 @@ func (f *Forwarder) AllocateNextHigher(availableChannelCapacity int64, available
BandwidthDelta: bandwidthRequested - alreadyAllocated,
BandwidthNeeded: optimalBandwidthNeeded,
Bitrates: brs,
TargetLayers: newTargetLayer,
TargetLayer: newTargetLayer,
RequestLayerSpatial: newTargetLayer.Spatial,
MaxLayers: maxLayer,
MaxLayer: maxLayer,
DistanceToDesired: getDistanceToDesired(
f.muted,
f.pubMuted,
@@ -1236,16 +1236,16 @@ func (f *Forwarder) Pause(availableLayers []int32, brs Bitrates) VideoAllocation
BandwidthDelta: 0 - f.lastAllocation.BandwidthRequested,
Bitrates: brs,
BandwidthNeeded: optimalBandwidthNeeded,
TargetLayers: buffer.InvalidLayers,
TargetLayer: buffer.InvalidLayer,
RequestLayerSpatial: buffer.InvalidLayerSpatial,
MaxLayers: maxLayer,
MaxLayer: maxLayer,
DistanceToDesired: getDistanceToDesired(
f.muted,
f.pubMuted,
maxSeenLayer,
availableLayers,
brs,
buffer.InvalidLayers,
buffer.InvalidLayer,
maxLayer,
),
}
@@ -1266,19 +1266,19 @@ func (f *Forwarder) Pause(availableLayers []int32, brs Bitrates) VideoAllocation
alloc.PauseReason = VideoPauseReasonBandwidth
}
f.clearParkedLayers()
f.clearParkedLayer()
return f.updateAllocation(alloc, "pause")
}
func (f *Forwarder) updateAllocation(alloc VideoAllocation, reason string) VideoAllocation {
// restrict target temporal to 0 if codec does not support temporal layers
if alloc.TargetLayers.IsValid() && strings.ToLower(f.codec.MimeType) == "video/h264" {
alloc.TargetLayers.Temporal = 0
if alloc.TargetLayer.IsValid() && strings.ToLower(f.codec.MimeType) == "video/h264" {
alloc.TargetLayer.Temporal = 0
}
if alloc.IsDeficient != f.lastAllocation.IsDeficient ||
alloc.PauseReason != f.lastAllocation.PauseReason ||
alloc.TargetLayers != f.lastAllocation.TargetLayers ||
alloc.TargetLayer != f.lastAllocation.TargetLayer ||
alloc.RequestLayerSpatial != f.lastAllocation.RequestLayerSpatial {
if reason == "optimal" {
f.logger.Debugw(fmt.Sprintf("stream allocation: %s", reason), "allocation", alloc)
@@ -1288,7 +1288,7 @@ func (f *Forwarder) updateAllocation(alloc VideoAllocation, reason string) Video
}
f.lastAllocation = alloc
f.setTargetLayers(f.lastAllocation.TargetLayers, f.lastAllocation.RequestLayerSpatial)
f.setTargetLayer(f.lastAllocation.TargetLayer, f.lastAllocation.RequestLayerSpatial)
if !f.vls.GetTarget().IsValid() {
f.resyncLocked()
}
@@ -1296,8 +1296,8 @@ func (f *Forwarder) updateAllocation(alloc VideoAllocation, reason string) Video
return f.lastAllocation
}
func (f *Forwarder) setTargetLayers(targetLayers buffer.VideoLayer, requestLayerSpatial int32) {
f.vls.SetTarget(targetLayers)
func (f *Forwarder) setTargetLayer(targetLayer buffer.VideoLayer, requestLayerSpatial int32) {
f.vls.SetTarget(targetLayer)
f.vls.SetRequestSpatial(requestLayerSpatial)
}
@@ -1309,31 +1309,31 @@ func (f *Forwarder) Resync() {
}
func (f *Forwarder) resyncLocked() {
f.vls.SetCurrent(buffer.InvalidLayers)
f.vls.SetCurrent(buffer.InvalidLayer)
f.lastSSRC = 0
f.clearParkedLayers()
f.clearParkedLayer()
}
func (f *Forwarder) clearParkedLayers() {
f.vls.SetParked(buffer.InvalidLayers)
if f.parkedLayersTimer != nil {
f.parkedLayersTimer.Stop()
f.parkedLayersTimer = nil
func (f *Forwarder) clearParkedLayer() {
f.vls.SetParked(buffer.InvalidLayer)
if f.parkedLayerTimer != nil {
f.parkedLayerTimer.Stop()
f.parkedLayerTimer = nil
}
}
func (f *Forwarder) setupParkedLayers(parkedLayers buffer.VideoLayer) {
f.clearParkedLayers()
func (f *Forwarder) setupParkedLayer(parkedLayer buffer.VideoLayer) {
f.clearParkedLayer()
f.vls.SetParked(parkedLayers)
f.parkedLayersTimer = time.AfterFunc(ParkedLayersWaitDuration, func() {
f.vls.SetParked(parkedLayer)
f.parkedLayerTimer = time.AfterFunc(ParkedLayerWaitDuration, func() {
f.lock.Lock()
notify := f.vls.GetParked().IsValid()
f.clearParkedLayers()
f.clearParkedLayer()
f.lock.Unlock()
if onParkedLayersExpired := f.getOnParkedLayersExpired(); onParkedLayersExpired != nil && notify {
onParkedLayersExpired()
if onParkedLayerExpired := f.getOnParkedLayerExpired(); onParkedLayerExpired != nil && notify {
onParkedLayerExpired()
}
})
}
@@ -1588,13 +1588,13 @@ func (f *Forwarder) GetRTPMungerParams() RTPMungerParams {
// -----------------------------------------------------------------------------
func getOptimalBandwidthNeeded(muted bool, pubMuted bool, maxPublishedLayer int32, brs Bitrates, maxLayers buffer.VideoLayer) int64 {
func getOptimalBandwidthNeeded(muted bool, pubMuted bool, maxPublishedLayer int32, brs Bitrates, maxLayer buffer.VideoLayer) int64 {
if muted || pubMuted || maxPublishedLayer == buffer.InvalidLayerSpatial {
return 0
}
for i := maxLayers.Spatial; i >= 0; i-- {
for j := maxLayers.Temporal; j >= 0; j-- {
for i := maxLayer.Spatial; i >= 0; i-- {
for j := maxLayer.Temporal; j >= 0; j-- {
if brs[i][j] == 0 {
continue
}
@@ -1617,14 +1617,14 @@ func getDistanceToDesired(
maxSeenLayer buffer.VideoLayer,
availableLayers []int32,
brs Bitrates,
targetLayers buffer.VideoLayer,
maxLayers buffer.VideoLayer,
targetLayer buffer.VideoLayer,
maxLayer buffer.VideoLayer,
) float64 {
if muted || pubMuted || !maxSeenLayer.IsValid() || !maxLayers.IsValid() {
if muted || pubMuted || !maxSeenLayer.IsValid() || !maxLayer.IsValid() {
return 0.0
}
adjustedMaxLayers := maxLayers
adjustedMaxLayer := maxLayer
maxAvailableSpatial := buffer.InvalidLayerSpatial
maxAvailableTemporal := buffer.InvalidLayerTemporal
@@ -1651,48 +1651,48 @@ done:
}
}
if maxAvailableSpatial < adjustedMaxLayers.Spatial {
adjustedMaxLayers.Spatial = maxAvailableSpatial
if maxAvailableSpatial < adjustedMaxLayer.Spatial {
adjustedMaxLayer.Spatial = maxAvailableSpatial
}
if maxSeenLayer.Spatial < adjustedMaxLayers.Spatial {
adjustedMaxLayers.Spatial = maxSeenLayer.Spatial
if maxSeenLayer.Spatial < adjustedMaxLayer.Spatial {
adjustedMaxLayer.Spatial = maxSeenLayer.Spatial
}
// max available temporal is min(subscribedMax, temporalLayerSeenMax, availableMax)
// subscribedMax = subscriber requested max temporal layer
// temporalLayerSeenMax = max temporal layer ever published/seen
// availableMax = based on bit rate measurement, available max temporal in the adjusted max spatial layer
if adjustedMaxLayers.Spatial != buffer.InvalidLayerSpatial {
if adjustedMaxLayer.Spatial != buffer.InvalidLayerSpatial {
for t := int32(len(brs[0])) - 1; t >= 0; t-- {
if brs[adjustedMaxLayers.Spatial][t] != 0 {
if brs[adjustedMaxLayer.Spatial][t] != 0 {
maxAvailableTemporal = t
break
}
}
}
if maxAvailableTemporal < adjustedMaxLayers.Temporal {
adjustedMaxLayers.Temporal = maxAvailableTemporal
if maxAvailableTemporal < adjustedMaxLayer.Temporal {
adjustedMaxLayer.Temporal = maxAvailableTemporal
}
if maxSeenLayer.Temporal < adjustedMaxLayers.Temporal {
adjustedMaxLayers.Temporal = maxSeenLayer.Temporal
if maxSeenLayer.Temporal < adjustedMaxLayer.Temporal {
adjustedMaxLayer.Temporal = maxSeenLayer.Temporal
}
if !adjustedMaxLayers.IsValid() {
adjustedMaxLayers = buffer.VideoLayer{Spatial: 0, Temporal: 0}
if !adjustedMaxLayer.IsValid() {
adjustedMaxLayer = buffer.VideoLayer{Spatial: 0, Temporal: 0}
}
// adjust target layers if they are invalid, i. e. not streaming
adjustedTargetLayers := targetLayers
if !targetLayers.IsValid() {
adjustedTargetLayers = buffer.VideoLayer{Spatial: 0, Temporal: 0}
adjustedTargetLayer := targetLayer
if !targetLayer.IsValid() {
adjustedTargetLayer = buffer.VideoLayer{Spatial: 0, Temporal: 0}
}
distance :=
((adjustedMaxLayers.Spatial - adjustedTargetLayers.Spatial) * (maxSeenLayer.Temporal + 1)) +
(adjustedMaxLayers.Temporal - adjustedTargetLayers.Temporal)
if !targetLayers.IsValid() {
((adjustedMaxLayer.Spatial - adjustedTargetLayer.Spatial) * (maxSeenLayer.Temporal + 1)) +
(adjustedMaxLayer.Temporal - adjustedTargetLayer.Temporal)
if !targetLayer.IsValid() {
distance++
}

View File

@@ -13,8 +13,8 @@ import (
)
func disable(f *Forwarder) {
f.vls.SetCurrent(buffer.InvalidLayers)
f.vls.SetTarget(buffer.InvalidLayers)
f.vls.SetCurrent(buffer.InvalidLayer)
f.vls.SetTarget(buffer.InvalidLayer)
}
func newForwarder(codec webrtc.RTPCodecCapability, kind webrtc.RTPCodecType) *Forwarder {
@@ -40,74 +40,74 @@ func TestForwarderMute(t *testing.T) {
func TestForwarderLayersAudio(t *testing.T) {
f := newForwarder(testutils.TestOpusCodec, webrtc.RTPCodecTypeAudio)
require.Equal(t, buffer.InvalidLayers, f.MaxLayers())
require.Equal(t, buffer.InvalidLayer, f.MaxLayer())
require.Equal(t, buffer.InvalidLayers, f.CurrentLayers())
require.Equal(t, buffer.InvalidLayers, f.TargetLayers())
require.Equal(t, buffer.InvalidLayer, f.CurrentLayer())
require.Equal(t, buffer.InvalidLayer, f.TargetLayer())
changed, maxLayers, currentLayers := f.SetMaxSpatialLayer(1)
changed, maxLayer, currentLayer := f.SetMaxSpatialLayer(1)
require.False(t, changed)
require.Equal(t, buffer.InvalidLayers, maxLayers)
require.Equal(t, buffer.InvalidLayers, currentLayers)
require.Equal(t, buffer.InvalidLayer, maxLayer)
require.Equal(t, buffer.InvalidLayer, currentLayer)
changed, maxLayers, currentLayers = f.SetMaxTemporalLayer(1)
changed, maxLayer, currentLayer = f.SetMaxTemporalLayer(1)
require.False(t, changed)
require.Equal(t, buffer.InvalidLayers, maxLayers)
require.Equal(t, buffer.InvalidLayers, currentLayers)
require.Equal(t, buffer.InvalidLayer, maxLayer)
require.Equal(t, buffer.InvalidLayer, currentLayer)
require.Equal(t, buffer.InvalidLayers, f.MaxLayers())
require.Equal(t, buffer.InvalidLayer, f.MaxLayer())
}
func TestForwarderLayersVideo(t *testing.T) {
f := newForwarder(testutils.TestVP8Codec, webrtc.RTPCodecTypeVideo)
maxLayers := f.MaxLayers()
maxLayer := f.MaxLayer()
expectedLayers := buffer.VideoLayer{Spatial: buffer.InvalidLayerSpatial, Temporal: buffer.DefaultMaxLayerTemporal}
require.Equal(t, expectedLayers, maxLayers)
require.Equal(t, expectedLayers, maxLayer)
require.Equal(t, buffer.InvalidLayers, f.CurrentLayers())
require.Equal(t, buffer.InvalidLayers, f.TargetLayers())
require.Equal(t, buffer.InvalidLayer, f.CurrentLayer())
require.Equal(t, buffer.InvalidLayer, f.TargetLayer())
expectedLayers = buffer.VideoLayer{
Spatial: buffer.DefaultMaxLayerSpatial,
Temporal: buffer.DefaultMaxLayerTemporal,
}
changed, maxLayers, currentLayers := f.SetMaxSpatialLayer(buffer.DefaultMaxLayerSpatial)
changed, maxLayer, currentLayer := f.SetMaxSpatialLayer(buffer.DefaultMaxLayerSpatial)
require.True(t, changed)
require.Equal(t, expectedLayers, maxLayers)
require.Equal(t, buffer.InvalidLayers, currentLayers)
require.Equal(t, expectedLayers, maxLayer)
require.Equal(t, buffer.InvalidLayer, currentLayer)
changed, maxLayers, currentLayers = f.SetMaxSpatialLayer(buffer.DefaultMaxLayerSpatial - 1)
changed, maxLayer, currentLayer = f.SetMaxSpatialLayer(buffer.DefaultMaxLayerSpatial - 1)
require.True(t, changed)
expectedLayers = buffer.VideoLayer{
Spatial: buffer.DefaultMaxLayerSpatial - 1,
Temporal: buffer.DefaultMaxLayerTemporal,
}
require.Equal(t, expectedLayers, maxLayers)
require.Equal(t, expectedLayers, f.MaxLayers())
require.Equal(t, buffer.InvalidLayers, currentLayers)
require.Equal(t, expectedLayers, maxLayer)
require.Equal(t, expectedLayers, f.MaxLayer())
require.Equal(t, buffer.InvalidLayer, currentLayer)
f.vls.SetCurrent(buffer.VideoLayer{Spatial: 0, Temporal: 1})
changed, maxLayers, currentLayers = f.SetMaxSpatialLayer(buffer.DefaultMaxLayerSpatial - 1)
changed, maxLayer, currentLayer = f.SetMaxSpatialLayer(buffer.DefaultMaxLayerSpatial - 1)
require.False(t, changed)
require.Equal(t, expectedLayers, maxLayers)
require.Equal(t, expectedLayers, f.MaxLayers())
require.Equal(t, buffer.VideoLayer{Spatial: 0, Temporal: 1}, currentLayers)
require.Equal(t, expectedLayers, maxLayer)
require.Equal(t, expectedLayers, f.MaxLayer())
require.Equal(t, buffer.VideoLayer{Spatial: 0, Temporal: 1}, currentLayer)
changed, maxLayers, currentLayers = f.SetMaxTemporalLayer(buffer.DefaultMaxLayerTemporal)
changed, maxLayer, currentLayer = f.SetMaxTemporalLayer(buffer.DefaultMaxLayerTemporal)
require.False(t, changed)
require.Equal(t, expectedLayers, maxLayers)
require.Equal(t, buffer.VideoLayer{Spatial: 0, Temporal: 1}, currentLayers)
require.Equal(t, expectedLayers, maxLayer)
require.Equal(t, buffer.VideoLayer{Spatial: 0, Temporal: 1}, currentLayer)
changed, maxLayers, currentLayers = f.SetMaxTemporalLayer(buffer.DefaultMaxLayerTemporal - 1)
changed, maxLayer, currentLayer = f.SetMaxTemporalLayer(buffer.DefaultMaxLayerTemporal - 1)
require.True(t, changed)
expectedLayers = buffer.VideoLayer{
Spatial: buffer.DefaultMaxLayerSpatial - 1,
Temporal: buffer.DefaultMaxLayerTemporal - 1,
}
require.Equal(t, expectedLayers, maxLayers)
require.Equal(t, expectedLayers, f.MaxLayers())
require.Equal(t, buffer.VideoLayer{Spatial: 0, Temporal: 1}, currentLayers)
require.Equal(t, expectedLayers, maxLayer)
require.Equal(t, expectedLayers, f.MaxLayer())
require.Equal(t, buffer.VideoLayer{Spatial: 0, Temporal: 1}, currentLayer)
}
func TestForwarderAllocateOptimal(t *testing.T) {
@@ -121,15 +121,15 @@ func TestForwarderAllocateOptimal(t *testing.T) {
}
// invalid max layers
f.vls.SetMax(buffer.InvalidLayers)
f.vls.SetMax(buffer.InvalidLayer)
expectedResult := VideoAllocation{
PauseReason: VideoPauseReasonFeedDry,
BandwidthRequested: 0,
BandwidthDelta: 0,
Bitrates: bitrates,
TargetLayers: buffer.InvalidLayers,
TargetLayer: buffer.InvalidLayer,
RequestLayerSpatial: buffer.InvalidLayerSpatial,
MaxLayers: buffer.InvalidLayers,
MaxLayer: buffer.InvalidLayer,
DistanceToDesired: 0,
}
result := f.AllocateOptimal(nil, bitrates, true)
@@ -139,15 +139,15 @@ func TestForwarderAllocateOptimal(t *testing.T) {
f.SetMaxSpatialLayer(buffer.DefaultMaxLayerSpatial)
f.SetMaxTemporalLayer(buffer.DefaultMaxLayerTemporal)
// should still have target at buffer.InvalidLayers until max publisher layer is available
// should still have target at buffer.InvalidLayer until max publisher layer is available
expectedResult = VideoAllocation{
PauseReason: VideoPauseReasonFeedDry,
BandwidthRequested: 0,
BandwidthDelta: 0,
Bitrates: bitrates,
TargetLayers: buffer.InvalidLayers,
TargetLayer: buffer.InvalidLayer,
RequestLayerSpatial: buffer.InvalidLayerSpatial,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 0,
}
result = f.AllocateOptimal(nil, bitrates, true)
@@ -164,9 +164,9 @@ func TestForwarderAllocateOptimal(t *testing.T) {
BandwidthRequested: 0,
BandwidthDelta: 0,
Bitrates: bitrates,
TargetLayers: buffer.InvalidLayers,
TargetLayer: buffer.InvalidLayer,
RequestLayerSpatial: buffer.InvalidLayerSpatial,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 0,
}
result = f.AllocateOptimal(nil, bitrates, true)
@@ -183,9 +183,9 @@ func TestForwarderAllocateOptimal(t *testing.T) {
BandwidthRequested: 0,
BandwidthDelta: 0,
Bitrates: bitrates,
TargetLayers: buffer.InvalidLayers,
TargetLayer: buffer.InvalidLayer,
RequestLayerSpatial: buffer.InvalidLayerSpatial,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 0,
}
result = f.AllocateOptimal(nil, bitrates, true)
@@ -204,16 +204,16 @@ func TestForwarderAllocateOptimal(t *testing.T) {
BandwidthRequested: 0,
BandwidthDelta: 0,
Bitrates: emptyBitrates,
TargetLayers: f.vls.GetParked(),
TargetLayer: f.vls.GetParked(),
RequestLayerSpatial: f.vls.GetParked().Spatial,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 0,
}
result = f.AllocateOptimal(nil, emptyBitrates, true)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, f.vls.GetParked(), f.TargetLayers())
f.vls.SetParked(buffer.InvalidLayers)
require.Equal(t, f.vls.GetParked(), f.TargetLayer())
f.vls.SetParked(buffer.InvalidLayer)
// when max layers changes, target is opportunistic, but requested spatial layer should be at max
f.SetMaxTemporalLayerSeen(3)
@@ -224,23 +224,23 @@ func TestForwarderAllocateOptimal(t *testing.T) {
BandwidthDelta: bitrates[1][3],
BandwidthNeeded: bitrates[1][3],
Bitrates: bitrates,
TargetLayers: buffer.DefaultMaxLayers,
TargetLayer: buffer.DefaultMaxLayer,
RequestLayerSpatial: f.vls.GetMax().Spatial,
MaxLayers: f.vls.GetMax(),
MaxLayer: f.vls.GetMax(),
DistanceToDesired: -1,
}
result = f.AllocateOptimal(nil, bitrates, true)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, buffer.DefaultMaxLayers, f.TargetLayers())
require.Equal(t, buffer.DefaultMaxLayer, f.TargetLayer())
// reset max layers for rest of the tests below
f.vls.SetMax(buffer.DefaultMaxLayers)
f.vls.SetMax(buffer.DefaultMaxLayer)
// when feed is dry and current is not valid, should set up for opportunistic forwarding
// NOTE: feed is dry due to availableLayers = nil, some valid bitrates may be passed in here for testing purposes only
disable(f)
expectedTargetLayers := buffer.VideoLayer{
expectedTargetLayer := buffer.VideoLayer{
Spatial: 2,
Temporal: buffer.DefaultMaxLayerTemporal,
}
@@ -250,21 +250,21 @@ func TestForwarderAllocateOptimal(t *testing.T) {
BandwidthDelta: bitrates[2][1] - bitrates[1][3],
BandwidthNeeded: bitrates[2][1],
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: -0.5,
}
result = f.AllocateOptimal(nil, bitrates, true)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
f.vls.SetTarget(buffer.VideoLayer{Spatial: 0, Temporal: 0}) // set to valid to trigger paths in tests below
f.vls.SetCurrent(buffer.VideoLayer{Spatial: 0, Temporal: 3}) // set to valid to trigger paths in tests below
// when feed is dry and current is valid, should stay at current
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 0,
Temporal: 3,
}
@@ -273,17 +273,17 @@ func TestForwarderAllocateOptimal(t *testing.T) {
BandwidthRequested: 0,
BandwidthDelta: 0 - bitrates[2][1],
Bitrates: emptyBitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: -0.75,
}
result = f.AllocateOptimal(nil, emptyBitrates, true)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
f.vls.SetCurrent(buffer.InvalidLayers)
f.vls.SetCurrent(buffer.InvalidLayer)
// opportunistic target if feed is not dry and current is not valid, i. e. not forwarding
expectedResult = VideoAllocation{
@@ -292,34 +292,34 @@ func TestForwarderAllocateOptimal(t *testing.T) {
BandwidthDelta: bitrates[2][1],
BandwidthNeeded: bitrates[2][1],
Bitrates: bitrates,
TargetLayers: buffer.DefaultMaxLayers,
TargetLayer: buffer.DefaultMaxLayer,
RequestLayerSpatial: 2,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: -0.5,
}
result = f.AllocateOptimal([]int32{0, 1}, bitrates, true)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, buffer.DefaultMaxLayers, f.TargetLayers())
require.Equal(t, buffer.DefaultMaxLayer, f.TargetLayer())
// if feed is not dry and current is not locked, should be opportunistic (with and without overshoot)
f.vls.SetTarget(buffer.InvalidLayers)
f.vls.SetTarget(buffer.InvalidLayer)
expectedResult = VideoAllocation{
PauseReason: VideoPauseReasonFeedDry,
BandwidthRequested: 0,
BandwidthDelta: 0 - bitrates[2][1],
Bitrates: emptyBitrates,
TargetLayers: buffer.DefaultMaxLayers,
TargetLayer: buffer.DefaultMaxLayer,
RequestLayerSpatial: 2,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: -1.0,
}
result = f.AllocateOptimal([]int32{0, 1}, emptyBitrates, false)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
f.vls.SetTarget(buffer.InvalidLayers)
expectedTargetLayers = buffer.VideoLayer{
f.vls.SetTarget(buffer.InvalidLayer)
expectedTargetLayer = buffer.VideoLayer{
Spatial: 2,
Temporal: buffer.DefaultMaxLayerTemporal,
}
@@ -329,9 +329,9 @@ func TestForwarderAllocateOptimal(t *testing.T) {
BandwidthDelta: bitrates[2][1],
BandwidthNeeded: bitrates[2][1],
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: 2,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: -0.5,
}
result = f.AllocateOptimal([]int32{0, 1}, bitrates, true)
@@ -340,7 +340,7 @@ func TestForwarderAllocateOptimal(t *testing.T) {
// switches to highest available if feed is not dry and current is valid and current is not available
f.vls.SetCurrent(buffer.VideoLayer{Spatial: 0, Temporal: 1})
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 1,
Temporal: buffer.DefaultMaxLayerTemporal,
}
@@ -350,9 +350,9 @@ func TestForwarderAllocateOptimal(t *testing.T) {
BandwidthDelta: 0,
BandwidthNeeded: bitrates[2][1],
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: 1,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 0.5,
}
result = f.AllocateOptimal([]int32{1}, bitrates, true)
@@ -363,7 +363,7 @@ func TestForwarderAllocateOptimal(t *testing.T) {
f.vls.SetMax(buffer.VideoLayer{Spatial: 0, Temporal: 1})
f.vls.SetCurrent(buffer.VideoLayer{Spatial: 0, Temporal: 1})
f.vls.SetRequestSpatial(0)
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 0,
Temporal: 1,
}
@@ -372,9 +372,9 @@ func TestForwarderAllocateOptimal(t *testing.T) {
BandwidthRequested: 0,
BandwidthDelta: 0 - bitrates[2][1],
Bitrates: emptyBitrates,
TargetLayers: expectedTargetLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: 0,
MaxLayers: f.vls.GetMax(),
MaxLayer: f.vls.GetMax(),
DistanceToDesired: 0.0,
}
result = f.AllocateOptimal([]int32{0, 1}, emptyBitrates, true)
@@ -385,7 +385,7 @@ func TestForwarderAllocateOptimal(t *testing.T) {
f.vls.SetMax(buffer.VideoLayer{Spatial: 2, Temporal: 1})
f.vls.SetCurrent(buffer.VideoLayer{Spatial: 0, Temporal: 1})
f.vls.SetRequestSpatial(0)
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 2,
Temporal: 1,
}
@@ -394,9 +394,9 @@ func TestForwarderAllocateOptimal(t *testing.T) {
BandwidthRequested: 0,
BandwidthDelta: 0,
Bitrates: emptyBitrates,
TargetLayers: expectedTargetLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: 2,
MaxLayers: f.vls.GetMax(),
MaxLayer: f.vls.GetMax(),
DistanceToDesired: -1,
}
result = f.AllocateOptimal([]int32{0, 1}, emptyBitrates, true)
@@ -436,7 +436,7 @@ func TestForwarderProvisionalAllocate(t *testing.T) {
require.Equal(t, int64(0), usedBitrate)
// committing should set target to (1, 2)
expectedTargetLayers := buffer.VideoLayer{
expectedTargetLayer := buffer.VideoLayer{
Spatial: 1,
Temporal: 2,
}
@@ -446,24 +446,24 @@ func TestForwarderProvisionalAllocate(t *testing.T) {
BandwidthDelta: bitrates[1][2],
BandwidthNeeded: bitrates[2][3],
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 1.25,
}
result := f.ProvisionalAllocateCommit()
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
// when nothing fits and pausing disallowed, should allocate (0, 0)
f.vls.SetTarget(buffer.InvalidLayers)
f.vls.SetTarget(buffer.InvalidLayer)
f.ProvisionalAllocatePrepare(nil, bitrates)
usedBitrate = f.ProvisionalAllocate(0, buffer.VideoLayer{Spatial: 0, Temporal: 0}, false, false)
require.Equal(t, int64(1), usedBitrate)
// committing should set target to (0, 0)
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 0,
Temporal: 0,
}
@@ -473,15 +473,15 @@ func TestForwarderProvisionalAllocate(t *testing.T) {
BandwidthDelta: bitrates[0][0] - bitrates[1][2],
BandwidthNeeded: bitrates[2][3],
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 2.75,
}
result = f.ProvisionalAllocateCommit()
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
//
// Test allowOvershoot.
@@ -508,11 +508,11 @@ func TestForwarderProvisionalAllocate(t *testing.T) {
require.Equal(t, bitrates[1][3]-bitrates[2][3], usedBitrate)
// committing should set target to (1, 3)
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 1,
Temporal: 3,
}
expectedMaxLayers := buffer.VideoLayer{
expectedMaxLayer := buffer.VideoLayer{
Spatial: 0,
Temporal: 3,
}
@@ -520,15 +520,15 @@ func TestForwarderProvisionalAllocate(t *testing.T) {
BandwidthRequested: bitrates[1][3],
BandwidthDelta: bitrates[1][3] - 1, // 1 is the last allocation bandwidth requested
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: expectedMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: expectedMaxLayer,
DistanceToDesired: -1.75,
}
result = f.ProvisionalAllocateCommit()
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
//
// Even if overshoot is allowed, but if higher layers do not have bit rates, should continue with current layer.
@@ -555,7 +555,7 @@ func TestForwarderProvisionalAllocate(t *testing.T) {
require.Equal(t, int64(0), usedBitrate)
// committing should set target to (0, 2), i. e. leave it at current for opportunistic forwarding
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 0,
Temporal: 2,
}
@@ -564,15 +564,15 @@ func TestForwarderProvisionalAllocate(t *testing.T) {
BandwidthRequested: bitrates[0][2],
BandwidthDelta: bitrates[0][2] - 8, // 8 is the last allocation bandwidth requested
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: expectedMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: expectedMaxLayer,
DistanceToDesired: 0.25,
}
result = f.ProvisionalAllocateCommit()
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
//
// Same case as above, but current is above max, so target should go to invalid
@@ -597,16 +597,16 @@ func TestForwarderProvisionalAllocate(t *testing.T) {
BandwidthRequested: 0,
BandwidthDelta: 0,
Bitrates: bitrates,
TargetLayers: buffer.InvalidLayers,
TargetLayer: buffer.InvalidLayer,
RequestLayerSpatial: buffer.InvalidLayerSpatial,
MaxLayers: expectedMaxLayers,
MaxLayer: expectedMaxLayer,
DistanceToDesired: 0.25,
}
result = f.ProvisionalAllocateCommit()
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, buffer.InvalidLayers, f.TargetLayers())
require.Equal(t, buffer.InvalidLayers, f.CurrentLayers())
require.Equal(t, buffer.InvalidLayer, f.TargetLayer())
require.Equal(t, buffer.InvalidLayer, f.CurrentLayer())
}
func TestForwarderProvisionalAllocateMute(t *testing.T) {
@@ -629,21 +629,21 @@ func TestForwarderProvisionalAllocateMute(t *testing.T) {
usedBitrate = f.ProvisionalAllocate(bitrates[2][3], buffer.VideoLayer{Spatial: 1, Temporal: 2}, true, true)
require.Equal(t, int64(0), usedBitrate)
// committing should set target to buffer.InvalidLayers as track is muted
// committing should set target to buffer.InvalidLayer as track is muted
expectedResult := VideoAllocation{
PauseReason: VideoPauseReasonMuted,
BandwidthRequested: 0,
BandwidthDelta: 0,
Bitrates: bitrates,
TargetLayers: buffer.InvalidLayers,
TargetLayer: buffer.InvalidLayer,
RequestLayerSpatial: buffer.InvalidLayerSpatial,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 0,
}
result := f.ProvisionalAllocateCommit()
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, buffer.InvalidLayers, f.TargetLayers())
require.Equal(t, buffer.InvalidLayer, f.TargetLayer())
}
func TestForwarderProvisionalAllocateGetCooperativeTransition(t *testing.T) {
@@ -661,9 +661,9 @@ func TestForwarderProvisionalAllocateGetCooperativeTransition(t *testing.T) {
f.ProvisionalAllocatePrepare(nil, bitrates)
// from scratch (buffer.InvalidLayers) should give back layer (0, 0)
// from scratch (buffer.InvalidLayer) should give back layer (0, 0)
expectedTransition := VideoTransition{
From: buffer.InvalidLayers,
From: buffer.InvalidLayer,
To: buffer.VideoLayer{Spatial: 0, Temporal: 0},
BandwidthDelta: 1,
}
@@ -678,23 +678,23 @@ func TestForwarderProvisionalAllocateGetCooperativeTransition(t *testing.T) {
BandwidthDelta: 1,
BandwidthNeeded: bitrates[2][1],
Bitrates: bitrates,
TargetLayers: expectedLayers,
TargetLayer: expectedLayers,
RequestLayerSpatial: expectedLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 2.25,
}
result := f.ProvisionalAllocateCommit()
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedLayers, f.TargetLayers())
require.Equal(t, expectedLayers, f.TargetLayer())
// a higher target that is already streaming, just maintain it
targetLayers := buffer.VideoLayer{Spatial: 2, Temporal: 1}
f.vls.SetTarget(targetLayers)
targetLayer := buffer.VideoLayer{Spatial: 2, Temporal: 1}
f.vls.SetTarget(targetLayer)
f.lastAllocation.BandwidthRequested = 10
expectedTransition = VideoTransition{
From: targetLayers,
To: targetLayers,
From: targetLayer,
To: targetLayer,
BandwidthDelta: 0,
}
transition = f.ProvisionalAllocateGetCooperativeTransition(false)
@@ -707,21 +707,21 @@ func TestForwarderProvisionalAllocateGetCooperativeTransition(t *testing.T) {
BandwidthDelta: 0,
Bitrates: bitrates,
BandwidthNeeded: bitrates[2][1],
TargetLayers: expectedLayers,
TargetLayer: expectedLayers,
RequestLayerSpatial: expectedLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 0.0,
}
result = f.ProvisionalAllocateCommit()
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedLayers, f.TargetLayers())
require.Equal(t, expectedLayers, f.TargetLayer())
// from a target that has become unavailable, should switch to lower available layer
targetLayers = buffer.VideoLayer{Spatial: 2, Temporal: 2}
f.vls.SetTarget(targetLayers)
targetLayer = buffer.VideoLayer{Spatial: 2, Temporal: 2}
f.vls.SetTarget(targetLayer)
expectedTransition = VideoTransition{
From: targetLayers,
From: targetLayer,
To: buffer.VideoLayer{Spatial: 2, Temporal: 1},
BandwidthDelta: 0,
}
@@ -734,10 +734,10 @@ func TestForwarderProvisionalAllocateGetCooperativeTransition(t *testing.T) {
f.Mute(true)
f.ProvisionalAllocatePrepare(nil, bitrates)
// mute should send target to buffer.InvalidLayers
// mute should send target to buffer.InvalidLayer
expectedTransition = VideoTransition{
From: buffer.VideoLayer{Spatial: 2, Temporal: 1},
To: buffer.InvalidLayers,
To: buffer.InvalidLayer,
BandwidthDelta: -10,
}
transition = f.ProvisionalAllocateGetCooperativeTransition(false)
@@ -757,12 +757,12 @@ func TestForwarderProvisionalAllocateGetCooperativeTransition(t *testing.T) {
{9, 10, 0, 0},
}
f.vls.SetTarget(buffer.InvalidLayers)
f.vls.SetTarget(buffer.InvalidLayer)
f.ProvisionalAllocatePrepare(nil, bitrates)
// from scratch (buffer.InvalidLayers) should go to a layer past maximum as overshoot is allowed
// from scratch (buffer.InvalidLayer) should go to a layer past maximum as overshoot is allowed
expectedTransition = VideoTransition{
From: buffer.InvalidLayers,
From: buffer.InvalidLayer,
To: buffer.VideoLayer{Spatial: 1, Temporal: 0},
BandwidthDelta: 5,
}
@@ -771,20 +771,20 @@ func TestForwarderProvisionalAllocateGetCooperativeTransition(t *testing.T) {
// committing should set target to (1, 0)
expectedLayers = buffer.VideoLayer{Spatial: 1, Temporal: 0}
expectedMaxLayers := buffer.VideoLayer{Spatial: 0, Temporal: buffer.DefaultMaxLayerTemporal}
expectedMaxLayer := buffer.VideoLayer{Spatial: 0, Temporal: buffer.DefaultMaxLayerTemporal}
expectedResult = VideoAllocation{
BandwidthRequested: 5,
BandwidthDelta: 5,
Bitrates: bitrates,
TargetLayers: expectedLayers,
TargetLayer: expectedLayers,
RequestLayerSpatial: expectedLayers.Spatial,
MaxLayers: expectedMaxLayers,
MaxLayer: expectedMaxLayer,
DistanceToDesired: -1.0,
}
result = f.ProvisionalAllocateCommit()
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedLayers, f.TargetLayers())
require.Equal(t, expectedLayers, f.TargetLayer())
//
// Test continuing at current layers when feed is dry
@@ -796,13 +796,13 @@ func TestForwarderProvisionalAllocateGetCooperativeTransition(t *testing.T) {
}
f.vls.SetCurrent(buffer.VideoLayer{Spatial: 0, Temporal: 2})
f.vls.SetTarget(buffer.InvalidLayers)
f.vls.SetTarget(buffer.InvalidLayer)
f.ProvisionalAllocatePrepare(nil, bitrates)
// from scratch (buffer.InvalidLayers) should go to current layer
// NOTE: targetLayer is set to buffer.InvalidLayers for testing, but in practice current layers valid and target layers invalid should not happen
// from scratch (buffer.InvalidLayer) should go to current layer
// NOTE: targetLayer is set to buffer.InvalidLayer for testing, but in practice current layers valid and target layers invalid should not happen
expectedTransition = VideoTransition{
From: buffer.InvalidLayers,
From: buffer.InvalidLayer,
To: buffer.VideoLayer{Spatial: 0, Temporal: 2},
BandwidthDelta: -5, // 5 was the bandwidth needed for the last allocation
}
@@ -815,30 +815,30 @@ func TestForwarderProvisionalAllocateGetCooperativeTransition(t *testing.T) {
BandwidthRequested: 0,
BandwidthDelta: -5,
Bitrates: bitrates,
TargetLayers: expectedLayers,
TargetLayer: expectedLayers,
RequestLayerSpatial: expectedLayers.Spatial,
MaxLayers: expectedMaxLayers,
MaxLayer: expectedMaxLayer,
DistanceToDesired: -0.5,
}
result = f.ProvisionalAllocateCommit()
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedLayers, f.TargetLayers())
require.Equal(t, expectedLayers, f.TargetLayer())
// committing should set target to current layers to enable opportunistic forwarding
expectedResult = VideoAllocation{
BandwidthRequested: 0,
BandwidthDelta: 0,
Bitrates: bitrates,
TargetLayers: expectedLayers,
TargetLayer: expectedLayers,
RequestLayerSpatial: expectedLayers.Spatial,
MaxLayers: expectedMaxLayers,
MaxLayer: expectedMaxLayer,
DistanceToDesired: -0.5,
}
result = f.ProvisionalAllocateCommit()
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedLayers, f.TargetLayers())
require.Equal(t, expectedLayers, f.TargetLayer())
}
func TestForwarderProvisionalAllocateGetBestWeightedTransition(t *testing.T) {
@@ -857,7 +857,7 @@ func TestForwarderProvisionalAllocateGetBestWeightedTransition(t *testing.T) {
f.vls.SetTarget(buffer.VideoLayer{Spatial: 2, Temporal: 2})
f.lastAllocation.BandwidthRequested = bitrates[2][2]
expectedTransition := VideoTransition{
From: f.TargetLayers(),
From: f.TargetLayer(),
To: buffer.VideoLayer{Spatial: 2, Temporal: 0},
BandwidthDelta: 2,
}
@@ -909,7 +909,7 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
})
// move from (0, 0) -> (0, 1), i.e. a higher temporal layer is available in the same spatial layer
expectedTargetLayers := buffer.VideoLayer{
expectedTargetLayer := buffer.VideoLayer{
Spatial: 0,
Temporal: 1,
}
@@ -919,15 +919,15 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
BandwidthDelta: 1,
BandwidthNeeded: bitrates[2][1],
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 2.0,
}
result, boosted = f.AllocateNextHigher(100_000_000, nil, bitrates, false)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
require.True(t, boosted)
// empty bitrates cannot increase layer, i. e. last allocation is left unchanged
@@ -937,7 +937,7 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
// move from (0, 1) -> (1, 0), i.e. a higher spatial layer is available
f.vls.SetCurrent(buffer.VideoLayer{Spatial: f.vls.GetCurrent().Spatial, Temporal: 1})
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 1,
Temporal: 0,
}
@@ -947,20 +947,20 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
BandwidthDelta: 1,
BandwidthNeeded: bitrates[2][1],
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 1.25,
}
result, boosted = f.AllocateNextHigher(100_000_000, nil, bitrates, false)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
require.True(t, boosted)
// next higher, move from (1, 0) -> (1, 3), still deficient though
f.vls.SetCurrent(buffer.VideoLayer{Spatial: 1, Temporal: 0})
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 1,
Temporal: 3,
}
@@ -970,20 +970,20 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
BandwidthDelta: 1,
BandwidthNeeded: bitrates[2][1],
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 0.5,
}
result, boosted = f.AllocateNextHigher(100_000_000, nil, bitrates, false)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
require.True(t, boosted)
// next higher, move from (1, 3) -> (2, 1), optimal allocation
f.vls.SetCurrent(buffer.VideoLayer{Spatial: f.vls.GetCurrent().Spatial, Temporal: 3})
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 2,
Temporal: 1,
}
@@ -992,15 +992,15 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
BandwidthDelta: 2,
Bitrates: bitrates,
BandwidthNeeded: bitrates[2][1],
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 0.0,
}
result, boosted = f.AllocateNextHigher(100_000_000, nil, bitrates, false)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
require.True(t, boosted)
// ask again, should return not boosted as there is no room to go higher
@@ -1008,7 +1008,7 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
result, boosted = f.AllocateNextHigher(100_000_000, nil, bitrates, false)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
require.False(t, boosted)
// turn off everything, allocating next layer should result in streaming lowest layers
@@ -1016,7 +1016,7 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
f.lastAllocation.IsDeficient = true
f.lastAllocation.BandwidthRequested = 0
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 0,
Temporal: 0,
}
@@ -1026,15 +1026,15 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
BandwidthDelta: 2,
BandwidthNeeded: bitrates[2][1],
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 2.25,
}
result, boosted = f.AllocateNextHigher(100_000_000, nil, bitrates, false)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
require.True(t, boosted)
// no new available capacity cannot bump up layer
@@ -1044,15 +1044,15 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
BandwidthDelta: 2,
BandwidthNeeded: bitrates[2][1],
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: buffer.DefaultMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 2.25,
}
result, boosted = f.AllocateNextHigher(0, nil, bitrates, false)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
require.False(t, boosted)
// test allowOvershoot
@@ -1066,11 +1066,11 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
f.vls.SetCurrent(f.vls.GetTarget())
expectedTargetLayers = buffer.VideoLayer{
expectedTargetLayer = buffer.VideoLayer{
Spatial: 1,
Temporal: 0,
}
expectedMaxLayers := buffer.VideoLayer{
expectedMaxLayer := buffer.VideoLayer{
Spatial: 0,
Temporal: buffer.DefaultMaxLayerTemporal,
}
@@ -1078,16 +1078,16 @@ func TestForwarderAllocateNextHigher(t *testing.T) {
BandwidthRequested: bitrates[1][0],
BandwidthDelta: bitrates[1][0],
Bitrates: bitrates,
TargetLayers: expectedTargetLayers,
RequestLayerSpatial: expectedTargetLayers.Spatial,
MaxLayers: expectedMaxLayers,
TargetLayer: expectedTargetLayer,
RequestLayerSpatial: expectedTargetLayer.Spatial,
MaxLayer: expectedMaxLayer,
DistanceToDesired: -1.0,
}
// overshoot should return (1, 0) even if there is not enough capacity
result, boosted = f.AllocateNextHigher(bitrates[1][0]-1, nil, bitrates, true)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, expectedTargetLayers, f.TargetLayers())
require.Equal(t, expectedTargetLayer, f.TargetLayer())
require.True(t, boosted)
}
@@ -1116,15 +1116,15 @@ func TestForwarderPause(t *testing.T) {
BandwidthDelta: 0 - bitrates[0][0],
BandwidthNeeded: bitrates[2][3],
Bitrates: bitrates,
TargetLayers: buffer.InvalidLayers,
TargetLayer: buffer.InvalidLayer,
RequestLayerSpatial: buffer.InvalidLayerSpatial,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 3,
}
result := f.Pause(nil, bitrates)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, buffer.InvalidLayers, f.TargetLayers())
require.Equal(t, buffer.InvalidLayer, f.TargetLayer())
}
func TestForwarderPauseMute(t *testing.T) {
@@ -1150,15 +1150,15 @@ func TestForwarderPauseMute(t *testing.T) {
BandwidthRequested: 0,
BandwidthDelta: 0 - bitrates[0][0],
Bitrates: bitrates,
TargetLayers: buffer.InvalidLayers,
TargetLayer: buffer.InvalidLayer,
RequestLayerSpatial: buffer.InvalidLayerSpatial,
MaxLayers: buffer.DefaultMaxLayers,
MaxLayer: buffer.DefaultMaxLayer,
DistanceToDesired: 0,
}
result := f.Pause(nil, bitrates)
require.Equal(t, expectedResult, result)
require.Equal(t, expectedResult, f.lastAllocation)
require.Equal(t, buffer.InvalidLayers, f.TargetLayers())
require.Equal(t, buffer.InvalidLayer, f.TargetLayer())
}
func TestForwarderGetTranslationParamsMuted(t *testing.T) {
@@ -1765,7 +1765,7 @@ func TestForwardGetSnTsForPadding(t *testing.T) {
Spatial: 0,
Temporal: 1,
})
f.vls.SetCurrent(buffer.InvalidLayers)
f.vls.SetCurrent(buffer.InvalidLayer)
// send it through so that forwarder locks onto stream
_, _ = f.GetTranslationParams(extPkt, 0)
@@ -1832,7 +1832,7 @@ func TestForwardGetSnTsForBlankFrames(t *testing.T) {
Spatial: 0,
Temporal: 1,
})
f.vls.SetCurrent(buffer.InvalidLayers)
f.vls.SetCurrent(buffer.InvalidLayer)
// send it through so that forwarder locks onto stream
_, _ = f.GetTranslationParams(extPkt, 0)
@@ -1902,7 +1902,7 @@ func TestForwardGetPaddingVP8(t *testing.T) {
Spatial: 0,
Temporal: 1,
})
f.vls.SetCurrent(buffer.InvalidLayers)
f.vls.SetCurrent(buffer.InvalidLayer)
// send it through so that forwarder locks onto stream
_, _ = f.GetTranslationParams(extPkt, 0)

View File

@@ -396,12 +396,12 @@ func (s *StreamAllocator) OnSubscriptionChanged(downTrack *sfu.DownTrack) {
s.maybePostEventAllocateTrack(downTrack)
}
// called when subscribed layers changes (limiting max layers)
func (s *StreamAllocator) OnSubscribedLayersChanged(downTrack *sfu.DownTrack, layers buffer.VideoLayer) {
// called when subscribed layer changes (limiting max layer)
func (s *StreamAllocator) OnSubscribedLayerChanged(downTrack *sfu.DownTrack, layer buffer.VideoLayer) {
shouldPost := false
s.videoTracksMu.Lock()
if track := s.videoTracks[livekit.TrackID(downTrack.ID())]; track != nil {
if track.SetMaxLayers(layers) && track.SetDirty(true) {
if track.SetMaxLayer(layer) && track.SetDirty(true) {
shouldPost = true
}
}
@@ -941,12 +941,12 @@ func (s *StreamAllocator) allocateAllTracks() {
// 1. Stream as many tracks as possible, i.e. no pauses.
// 2. Try to give fair allocation to all track.
//
// Start with the lowest layers and give each track a chance at that layer and keep going up.
// As long as there is enough bandwidth for tracks to stream at the lowest layers, the first goal is achieved.
// Start with the lowest layer and give each track a chance at that layer and keep going up.
// As long as there is enough bandwidth for tracks to stream at the lowest layer, the first goal is achieved.
//
// Tracks that have higher subscribed layers can use any additional available bandwidth. This tried to achieve the second goal.
// Tracks that have higher subscribed layer can use any additional available bandwidth. This tried to achieve the second goal.
//
// If there is not enough bandwidth even for the lowest layers, tracks at lower priorities will be paused.
// If there is not enough bandwidth even for the lowest layer, tracks at lower priorities will be paused.
//
update := NewStreamStateUpdate()
@@ -1002,13 +1002,13 @@ func (s *StreamAllocator) allocateAllTracks() {
for spatial := int32(0); spatial <= buffer.DefaultMaxLayerSpatial; spatial++ {
for temporal := int32(0); temporal <= buffer.DefaultMaxLayerTemporal; temporal++ {
layers := buffer.VideoLayer{
layer := buffer.VideoLayer{
Spatial: spatial,
Temporal: temporal,
}
for _, track := range sorted {
usedChannelCapacity := track.ProvisionalAllocate(availableChannelCapacity, layers, s.params.Config.AllowPause, FlagAllowOvershootWhileDeficient)
usedChannelCapacity := track.ProvisionalAllocate(availableChannelCapacity, layer, s.params.Config.AllowPause, FlagAllowOvershootWhileDeficient)
availableChannelCapacity -= usedChannelCapacity
if availableChannelCapacity < 0 {
availableChannelCapacity = 0
@@ -1164,7 +1164,7 @@ func (s *StreamAllocator) maybeProbe() {
}
func (s *StreamAllocator) maybeProbeWithMedia() {
// boost deficient track farthest from desired layers
// boost deficient track farthest from desired layer
for _, track := range s.getMaxDistanceSortedDeficient() {
allocation, boosted := track.AllocateNextHigher(ChannelCapacityInfinity, FlagAllowOvershootInCatchup)
if !boosted {
@@ -1183,7 +1183,7 @@ func (s *StreamAllocator) maybeProbeWithMedia() {
}
func (s *StreamAllocator) maybeProbeWithPadding() {
// use deficient track farthest from desired layers to find how much to probe
// use deficient track farthest from desired layer to find how much to probe
for _, track := range s.getMaxDistanceSortedDeficient() {
transition, available := track.GetNextHigherTransition(FlagAllowOvershootInProbe)
if !available || transition.BandwidthDelta < 0 {

View File

@@ -16,7 +16,7 @@ type Track struct {
publisherID livekit.ParticipantID
logger logger.Logger
maxLayers buffer.VideoLayer
maxLayer buffer.VideoLayer
totalPackets uint32
totalRepeatedNacks uint32
@@ -42,7 +42,7 @@ func NewTrack(
isPaused: true,
}
t.SetPriority(0)
t.SetMaxLayers(downTrack.MaxLayers())
t.SetMaxLayer(downTrack.MaxLayer())
return t
}
@@ -103,12 +103,12 @@ func (t *Track) PublisherID() livekit.ParticipantID {
return t.publisherID
}
func (t *Track) SetMaxLayers(layers buffer.VideoLayer) bool {
if t.maxLayers == layers {
func (t *Track) SetMaxLayer(layer buffer.VideoLayer) bool {
if t.maxLayer == layer {
return false
}
t.maxLayers = layers
t.maxLayer = layer
return true
}
@@ -124,8 +124,8 @@ func (t *Track) ProvisionalAllocatePrepare() {
t.downTrack.ProvisionalAllocatePrepare()
}
func (t *Track) ProvisionalAllocate(availableChannelCapacity int64, layers buffer.VideoLayer, allowPause bool, allowOvershoot bool) int64 {
return t.downTrack.ProvisionalAllocate(availableChannelCapacity, layers, allowPause, allowOvershoot)
func (t *Track) ProvisionalAllocate(availableChannelCapacity int64, layer buffer.VideoLayer, allowPause bool, allowOvershoot bool) int64 {
return t.downTrack.ProvisionalAllocate(availableChannelCapacity, layer, allowPause, allowOvershoot)
}
func (t *Track) ProvisionalAllocateGetCooperativeTransition(allowOvershoot bool) sfu.VideoTransition {
@@ -197,11 +197,11 @@ func (t TrackSorter) Less(i, j int) bool {
return t[i].priority > t[j].priority
}
if t[i].maxLayers.Spatial != t[j].maxLayers.Spatial {
return t[i].maxLayers.Spatial > t[j].maxLayers.Spatial
if t[i].maxLayer.Spatial != t[j].maxLayer.Spatial {
return t[i].maxLayer.Spatial > t[j].maxLayer.Spatial
}
return t[i].maxLayers.Temporal > t[j].maxLayers.Temporal
return t[i].maxLayer.Temporal > t[j].maxLayer.Temporal
}
// ------------------------------------------------

View File

@@ -295,12 +295,12 @@ func (s *StreamTrackerManager) DistanceToDesired() float64 {
al, brs := s.getLayeredBitrateLocked()
maxLayers := buffer.InvalidLayers
maxLayer := buffer.InvalidLayer
done:
for s := int32(len(brs)) - 1; s >= 0; s-- {
for t := int32(len(brs[0])) - 1; t >= 0; t-- {
if brs[s][t] != 0 {
maxLayers = buffer.VideoLayer{
maxLayer = buffer.VideoLayer{
Spatial: s,
Temporal: t,
}
@@ -311,21 +311,21 @@ done:
// before bit rate measurement is available, stream tracker could declare layer seen, account for that
for _, layer := range al {
if layer > maxLayers.Spatial {
maxLayers.Spatial = layer
maxLayers.Temporal = s.maxTemporalLayerSeen // till bit rate measurement is available, assume max seen as temporal
if layer > maxLayer.Spatial {
maxLayer.Spatial = layer
maxLayer.Temporal = s.maxTemporalLayerSeen // till bit rate measurement is available, assume max seen as temporal
}
}
adjustedMaxLayers := maxLayers
if !maxLayers.IsValid() {
adjustedMaxLayers := maxLayer
if !maxLayer.IsValid() {
adjustedMaxLayers = buffer.VideoLayer{Spatial: 0, Temporal: 0}
}
distance :=
((s.maxExpectedLayer - adjustedMaxLayers.Spatial) * (s.maxTemporalLayerSeen + 1)) +
(s.maxTemporalLayerSeen - adjustedMaxLayers.Temporal)
if !maxLayers.IsValid() {
if !maxLayer.IsValid() {
distance++
}

View File

@@ -24,12 +24,12 @@ type Base struct {
func NewBase(logger logger.Logger) *Base {
return &Base{
logger: logger,
maxLayer: buffer.InvalidLayers,
targetLayer: buffer.InvalidLayers, // start off with nothing, let streamallocator/opportunistic forwarder set the target
maxLayer: buffer.InvalidLayer,
targetLayer: buffer.InvalidLayer, // start off with nothing, let streamallocator/opportunistic forwarder set the target
requestSpatial: buffer.InvalidLayerSpatial,
maxSeenLayer: buffer.InvalidLayers,
parkedLayer: buffer.InvalidLayers,
currentLayer: buffer.InvalidLayers,
maxSeenLayer: buffer.InvalidLayer,
parkedLayer: buffer.InvalidLayer,
currentLayer: buffer.InvalidLayer,
}
}

View File

@@ -89,7 +89,7 @@ func (s *Simulcast) Select(extPkt *buffer.ExtPacket, layer int32) (result VideoL
if !isActive {
result.IsResuming = true
}
s.SetParked(buffer.InvalidLayers)
s.SetParked(buffer.InvalidLayer)
if s.currentLayer.Spatial >= s.maxLayer.Spatial {
result.IsSwitchingToMaxSpatial = true