mirror of
https://github.com/livekit/livekit.git
synced 2026-08-28 13:54:34 +00:00
Merge remote-tracking branch 'origin/master' into raja_min_packets
This commit is contained in:
@@ -883,9 +883,15 @@ func (s *StreamAllocator) allocateTrack(track *Track) {
|
||||
return
|
||||
}
|
||||
|
||||
// this track is currently not streaming and needs bits to start.
|
||||
// first try an allocation using available headroom
|
||||
availableChannelCapacity := s.getAvailableHeadroom(false)
|
||||
// already streaming at some layer and transition is not requesting any change, i. e. BandwidthDelta == 0
|
||||
if transition.From.IsValid() && transition.BandwidthDelta == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// this track is currently not streaming and needs bits to start OR streaming at some layer and wants more bits.
|
||||
// NOTE: With co-operative transition, tracks should not be asking for more if already streaming, but handle that case any way.
|
||||
// first try an allocation using available headroom, current consumption of this track is discounted to calculate headroom.
|
||||
availableChannelCapacity := s.getAvailableHeadroomWithoutTracks(false, []*Track{track})
|
||||
if availableChannelCapacity > 0 {
|
||||
track.ProvisionalAllocateReset() // to reset allocation from co-operative transition above and try fresh
|
||||
|
||||
@@ -899,21 +905,30 @@ func (s *StreamAllocator) allocateTrack(track *Track) {
|
||||
Temporal: temporal,
|
||||
}
|
||||
|
||||
usedChannelCapacity := track.ProvisionalAllocate(availableChannelCapacity, layer, s.allowPause, FlagAllowOvershootWhileDeficient)
|
||||
isCandidate, usedChannelCapacity := track.ProvisionalAllocate(
|
||||
availableChannelCapacity,
|
||||
layer,
|
||||
s.allowPause,
|
||||
FlagAllowOvershootWhileDeficient,
|
||||
)
|
||||
if availableChannelCapacity < usedChannelCapacity {
|
||||
break alloc_loop
|
||||
}
|
||||
|
||||
bestLayer = layer
|
||||
if isCandidate {
|
||||
bestLayer = layer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if bestLayer.IsValid() {
|
||||
// found layer that can fit in available headroom
|
||||
update := NewStreamStateUpdate()
|
||||
allocation := track.ProvisionalAllocateCommit()
|
||||
updateStreamStateChange(track, allocation, update)
|
||||
s.maybeSendUpdate(update)
|
||||
if bestLayer.GreaterThan(transition.From) {
|
||||
// found layer that can fit in available headroom, take it if it is better than existing
|
||||
update := NewStreamStateUpdate()
|
||||
allocation := track.ProvisionalAllocateCommit()
|
||||
updateStreamStateChange(track, allocation, update)
|
||||
s.maybeSendUpdate(update)
|
||||
}
|
||||
|
||||
s.adjustState()
|
||||
return
|
||||
@@ -923,11 +938,6 @@ func (s *StreamAllocator) allocateTrack(track *Track) {
|
||||
transition = track.ProvisionalAllocateGetCooperativeTransition(FlagAllowOvershootWhileDeficient) // get transition again to reset above allocation attempt using available headroom
|
||||
}
|
||||
|
||||
// track is currently streaming at minimum
|
||||
if transition.BandwidthDelta == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// if there is not enough headroom, try to redistribute starting with tracks that are closest to their desired.
|
||||
bandwidthAcquired := int64(0)
|
||||
var contributingTracks []*Track
|
||||
@@ -1018,17 +1028,31 @@ func (s *StreamAllocator) maybeBoostDeficientTracks() {
|
||||
|
||||
update := NewStreamStateUpdate()
|
||||
|
||||
for _, track := range s.getMaxDistanceSortedDeficient() {
|
||||
allocation, boosted := track.AllocateNextHigher(availableChannelCapacity, FlagAllowOvershootInCatchup)
|
||||
if !boosted {
|
||||
continue
|
||||
sortedTracks := s.getMaxDistanceSortedDeficient()
|
||||
boost_loop:
|
||||
for {
|
||||
for idx, track := range sortedTracks {
|
||||
allocation, boosted := track.AllocateNextHigher(availableChannelCapacity, FlagAllowOvershootInCatchup)
|
||||
if !boosted {
|
||||
if idx == len(sortedTracks)-1 {
|
||||
// all tracks tried
|
||||
break boost_loop
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
updateStreamStateChange(track, allocation, update)
|
||||
|
||||
availableChannelCapacity -= allocation.BandwidthDelta
|
||||
if availableChannelCapacity <= 0 {
|
||||
break boost_loop
|
||||
}
|
||||
|
||||
break // sort again below as the track that was just boosted could still be farthest from its desired
|
||||
}
|
||||
|
||||
updateStreamStateChange(track, allocation, update)
|
||||
|
||||
availableChannelCapacity -= allocation.BandwidthDelta
|
||||
if availableChannelCapacity <= 0 {
|
||||
break
|
||||
sortedTracks = s.getMaxDistanceSortedDeficient()
|
||||
if len(sortedTracks) == 0 {
|
||||
break // nothing available to boost
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1103,7 +1127,7 @@ func (s *StreamAllocator) allocateAllTracks() {
|
||||
}
|
||||
|
||||
for _, track := range sorted {
|
||||
usedChannelCapacity := track.ProvisionalAllocate(availableChannelCapacity, layer, s.allowPause, FlagAllowOvershootWhileDeficient)
|
||||
_, usedChannelCapacity := track.ProvisionalAllocate(availableChannelCapacity, layer, s.allowPause, FlagAllowOvershootWhileDeficient)
|
||||
availableChannelCapacity -= usedChannelCapacity
|
||||
if availableChannelCapacity < 0 {
|
||||
availableChannelCapacity = 0
|
||||
@@ -1174,10 +1198,32 @@ func (s *StreamAllocator) getExpectedBandwidthUsage() int64 {
|
||||
return expected
|
||||
}
|
||||
|
||||
func (s *StreamAllocator) getExpectedBandwidthUsageWithoutTracks(filteredTracks []*Track) int64 {
|
||||
expected := int64(0)
|
||||
for _, track := range s.getTracks() {
|
||||
filtered := false
|
||||
for _, ft := range filteredTracks {
|
||||
if ft == track {
|
||||
filtered = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !filtered {
|
||||
expected += track.BandwidthRequested()
|
||||
}
|
||||
}
|
||||
|
||||
return expected
|
||||
}
|
||||
|
||||
func (s *StreamAllocator) getAvailableHeadroom(allowOverride bool) int64 {
|
||||
return s.getAvailableChannelCapacity(allowOverride) - s.getExpectedBandwidthUsage()
|
||||
}
|
||||
|
||||
func (s *StreamAllocator) getAvailableHeadroomWithoutTracks(allowOverride bool, filteredTracks []*Track) int64 {
|
||||
return s.getAvailableChannelCapacity(allowOverride) - s.getExpectedBandwidthUsageWithoutTracks(filteredTracks)
|
||||
}
|
||||
|
||||
func (s *StreamAllocator) getNackDelta() (uint32, uint32) {
|
||||
aggPacketDelta := uint32(0)
|
||||
aggRepeatedNackDelta := uint32(0)
|
||||
|
||||
@@ -164,7 +164,7 @@ func (t *Track) ProvisionalAllocateReset() {
|
||||
t.downTrack.ProvisionalAllocateReset()
|
||||
}
|
||||
|
||||
func (t *Track) ProvisionalAllocate(availableChannelCapacity int64, layer buffer.VideoLayer, allowPause bool, allowOvershoot bool) int64 {
|
||||
func (t *Track) ProvisionalAllocate(availableChannelCapacity int64, layer buffer.VideoLayer, allowPause bool, allowOvershoot bool) (bool, int64) {
|
||||
return t.downTrack.ProvisionalAllocate(availableChannelCapacity, layer, allowPause, allowOvershoot)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user