snapshot of https://github.com/livekit/livekit.git @ 08c5433449c106943231037d0b892895f6e92d3b (2026-09-15)
This commit is contained in:
108
pkg/sfu/videolayerselector/framenumberwrapper_test.go
Normal file
108
pkg/sfu/videolayerselector/framenumberwrapper_test.go
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright 2024 LiveKit, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package videolayerselector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"math/rand"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/livekit/mediatransportutil/pkg/utils"
|
||||
"github.com/livekit/protocol/logger"
|
||||
)
|
||||
|
||||
func TestFrameNumberWrapper(t *testing.T) {
|
||||
|
||||
logger.InitFromConfig(&logger.Config{Level: "debug"}, t.Name())
|
||||
|
||||
fnWrap := &FrameNumberWrapper{logger: logger.GetLogger()}
|
||||
|
||||
fnWrapAround := utils.NewWrapAround[uint16, uint64](utils.WrapAroundParams{IsRestartAllowed: false})
|
||||
|
||||
firstF := uint16(1000)
|
||||
|
||||
testFrameOrder := func(frame uint16, isKeyFrame bool, frame2 uint16, isKeyFrame2, expectInorder bool) {
|
||||
frameUnwrap := fnWrapAround.Update(frame).ExtendedVal
|
||||
wrappedFrame := uint16(fnWrap.UpdateAndGet(frameUnwrap, isKeyFrame))
|
||||
|
||||
// make sure wrap around always get in order frame number
|
||||
fnWrapAround.Update(frame + (frame2-frame)/2)
|
||||
|
||||
frame2Unwrap := fnWrapAround.Update(frame2).ExtendedVal
|
||||
wrappedFrame2 := uint16(fnWrap.UpdateAndGet(frame2Unwrap, isKeyFrame2))
|
||||
// keeps order
|
||||
require.Equal(t, expectInorder, inOrder(wrappedFrame2, wrappedFrame), "frame %d, frame2 %d, wrappedFrame %d, wrapped Frame2 %d, frameUnwrap %d, frame2Unwrap %d", frame, frame2, wrappedFrame, wrappedFrame2, frameUnwrap, frame2Unwrap)
|
||||
// frame number diff should be the same if frame2 is not a key frame
|
||||
if !isKeyFrame2 {
|
||||
require.Equal(t, frame2-frame, wrappedFrame2-wrappedFrame)
|
||||
}
|
||||
}
|
||||
|
||||
secondF := getFrame(firstF, true)
|
||||
testFrameOrder(firstF, true, secondF, false, true)
|
||||
|
||||
// non key frame keeps diff and order
|
||||
for i := 0; i < 100; i++ {
|
||||
// frame in order
|
||||
firstF = secondF
|
||||
secondF = getFrame(firstF, true)
|
||||
testFrameOrder(firstF, false, secondF, false, true)
|
||||
|
||||
// frame out of order
|
||||
firstF = secondF
|
||||
secondF = getFrame(firstF, false)
|
||||
// it is possible that an out of order non-keyframe has been converted to in order frame number if the diff is 32768
|
||||
// that is ok because the client can't decode in such case and always need to wait for the key frame.
|
||||
// so it is just a failure of test case and increase the frame number here.
|
||||
if secondF-firstF == 0x8000 {
|
||||
secondF++
|
||||
}
|
||||
testFrameOrder(firstF, false, secondF, false, false)
|
||||
|
||||
// key frame in order
|
||||
firstF = secondF
|
||||
secondF = getFrame(firstF, true)
|
||||
testFrameOrder(firstF, false, secondF, true, true)
|
||||
|
||||
// frame in order
|
||||
firstF = secondF
|
||||
secondF = getFrame(firstF, true)
|
||||
testFrameOrder(firstF, false, secondF, false, true)
|
||||
|
||||
// key frame out of order but should be in order after wrap around
|
||||
firstF = secondF
|
||||
secondF = getFrame(firstF, false)
|
||||
testFrameOrder(firstF, false, secondF, true, true)
|
||||
}
|
||||
}
|
||||
|
||||
func inOrder(a, b uint16) bool {
|
||||
return a-b < 0x8000 || (a-b == 0x8000 && a > b)
|
||||
}
|
||||
|
||||
func getFrame(base uint16, inorder bool) uint16 {
|
||||
if inorder {
|
||||
return base + uint16(rand.Intn(0x8000))
|
||||
}
|
||||
|
||||
for {
|
||||
ret := base + uint16(rand.Intn(0x8000)) + 0x8000
|
||||
if !inOrder(ret, base) {
|
||||
return ret
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user