You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lal/pkg/rtsp/avpacket_queue_test.go

345 lines
8.7 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// Copyright 2021, Chef. All rights reserved.
// https://github.com/q191201771/lal
//
// Use of this source code is governed by a MIT-style license
// that can be found in the License file.
//
// Author: Chef (191201771@qq.com)
package rtsp
import (
"github.com/q191201771/naza/pkg/nazalog"
"testing"
"github.com/q191201771/lal/pkg/base"
"github.com/q191201771/naza/pkg/assert"
)
func TestAvPacketQueue(t *testing.T) {
// TODO(chef): 检查该测试函数中TimestampFilterHandleRotateFlag为true的情况下的bad case 202305
tfhrf := TimestampFilterHandleRotateFlag
defer func() {
TimestampFilterHandleRotateFlag = tfhrf
}()
TimestampFilterHandleRotateFlag = false
var golden = []base.AvPacket{
a(0),
v(0),
a(23),
v(40),
a(46),
a(69),
v(80),
a(92),
a(115),
v(120),
}
var (
diffA = uint32(23)
diffV = uint32(40)
)
var in []base.AvPacket
// case. 只有音频,且数量小于队列容量
oneCase(t, []base.AvPacket{
a(1),
}, nil)
// case. 只有音频,且数量大于队列容量
in = nil
for i := uint32(0); i <= maxQueueSize; i++ {
in = append(in, a(i*diffA))
}
oneCase(t, in, in[:len(in)-1])
// case. 只有视频,且数量大于队列容量,只是为了测试覆盖率
in = nil
for i := uint32(0); i <= maxQueueSize; i++ {
in = append(in, v(i*diffV))
}
oneCase(t, in, in[:len(in)-1])
// case. 最正常的数据
oneCase(t, golden, golden[:len(golden)-1])
// case. 音频和视频之间不完全有序
oneCase(t, []base.AvPacket{
a(0),
a(23),
a(46),
a(69),
v(0),
v(40),
v(80),
v(120),
a(92),
a(115),
}, golden[:len(golden)-1])
// case. 起始非0且起始不对齐
in = nil
for _, pkt := range golden {
pkt2 := pkt
if pkt2.PayloadType == base.AvPacketPtAac {
pkt2.Timestamp += 100
} else {
pkt2.Timestamp += 10000
}
in = append(in, pkt2)
}
oneCase(t, in, golden[:len(golden)-1])
// case. 起始非0且起始不对齐且乱序
oneCase(t, []base.AvPacket{
a(0 + 99),
a(23 + 99),
a(46 + 99),
a(69 + 99),
v(0 + 1234),
v(40 + 1234),
v(80 + 1234),
v(120 + 1234),
a(92 + 99),
a(115 + 99),
}, golden[:len(golden)-1])
// case.
oneCase(t, []base.AvPacket{
a(4294967293),
v(4294967294),
a(4294967295),
}, []base.AvPacket{
a(0),
v(0),
})
// case. 翻转1
// i:[ A(4294967226) V(66666) A(4294967249) V(66706) A(4294967272) A(4294967295) V(66746) A(22) A(45) V(66786) A(68) V(66826) ]
// o:[ V(0) A(0) A(23) V(40) A(46) A(69) V(80) V(0) A(0) A(23) V(40) ]
// q:[ A(46) ]
ab := uint32(4294967295 - diffA*3) // max 4294967295
vb := uint32(66666)
in = []base.AvPacket{
v(vb), // 0
a(ab), // 0: 0
a(ab + diffA), // 23
v(vb + diffV), // 40
a(ab + diffA*2), // 46
a(ab + diffA*3), // 69
v(vb + diffV*2), // 80
a(ab + diffA*4), // 92 rotate
a(ab + diffA*5), // 115 -> 23
v(vb + diffV*3), // 120 -> 0
a(ab + diffA*6), // 138
v(vb + diffV*4), // 160
}
expects := [][]base.AvPacket{
nil,
{v(0)},
{v(0)},
{v(0), a(0), a(diffA)},
{v(0), a(0), a(diffA), v(diffV)},
{v(0), a(0), a(diffA), v(diffV)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2), a(0), v(0)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2), a(0), v(0)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2), a(0), v(0), a(diffA), v(diffV)},
}
for i := 0; i < len(in); i++ {
out, q := oneCase(t, in[:i+1], expects[i])
Log.Infof("-----%d", i)
Log.Infof("i:%s", packetsReadable(in[:i+1]))
Log.Infof("o:%s", packetsReadable(out))
Log.Infof("e:%s", packetsReadable(expects[i]))
Log.Infof("q:%s", packetsReadable(peekQueuePackets(q)))
}
// case. 翻转2
// i:[ V(4294967215) A(12345) A(12368) V(4294967255) A(12391) A(12414) V(4294967295) A(12437) A(12460) V(39) A(12483) V(79) A(12506) A(12529) ]
// o:[ V(0) A(0) A(23) V(40) A(46) A(69) V(80) A(92) A(115) V(0) A(0) A(23) V(40) ]
// q:[ A(46) ]
ab = uint32(12345)
vb = uint32(4294967295 - diffV*2) // max 4294967295
in = []base.AvPacket{
v(vb), // 0
a(ab), // 0
a(ab + diffA), // 23
v(vb + diffV), // 40
a(ab + diffA*2), // 46
a(ab + diffA*3), // 69
v(vb + diffV*2), // 80
a(ab + diffA*4), // 92
a(ab + diffA*5), // 115
v(vb + diffV*3), // 120 rotate
a(ab + diffA*6), // 138 -> 0
v(vb + diffV*4), // 160 -> 40
a(ab + diffA*7), // 161
a(ab + diffA*8), // 184
}
expects = [][]base.AvPacket{
nil,
{v(0)},
{v(0)},
{v(0), a(0), a(diffA)},
{v(0), a(0), a(diffA), v(diffV)},
{v(0), a(0), a(diffA), v(diffV)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2), a(diffA * 4), a(diffA * 5)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2), a(diffA * 4), a(diffA * 5), v(0)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2), a(diffA * 4), a(diffA * 5), v(0), a(0)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2), a(diffA * 4), a(diffA * 5), v(0), a(0), a(diffA)},
{v(0), a(0), a(diffA), v(diffV), a(diffA * 2), a(diffA * 3), v(diffV * 2), a(diffA * 4), a(diffA * 5), v(0), a(0), a(diffA), v(diffV)},
}
for i := 0; i < len(in); i++ {
oneCase(t, in[:i+1], expects[i])
}
}
func TestAvPacketQueue__Rotate(t *testing.T) {
tfhrf := TimestampFilterHandleRotateFlag
defer func() {
TimestampFilterHandleRotateFlag = tfhrf
}()
in := []base.AvPacket{
v(4294564),
v(4294604),
v(4294644),
v(4294684),
v(4294724),
v(4294764),
v(4294804),
v(4294844),
a(4294756), // [old] out V4294564 4294604 4294644 4294684, A4294756
v(4294884),
v(4294924),
v(4294924),
v(4294924),
v(4294964),
v(37), // [old] rotate, out all, except V37
a(4294916), // [old] out V37
v(77), // [old] out A4294916
v(117),
v(157),
v(197),
a(109), // [old] rotate, out all, except A109
v(237), // [old] out A109
v(277),
v(317),
v(357),
a(269), // [old] out V237 277 317 357
v(397), // [old] out A269
}
audioBase := uint32(2551917)
videoBase := uint32(2551884)
expectedOld := []base.AvPacket{
v(4294564 - videoBase),
v(4294604 - videoBase),
v(4294644 - videoBase),
v(4294684 - videoBase),
a(4294756 - audioBase),
v(4294724 - videoBase),
v(4294764 - videoBase),
v(4294804 - videoBase),
v(4294844 - videoBase),
v(4294884 - videoBase),
v(4294924 - videoBase),
v(4294924 - videoBase),
v(4294924 - videoBase),
v(4294964 - videoBase),
v(37 - 37),
a(4294916 - 4294916),
v(77 - 37),
v(117 - 37),
v(157 - 37),
v(197 - 37),
a(109 - 109),
v(237 - 237),
v(277 - 237),
v(317 - 237),
v(357 - 237),
a(269 - 109),
}
expectedNew := []base.AvPacket{
v(0), a(0), v(40), v(80), v(120), v(160), a(160), v(200), v(240), v(280), v(320), a(320), v(360), v(360), v(360), v(400), v(440), v(480), a(480),
}
_ = expectedOld
//TimestampFilterHandleRotateFlag = false
// oneCaseWithHackBase(t, in, expectedOld, int64(audioBase), int64(videoBase))
TimestampFilterHandleRotateFlag = true
oneCaseWithHackBase(t, in, expectedNew, int64(audioBase), int64(videoBase))
}
// ---------------------------------------------------------------------------------------------------------------------
func a(t uint32) base.AvPacket {
return base.AvPacket{
PayloadType: base.AvPacketPtAac,
Timestamp: int64(t),
}
}
func v(t uint32) base.AvPacket {
return base.AvPacket{
PayloadType: base.AvPacketPtAvc,
Timestamp: int64(t),
}
}
func oneCaseWithHackBase(t *testing.T, in []base.AvPacket, expected []base.AvPacket, audioBase, videoBase int64) (out []base.AvPacket, q *AvPacketQueue) {
out, q = calc(in, audioBase, videoBase)
nazalog.Debugf("in: %s", packetsReadable(in))
nazalog.Debugf("exp: %s", packetsReadable(expected))
nazalog.Debugf("out: %s", packetsReadable(out))
nazalog.Debugf("remain: %s", packetsReadable(peekQueuePackets(q)))
assert.Equal(t, expected, out)
return out, q
}
func oneCase(t *testing.T, in []base.AvPacket, expected []base.AvPacket) (out []base.AvPacket, q *AvPacketQueue) {
return oneCaseWithHackBase(t, in, expected, -1, -1)
}
func calc(in []base.AvPacket, audioBase, videoBase int64) (out []base.AvPacket, q *AvPacketQueue) {
q = NewAvPacketQueue(func(pkt base.AvPacket) {
out = append(out, pkt)
})
q.audioBaseTs = audioBase
q.videoBaseTs = videoBase
for _, pkt := range in {
q.Feed(pkt)
}
return out, q
}