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

250 lines
6.3 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.

package rtsp
import (
"bytes"
"fmt"
"github.com/q191201771/lal/pkg/base"
"github.com/q191201771/naza/pkg/assert"
"github.com/q191201771/naza/pkg/nazalog"
"testing"
)
var (
diffA = uint32(23)
diffV = uint32(40)
)
var golden = []base.AVPacket{
v(0), // 注意一个小细节,音频视频相等时,视频先输出
a(0),
a(23),
v(40),
a(46),
a(69),
v(80),
a(92),
a(115),
v(120),
}
func TestAVPacketQueue(t *testing.T) {
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{
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{
a(ab), // 0: 0
v(vb), // 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), v(0)},
{v(0), a(0), a(diffA), v(diffV), a(diffA*2), a(diffA*3), v(diffV*2), v(0)},
{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)},
}
for i := 0; i < len(in); i++ {
out, q := oneCase(t, in[:i+1], expects[i])
nazalog.Infof("-----%d", i)
nazalog.Infof("i:%s", packetsReadable(in[:i+1]))
nazalog.Infof("o:%s", packetsReadable(out))
nazalog.Infof("e:%s", packetsReadable(expects[i]))
nazalog.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 a(t uint32) base.AVPacket {
return base.AVPacket{
PayloadType:base.AVPacketPTAAC,
Timestamp:t,
}
}
func v(t uint32) base.AVPacket {
return base.AVPacket{
PayloadType:base.AVPacketPTAVC,
Timestamp:t,
}
}
func oneCase(t *testing.T, in []base.AVPacket, expected []base.AVPacket) (out []base.AVPacket, q *AVPacketQueue) {
out, q = calc(in)
assert.Equal(t, expected, out)
return out, q
}
func calc(in []base.AVPacket) (out []base.AVPacket, q *AVPacketQueue) {
q = NewAVPacketQueue(func(pkt base.AVPacket) {
out = append(out, pkt)
})
for _, pkt := range in {
q.Feed(pkt)
}
return out, q
}
func packetsReadable(pkts []base.AVPacket) string {
var buf bytes.Buffer
buf.WriteString("[")
for _, pkt := range pkts {
if pkt.PayloadType == base.AVPacketPTAAC {
buf.WriteString(fmt.Sprintf(" A(%d) ", pkt.Timestamp))
} else {
buf.WriteString(fmt.Sprintf(" V(%d) ", pkt.Timestamp))
}
}
buf.WriteString("]")
return buf.String()
}
func peekQueuePackets(q *AVPacketQueue) []base.AVPacket {
var out []base.AVPacket
for i := 0; i < q.audioQueue.Size(); i++ {
pkt, _ := q.audioQueue.At(i)
ppkt := pkt.(base.AVPacket)
out = append(out, ppkt)
}
for i := 0; i < q.videoQueue.Size(); i++ {
pkt, _ := q.videoQueue.At(i)
ppkt := pkt.(base.AVPacket)
out = append(out, ppkt)
}
return out
}