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

258 lines
6.8 KiB
Go

4 years ago
// 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 (
"bytes"
"fmt"
4 years ago
"testing"
"github.com/q191201771/lal/pkg/base"
"github.com/q191201771/naza/pkg/assert"
"github.com/q191201771/naza/pkg/nazalog"
)
var (
diffA = uint32(23)
diffV = uint32(40)
)
var golden = []base.AVPacket{
4 years ago
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++ {
4 years ago
in = append(in, a(i*diffA))
}
oneCase(t, in, in[:len(in)-1])
// case. 只有视频,且数量大于队列容量,只是为了测试覆盖率
in = nil
for i := uint32(0); i <= maxQueueSize; i++ {
4 years ago
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{
4 years ago
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) ]
4 years ago
ab := uint32(4294967295 - diffA*3) // max 4294967295
vb := uint32(66666)
in = []base.AVPacket{
4 years ago
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)},
4 years ago
{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)
4 years ago
vb = uint32(4294967295 - diffV*2) // max 4294967295
in = []base.AVPacket{
4 years ago
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)},
4 years ago
{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{
4 years ago
PayloadType: base.AVPacketPTAAC,
Timestamp: t,
}
}
func v(t uint32) base.AVPacket {
return base.AVPacket{
4 years ago
PayloadType: base.AVPacketPTAVC,
Timestamp: t,
}
}
func oneCase(t *testing.T, in []base.AVPacket, expected []base.AVPacket) (out []base.AVPacket, q *AVPacketQueue) {
4 years ago
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
}