diff --git a/pkg/logic/gop_cache.go b/pkg/logic/gop_cache.go index db3b922..3bbdbfc 100644 --- a/pkg/logic/gop_cache.go +++ b/pkg/logic/gop_cache.go @@ -58,14 +58,20 @@ type GOPCache struct { Metadata []byte VideoSeqHeader []byte AACSeqHeader []byte - gopCircularQue *gopCircularQueue + gopRing []GOP + gopRingFirst int + gopRingLast int + gopSize int } func NewGopCache(t string, uniqueKey string, gopNum int) *GOPCache { return &GOPCache{ t: t, uniqueKey: uniqueKey, - gopCircularQue: NewGopCircularQueue(gopNum), + gopSize: gopNum + 1, + gopRing: make([]GOP, gopNum + 1, gopNum + 1), + gopRingFirst: 0, + gopRingLast: 0, } } @@ -90,44 +96,47 @@ func (gc *GOPCache) Feed(msg rtmp.AVMsg, lg LazyGet) { return } } - if gc.gopCircularQue.Cap() != 0 { + + if gc.gopSize > 1 { if msg.IsVideoKeyNalu() { - var gop *GOP - if gc.gopCircularQue.Full() { - //如果已经满了,获取队首即将被淘汰的GOP - gop = gc.gopCircularQue.Front() - gop.Clear() - } else { - gop = &GOP{} + gc.gopRing[gc.gopRingLast].Clear() + gc.gopRing[gc.gopRingLast].Feed(msg, lg()) + gc.gopRingLast = (gc.gopRingLast + 1) % gc.gopSize + if gc.gopRingLast == gc.gopRingFirst { + gc.gopRingFirst = (gc.gopRingFirst + 1) % gc.gopSize } - gop.Feed(msg, lg()) - gc.gopCircularQue.Enqueue(gop) } else { - gop := gc.gopCircularQue.Back() - if gop != nil { - gop.Feed(msg, lg()) + if gc.gopRingLast != gc.gopRingFirst { + gc.gopRing[(gc.gopRingLast - 1 + gc.gopSize) % gc.gopSize].Feed(msg, lg()) } } } } func (gc *GOPCache) GetGopLen() int{ - return gc.gopCircularQue.Len() + return (gc.gopRingLast + gc.gopSize - gc.gopRingFirst) % gc.gopSize } -func (gc *GOPCache) GetGopAt(pos int) *GOP { - return gc.gopCircularQue.At(pos) +func (gc *GOPCache) GetGopDataAt(pos int) [][]byte { + if pos >= gc.GetGopLen() || pos < 0 { + return nil + } + return gc.gopRing[(pos + gc.gopRingFirst) % gc.gopSize].data } func (gc *GOPCache) LastGOP() *GOP { - return gc.gopCircularQue.Back() + if gc.GetGopLen() == 0 { + return nil + } + return &gc.gopRing[(gc.gopRingLast - 1 + gc.gopSize) % gc.gopSize] } func (gc *GOPCache) Clear() { gc.Metadata = nil gc.VideoSeqHeader = nil gc.AACSeqHeader = nil - gc.gopCircularQue.Clear() + gc.gopRingLast = 0 + gc.gopRingFirst = 0 } type GOP struct { @@ -141,102 +150,3 @@ func (g *GOP) Feed(msg rtmp.AVMsg, b []byte) { func (g *GOP) Clear() { g.data = g.data[:0] } - -type gopCircularQueue struct { - buf []*GOP - size int - first int - last int -} - -func NewGopCircularQueue(cap int) *gopCircularQueue { - if cap < 0 { - panic("negative cap argument in NewGopCircularQueue") - } - - size := cap + 1 - return &gopCircularQueue{ - buf: make([]*GOP, size, size), - size: size, - first: 0, - last: 0, - } -} - -//Enqueue 入队 -func (gcq *gopCircularQueue) Enqueue(gop *GOP) { - if gcq.Full() { - //队列满了,抛弃队首元素 - gcq.firstInc() - } - gcq.buf[gcq.last] = gop - gcq.lastInc() -} - -//Dequeue 队首元素出队 -func (gcq *gopCircularQueue) Dequeue() *GOP{ - if gcq.Empty() { - return nil - } - - //把first return - gop := gcq.buf[gcq.first] - gcq.firstInc() - - return gop -} - -func (gcq *gopCircularQueue) Full() bool { - return (gcq.last + 1) % gcq.size == gcq.first -} - -func (gcq *gopCircularQueue) Empty() bool{ - return gcq.first == gcq.last -} - -//Len 获取元素的个数 -func (gcq *gopCircularQueue) Len() int{ - return (gcq.last + gcq.size - gcq.first) % gcq.size -} - -//Cap 获取队列的容量 -func (gcq *gopCircularQueue) Cap() int { - return gcq.size - 1 -} - -//Front 获取队首元素,不出队 -func (gcq *gopCircularQueue) Front() *GOP { - if gcq.Empty() { - return nil - } - return gcq.buf[gcq.first] -} - -//Back 获取队尾元素,不出队 -func (gcq *gopCircularQueue) Back() *GOP { - if gcq.Empty() { - return nil - } - return gcq.buf[(gcq.last + gcq.size - 1) % gcq.size] -} - -//At 获取第pos个元素 -func (gcq *gopCircularQueue) At(pos int) *GOP { - if pos >= gcq.Len() || pos < 0 { - return nil - } - return gcq.buf[(pos + gcq.first) % gcq.size] -} - -func (gcq *gopCircularQueue) Clear() { - gcq.first = 0 - gcq.last = 0 -} - -func (gcq *gopCircularQueue) lastInc() { - gcq.last = (gcq.last + 1) % gcq.size -} - -func (gcq *gopCircularQueue) firstInc() { - gcq.first = (gcq.first + 1) % gcq.size -} diff --git a/pkg/logic/gop_cache_test.go b/pkg/logic/gop_cache_test.go index da9a1aa..cd97a8a 100644 --- a/pkg/logic/gop_cache_test.go +++ b/pkg/logic/gop_cache_test.go @@ -1,371 +1,113 @@ package logic import ( - `github.com/q191201771/naza/pkg/assert` - `testing` + "github.com/q191201771/lal/pkg/rtmp" + "github.com/q191201771/naza/pkg/assert" + "testing" ) -func TestGopCircularQueueCap0(t *testing.T) { - var gcqCap int = 0 - - gcq := NewGopCircularQueue(gcqCap) - - //fl - assert.Equal(t, true, gcq.Empty()) - assert.Equal(t, true, gcq.Full()) - assert.Equal(t, 0, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.Front()) - assert.Equal(t, nil, gcq.Back()) - assert.Equal(t, nil, gcq.Dequeue()) - - - //fl - tGOP := &GOP{ - data:nil, - } - gcq.Enqueue(tGOP) - //fg - assert.Equal(t, true, gcq.Empty()) - assert.Equal(t, true, gcq.Full()) - assert.Equal(t, 0, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.Front()) - assert.Equal(t, nil, gcq.Back()) - - - //弹出一个后 - assert.Equal(t, nil, gcq.Dequeue()) - //fg - assert.Equal(t, true, gcq.Empty()) - assert.Equal(t, true, gcq.Full()) - assert.Equal(t, 0, gcq.Len()) - assert.Equal(t, 0, gcq.Cap()) - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.At(2)) - assert.Equal(t, nil, gcq.Front()) - assert.Equal(t, nil, gcq.Back()) - assert.Equal(t, nil, gcq.Dequeue()) - - //放入2个元素后 - gcq.Enqueue(tGOP) - gcq.Enqueue(tGOP) - assert.Equal(t, true, gcq.Empty()) - assert.Equal(t, true, gcq.Full()) - assert.Equal(t, 0, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.Front()) - assert.Equal(t, nil, gcq.Back()) - assert.Equal(t, nil, gcq.Dequeue()) -} +func TestGOPCache_Feed(t *testing.T) { -func TestGopCircularQueue(t *testing.T) { - var gcqCap int = 3 - - //元素为个数为0 - //fl,_, _, _ - gcq := NewGopCircularQueue(gcqCap) - assert.Equal(t, true, gcq.Empty()) - assert.Equal(t, false, gcq.Full()) - assert.Equal(t, 0, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - //gop := - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.Front()) - assert.Equal(t, nil, gcq.Back()) - assert.Equal(t, nil, gcq.Dequeue()) - - //fl,_, _, _ - tGOP := &GOP{ - data:[][]byte{[]byte("t")}, - } - gcq.Enqueue(tGOP) - //放入一个元素后 - //tf,l, _, _ - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, false, gcq.Full()) - assert.Equal(t, 1, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, tGOP, gcq.At(0)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, tGOP, gcq.Front()) - assert.Equal(t, tGOP, gcq.Back()) - - //在弹出一个元素后 - //tf,l, _,_ - assert.Equal(t, tGOP, gcq.Dequeue()) - //_,fl, _,_ - assert.Equal(t, true, gcq.Empty()) - assert.Equal(t, false, gcq.Full()) - assert.Equal(t, 0, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.Front()) - assert.Equal(t, nil, gcq.Back()) - assert.Equal(t, nil, gcq.Dequeue()) - - //_,fl, _,_ - GOP0 := &GOP{ - data:[][]byte{[]byte("0")}, - } - gcq.Enqueue(GOP0) - //_,f0,l_,_ - GOP1 := &GOP{ - data:[][]byte{[]byte("1")}, + i1 := rtmp.AVMsg{ + Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0}, + Payload: []byte{23, 1}, } - gcq.Enqueue(GOP1) - //_,f0, 1, l - //验证遍历情况 - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, false, gcq.Full()) - assert.Equal(t, 2, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, GOP0, gcq.At(0)) - assert.Equal(t, GOP1, gcq.At(1)) - assert.Equal(t, nil, gcq.At(2)) - assert.Equal(t, GOP0, gcq.Front()) - assert.Equal(t, GOP1, gcq.Back()) - - GOP2 := &GOP{ - data:[][]byte{[]byte("2")}, + p1 := rtmp.AVMsg{ + Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,}, + Payload: []byte{6, 0, 1}, } - gcq.Enqueue(GOP2) - //l,f0, 1, 2 - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, true, gcq.Full()) - assert.Equal(t, 3, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, GOP0, gcq.At(0)) - assert.Equal(t, GOP1, gcq.At(1)) - assert.Equal(t, GOP2, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, GOP0, gcq.Front()) - assert.Equal(t, GOP2, gcq.Back()) - - // - GOP3 := &GOP{ - data:[][]byte{[]byte("3")}, + i2 := rtmp.AVMsg{ + Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,}, + Payload: []byte{23, 1}, } - gcq.Enqueue(GOP3) - //3, l, f1, 2 - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, true, gcq.Full()) - assert.Equal(t, 3, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, GOP1, gcq.At(0)) - assert.Equal(t, GOP2, gcq.At(1)) - assert.Equal(t, GOP3, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, GOP1, gcq.Front()) - assert.Equal(t, GOP3, gcq.Back()) - - - - //3, l, f1, 2 - assert.Equal(t, GOP1, gcq.Dequeue()) - //出队后 - //3, l, _, f2 - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, false, gcq.Full()) - assert.Equal(t, 2, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, GOP2, gcq.At(0)) - assert.Equal(t, GOP3, gcq.At(1)) - assert.Equal(t, nil, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.At(4)) - assert.Equal(t, GOP2, gcq.Front()) - assert.Equal(t, GOP3, gcq.Back()) - - - - //3, l, _, f2 - GOP4 := &GOP{ - data:[][]byte{[]byte("4")}, + p2 := rtmp.AVMsg{ + Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,}, + Payload: []byte{6, 0, 2}, } - gcq.Enqueue(GOP4) - //入队后 - //3, 4, l, f2 - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, true, gcq.Full()) - assert.Equal(t, 3, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, GOP2, gcq.At(0)) - assert.Equal(t, GOP3, gcq.At(1)) - assert.Equal(t, GOP4, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.At(4)) - assert.Equal(t, GOP2, gcq.Front()) - assert.Equal(t, GOP4, gcq.Back()) - - //3, 4, l, 2f - assert.Equal(t, GOP2, gcq.Dequeue()) - //3f, 4, l, _ - - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, false, gcq.Full()) - assert.Equal(t, 2, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, GOP3, gcq.At(0)) - assert.Equal(t, GOP4, gcq.At(1)) - assert.Equal(t, nil, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.At(4)) - assert.Equal(t, GOP3, gcq.Front()) - assert.Equal(t, GOP4, gcq.Back()) - - //3f, 4, l, _ - GOP5 := &GOP{ - data:[][]byte{[]byte("5")}, + i3 := rtmp.AVMsg{ + Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,}, + Payload: []byte{23, 1}, } - gcq.Enqueue(GOP5) - //3f, 4, 5, l - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, true, gcq.Full()) - assert.Equal(t, 3, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, GOP3, gcq.At(0)) - assert.Equal(t, GOP4, gcq.At(1)) - assert.Equal(t, GOP5, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.At(4)) - assert.Equal(t, GOP3, gcq.Front()) - assert.Equal(t, GOP5, gcq.Back()) - - - - //3f, 4, 5, l - assert.Equal(t, GOP3, gcq.Dequeue()) - //_, 4f, 5, l - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, false, gcq.Full()) - assert.Equal(t, 2, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, GOP4, gcq.At(0)) - assert.Equal(t, GOP5, gcq.At(1)) - assert.Equal(t, nil, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.At(4)) - assert.Equal(t, GOP4, gcq.Front()) - assert.Equal(t, GOP5, gcq.Back()) - - //_, 4f, 5, l - assert.Equal(t, GOP4, gcq.Dequeue()) - //_, _, 5f, l - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, false, gcq.Full()) - assert.Equal(t, 1, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, GOP5, gcq.At(0)) - assert.Equal(t, nil, gcq.At(1)) - assert.Equal(t, nil, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.At(4)) - assert.Equal(t, GOP5, gcq.Front()) - assert.Equal(t, GOP5, gcq.Back()) - - //_, _, 5f, l - assert.Equal(t, GOP5, gcq.Dequeue()) - //_, _, _, fl - assert.Equal(t, true, gcq.Empty()) - assert.Equal(t, false, gcq.Full()) - assert.Equal(t, 0, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.At(1)) - assert.Equal(t, nil, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.At(4)) - assert.Equal(t, nil, gcq.Front()) - assert.Equal(t, nil, gcq.Back()) - - - //_, _, _, fl - GOP6 := &GOP{ - data:[][]byte{[]byte("6")}, + p3 := rtmp.AVMsg{ + Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,}, + Payload: []byte{6, 0, 3}, } - gcq.Enqueue(GOP6) - //l, _, _, f6 - GOP7 := &GOP{ - data:[][]byte{[]byte("7")}, + i4 := rtmp.AVMsg{ + Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,}, + Payload: []byte{23, 1}, } - gcq.Enqueue(GOP7) - //7, l, _, f6 - GOP8 := &GOP{ - data:[][]byte{[]byte("8")}, + p4 := rtmp.AVMsg{ + Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,}, + Payload: []byte{6, 0, 4}, } - gcq.Enqueue(GOP8) - //7, 8, l, f6 - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, true, gcq.Full()) - assert.Equal(t, 3, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, GOP6, gcq.At(0)) - assert.Equal(t, GOP7, gcq.At(1)) - assert.Equal(t, GOP8, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.At(4)) - assert.Equal(t, GOP6, gcq.Front()) - assert.Equal(t, GOP8, gcq.Back()) - - - GOP9 := &GOP{ - data:[][]byte{[]byte("9")}, - } - gcq.Enqueue(GOP9) - //f7, 8, 9, l - assert.Equal(t, false, gcq.Empty()) - assert.Equal(t, true, gcq.Full()) - assert.Equal(t, 3, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, GOP7, gcq.At(0)) - assert.Equal(t, GOP8, gcq.At(1)) - assert.Equal(t, GOP9, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.At(4)) - assert.Equal(t, GOP7, gcq.Front()) - assert.Equal(t, GOP9, gcq.Back()) - - //f7, 8, 9, l - assert.Equal(t, GOP7, gcq.Dequeue()) - //_, f8, 9, l - assert.Equal(t, GOP8, gcq.Dequeue()) - //_, _, f9, l - assert.Equal(t, GOP9, gcq.Dequeue()) - //_, _, _, fl - assert.Equal(t, true, gcq.Empty()) - assert.Equal(t, false, gcq.Full()) - assert.Equal(t, 0, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.At(1)) - assert.Equal(t, nil, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.At(4)) - assert.Equal(t, nil, gcq.Front()) - assert.Equal(t, nil, gcq.Back()) - - - //_, _, _, fl - assert.Equal(t, nil, gcq.Dequeue()) - //_, _, _, fl - assert.Equal(t, true, gcq.Empty()) - assert.Equal(t, false, gcq.Full()) - assert.Equal(t, 0, gcq.Len()) - assert.Equal(t, gcqCap, gcq.Cap()) - assert.Equal(t, nil, gcq.At(0)) - assert.Equal(t, nil, gcq.At(1)) - assert.Equal(t, nil, gcq.At(2)) - assert.Equal(t, nil, gcq.At(3)) - assert.Equal(t, nil, gcq.At(4)) - assert.Equal(t, nil, gcq.Front()) - assert.Equal(t, nil, gcq.Back()) + i1f := func()[]byte {return []byte{1, 1}} + p1f := func()[]byte {return []byte{0, 1}} + i2f := func()[]byte {return []byte{1, 2}} + p2f := func()[]byte {return []byte{0, 2}} + i3f := func()[]byte {return []byte{1, 3}} + p3f := func()[]byte {return []byte{0, 3}} + i4f := func()[]byte {return []byte{1, 4}} + p4f := func()[]byte {return []byte{0, 4}} + + + nc := NewGopCache("rtmp", "test", 3) + assert.Equal(t, 0, nc.GetGopLen()) + assert.Equal(t, nil, nc.GetGopDataAt(0)) + assert.Equal(t, nil, nc.GetGopDataAt(1)) + assert.Equal(t, nil, nc.GetGopDataAt(2)) + assert.Equal(t, nil, nc.GetGopDataAt(3)) + + nc.Feed(i1, i1f) + assert.Equal(t, 1, nc.GetGopLen()) + assert.Equal(t, [][]byte{{1, 1}}, nc.GetGopDataAt(0)) + assert.Equal(t, nil, nc.GetGopDataAt(1)) + assert.Equal(t, nil, nc.GetGopDataAt(2)) + assert.Equal(t, nil, nc.GetGopDataAt(3)) + nc.Feed(p1, p1f) + assert.Equal(t, 1, nc.GetGopLen()) + assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0)) + assert.Equal(t, nil, nc.GetGopDataAt(1)) + assert.Equal(t, nil, nc.GetGopDataAt(2)) + assert.Equal(t, nil, nc.GetGopDataAt(3)) + + + nc.Feed(i2, i2f) + assert.Equal(t, 2, nc.GetGopLen()) + assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0)) + assert.Equal(t, [][]byte{{1, 2}}, nc.GetGopDataAt(1)) + assert.Equal(t, nil, nc.GetGopDataAt(2)) + assert.Equal(t, nil, nc.GetGopDataAt(3)) + nc.Feed(p2, p2f) + assert.Equal(t, 2, nc.GetGopLen()) + assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0)) + assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(1)) + assert.Equal(t, nil, nc.GetGopDataAt(2)) + assert.Equal(t, nil, nc.GetGopDataAt(3)) + + nc.Feed(i3, i3f) + assert.Equal(t, 3, nc.GetGopLen()) + assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0)) + assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(1)) + assert.Equal(t, [][]byte{{1, 3}}, nc.GetGopDataAt(2)) + assert.Equal(t, nil, nc.GetGopDataAt(3)) + nc.Feed(p3, p3f) + assert.Equal(t, 3, nc.GetGopLen()) + assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0)) + assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(1)) + assert.Equal(t, [][]byte{{1, 3}, {0, 3}}, nc.GetGopDataAt(2)) + assert.Equal(t, nil, nc.GetGopDataAt(3)) + + + nc.Feed(i4, i4f) + assert.Equal(t, 3, nc.GetGopLen()) + assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(0)) + assert.Equal(t, [][]byte{{1, 3}, {0, 3}}, nc.GetGopDataAt(1)) + assert.Equal(t, [][]byte{{1, 4}}, nc.GetGopDataAt(2)) + assert.Equal(t, nil, nc.GetGopDataAt(3)) + nc.Feed(p4, p4f) + assert.Equal(t, 3, nc.GetGopLen()) + assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(0)) + assert.Equal(t, [][]byte{{1, 3}, {0, 3}}, nc.GetGopDataAt(1)) + assert.Equal(t, [][]byte{{1, 4}, {0, 4}}, nc.GetGopDataAt(2)) + assert.Equal(t, nil, nc.GetGopDataAt(3)) } diff --git a/pkg/logic/group.go b/pkg/logic/group.go index 99252a9..8547cdc 100644 --- a/pkg/logic/group.go +++ b/pkg/logic/group.go @@ -194,7 +194,7 @@ func (group *Group) broadcastRTMP(msg rtmp.AVMsg) { _ = session.AsyncWrite(group.gopCache.AACSeqHeader) } for i := 0; i < group.gopCache.GetGopLen();i++ { - for _, item := range group.gopCache.GetGopAt(i).data { + for _, item := range group.gopCache.GetGopDataAt(i) { _ = session.AsyncWrite(item) } } @@ -219,7 +219,7 @@ func (group *Group) broadcastRTMP(msg rtmp.AVMsg) { session.WriteRawPacket(group.httpflvGopCache.AACSeqHeader) } for i := 0; i < group.httpflvGopCache.GetGopLen(); i++ { - for _, item := range group.httpflvGopCache.GetGopAt(i).data { + for _, item := range group.httpflvGopCache.GetGopDataAt(i) { session.WriteRawPacket(item) } }