// 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 }