[refactor]:将环形队列结构删除,将环形队列逻辑写在GOgop_cache中

pull/8/head
liquanqing 5 years ago committed by yoko
parent c93237e29f
commit 3d8c1c3d58

@ -58,14 +58,20 @@ type GOPCache struct {
Metadata []byte Metadata []byte
VideoSeqHeader []byte VideoSeqHeader []byte
AACSeqHeader []byte AACSeqHeader []byte
gopCircularQue *gopCircularQueue gopRing []GOP
gopRingFirst int
gopRingLast int
gopSize int
} }
func NewGopCache(t string, uniqueKey string, gopNum int) *GOPCache { func NewGopCache(t string, uniqueKey string, gopNum int) *GOPCache {
return &GOPCache{ return &GOPCache{
t: t, t: t,
uniqueKey: uniqueKey, 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 return
} }
} }
if gc.gopCircularQue.Cap() != 0 {
if gc.gopSize > 1 {
if msg.IsVideoKeyNalu() { if msg.IsVideoKeyNalu() {
var gop *GOP gc.gopRing[gc.gopRingLast].Clear()
if gc.gopCircularQue.Full() { gc.gopRing[gc.gopRingLast].Feed(msg, lg())
//如果已经满了获取队首即将被淘汰的GOP gc.gopRingLast = (gc.gopRingLast + 1) % gc.gopSize
gop = gc.gopCircularQue.Front() if gc.gopRingLast == gc.gopRingFirst {
gop.Clear() gc.gopRingFirst = (gc.gopRingFirst + 1) % gc.gopSize
} else {
gop = &GOP{}
} }
gop.Feed(msg, lg())
gc.gopCircularQue.Enqueue(gop)
} else { } else {
gop := gc.gopCircularQue.Back() if gc.gopRingLast != gc.gopRingFirst {
if gop != nil { gc.gopRing[(gc.gopRingLast - 1 + gc.gopSize) % gc.gopSize].Feed(msg, lg())
gop.Feed(msg, lg())
} }
} }
} }
} }
func (gc *GOPCache) GetGopLen() int{ 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 { func (gc *GOPCache) GetGopDataAt(pos int) [][]byte {
return gc.gopCircularQue.At(pos) if pos >= gc.GetGopLen() || pos < 0 {
return nil
}
return gc.gopRing[(pos + gc.gopRingFirst) % gc.gopSize].data
} }
func (gc *GOPCache) LastGOP() *GOP { 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() { func (gc *GOPCache) Clear() {
gc.Metadata = nil gc.Metadata = nil
gc.VideoSeqHeader = nil gc.VideoSeqHeader = nil
gc.AACSeqHeader = nil gc.AACSeqHeader = nil
gc.gopCircularQue.Clear() gc.gopRingLast = 0
gc.gopRingFirst = 0
} }
type GOP struct { type GOP struct {
@ -141,102 +150,3 @@ func (g *GOP) Feed(msg rtmp.AVMsg, b []byte) {
func (g *GOP) Clear() { func (g *GOP) Clear() {
g.data = g.data[:0] 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
}

@ -1,371 +1,113 @@
package logic package logic
import ( import (
`github.com/q191201771/naza/pkg/assert` "github.com/q191201771/lal/pkg/rtmp"
`testing` "github.com/q191201771/naza/pkg/assert"
"testing"
) )
func TestGopCircularQueueCap0(t *testing.T) { func TestGOPCache_Feed(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 TestGopCircularQueue(t *testing.T) { i1 := rtmp.AVMsg{
var gcqCap int = 3 Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0},
Payload: []byte{23, 1},
//元素为个数为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")},
} }
gcq.Enqueue(GOP1) p1 := rtmp.AVMsg{
//_,f0, 1, l Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,},
//验证遍历情况 Payload: []byte{6, 0, 1},
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")},
} }
gcq.Enqueue(GOP2) i2 := rtmp.AVMsg{
//l,f0, 1, 2 Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,},
assert.Equal(t, false, gcq.Empty()) Payload: []byte{23, 1},
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")},
} }
gcq.Enqueue(GOP3) p2 := rtmp.AVMsg{
//3, l, f1, 2 Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,},
assert.Equal(t, false, gcq.Empty()) Payload: []byte{6, 0, 2},
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")},
} }
gcq.Enqueue(GOP4) i3 := rtmp.AVMsg{
//入队后 Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,},
//3, 4, l, f2 Payload: []byte{23, 1},
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")},
} }
gcq.Enqueue(GOP5) p3 := rtmp.AVMsg{
//3f, 4, 5, l Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,},
assert.Equal(t, false, gcq.Empty()) Payload: []byte{6, 0, 3},
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")},
} }
gcq.Enqueue(GOP6) i4 := rtmp.AVMsg{
//l, _, _, f6 Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,},
GOP7 := &GOP{ Payload: []byte{23, 1},
data:[][]byte{[]byte("7")},
} }
gcq.Enqueue(GOP7) p4 := rtmp.AVMsg{
//7, l, _, f6 Header: rtmp.Header{CSID: 0, MsgLen: 0, Timestamp: 1, MsgTypeID: 9, MsgStreamID: 10, TimestampAbs: 0,},
GOP8 := &GOP{ Payload: []byte{6, 0, 4},
data:[][]byte{[]byte("8")},
} }
gcq.Enqueue(GOP8) i1f := func()[]byte {return []byte{1, 1}}
//7, 8, l, f6 p1f := func()[]byte {return []byte{0, 1}}
assert.Equal(t, false, gcq.Empty()) i2f := func()[]byte {return []byte{1, 2}}
assert.Equal(t, true, gcq.Full()) p2f := func()[]byte {return []byte{0, 2}}
assert.Equal(t, 3, gcq.Len()) i3f := func()[]byte {return []byte{1, 3}}
assert.Equal(t, gcqCap, gcq.Cap()) p3f := func()[]byte {return []byte{0, 3}}
assert.Equal(t, GOP6, gcq.At(0)) i4f := func()[]byte {return []byte{1, 4}}
assert.Equal(t, GOP7, gcq.At(1)) p4f := func()[]byte {return []byte{0, 4}}
assert.Equal(t, GOP8, gcq.At(2))
assert.Equal(t, nil, gcq.At(3))
assert.Equal(t, nil, gcq.At(4)) nc := NewGopCache("rtmp", "test", 3)
assert.Equal(t, GOP6, gcq.Front()) assert.Equal(t, 0, nc.GetGopLen())
assert.Equal(t, GOP8, gcq.Back()) assert.Equal(t, nil, nc.GetGopDataAt(0))
assert.Equal(t, nil, nc.GetGopDataAt(1))
assert.Equal(t, nil, nc.GetGopDataAt(2))
GOP9 := &GOP{ assert.Equal(t, nil, nc.GetGopDataAt(3))
data:[][]byte{[]byte("9")},
} nc.Feed(i1, i1f)
gcq.Enqueue(GOP9) assert.Equal(t, 1, nc.GetGopLen())
//f7, 8, 9, l assert.Equal(t, [][]byte{{1, 1}}, nc.GetGopDataAt(0))
assert.Equal(t, false, gcq.Empty()) assert.Equal(t, nil, nc.GetGopDataAt(1))
assert.Equal(t, true, gcq.Full()) assert.Equal(t, nil, nc.GetGopDataAt(2))
assert.Equal(t, 3, gcq.Len()) assert.Equal(t, nil, nc.GetGopDataAt(3))
assert.Equal(t, gcqCap, gcq.Cap()) nc.Feed(p1, p1f)
assert.Equal(t, GOP7, gcq.At(0)) assert.Equal(t, 1, nc.GetGopLen())
assert.Equal(t, GOP8, gcq.At(1)) assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0))
assert.Equal(t, GOP9, gcq.At(2)) assert.Equal(t, nil, nc.GetGopDataAt(1))
assert.Equal(t, nil, gcq.At(3)) assert.Equal(t, nil, nc.GetGopDataAt(2))
assert.Equal(t, nil, gcq.At(4)) assert.Equal(t, nil, nc.GetGopDataAt(3))
assert.Equal(t, GOP7, gcq.Front())
assert.Equal(t, GOP9, gcq.Back())
nc.Feed(i2, i2f)
//f7, 8, 9, l assert.Equal(t, 2, nc.GetGopLen())
assert.Equal(t, GOP7, gcq.Dequeue()) assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0))
//_, f8, 9, l assert.Equal(t, [][]byte{{1, 2}}, nc.GetGopDataAt(1))
assert.Equal(t, GOP8, gcq.Dequeue()) assert.Equal(t, nil, nc.GetGopDataAt(2))
//_, _, f9, l assert.Equal(t, nil, nc.GetGopDataAt(3))
assert.Equal(t, GOP9, gcq.Dequeue()) nc.Feed(p2, p2f)
//_, _, _, fl assert.Equal(t, 2, nc.GetGopLen())
assert.Equal(t, true, gcq.Empty()) assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0))
assert.Equal(t, false, gcq.Full()) assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(1))
assert.Equal(t, 0, gcq.Len()) assert.Equal(t, nil, nc.GetGopDataAt(2))
assert.Equal(t, gcqCap, gcq.Cap()) assert.Equal(t, nil, nc.GetGopDataAt(3))
assert.Equal(t, nil, gcq.At(0))
assert.Equal(t, nil, gcq.At(1)) nc.Feed(i3, i3f)
assert.Equal(t, nil, gcq.At(2)) assert.Equal(t, 3, nc.GetGopLen())
assert.Equal(t, nil, gcq.At(3)) assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0))
assert.Equal(t, nil, gcq.At(4)) assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(1))
assert.Equal(t, nil, gcq.Front()) assert.Equal(t, [][]byte{{1, 3}}, nc.GetGopDataAt(2))
assert.Equal(t, nil, gcq.Back()) assert.Equal(t, nil, nc.GetGopDataAt(3))
nc.Feed(p3, p3f)
assert.Equal(t, 3, nc.GetGopLen())
//_, _, _, fl assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0))
assert.Equal(t, nil, gcq.Dequeue()) assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(1))
//_, _, _, fl assert.Equal(t, [][]byte{{1, 3}, {0, 3}}, nc.GetGopDataAt(2))
assert.Equal(t, true, gcq.Empty()) assert.Equal(t, nil, nc.GetGopDataAt(3))
assert.Equal(t, false, gcq.Full())
assert.Equal(t, 0, gcq.Len())
assert.Equal(t, gcqCap, gcq.Cap()) nc.Feed(i4, i4f)
assert.Equal(t, nil, gcq.At(0)) assert.Equal(t, 3, nc.GetGopLen())
assert.Equal(t, nil, gcq.At(1)) assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(0))
assert.Equal(t, nil, gcq.At(2)) assert.Equal(t, [][]byte{{1, 3}, {0, 3}}, nc.GetGopDataAt(1))
assert.Equal(t, nil, gcq.At(3)) assert.Equal(t, [][]byte{{1, 4}}, nc.GetGopDataAt(2))
assert.Equal(t, nil, gcq.At(4)) assert.Equal(t, nil, nc.GetGopDataAt(3))
assert.Equal(t, nil, gcq.Front()) nc.Feed(p4, p4f)
assert.Equal(t, nil, gcq.Back()) 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))
} }

@ -194,7 +194,7 @@ func (group *Group) broadcastRTMP(msg rtmp.AVMsg) {
_ = session.AsyncWrite(group.gopCache.AACSeqHeader) _ = session.AsyncWrite(group.gopCache.AACSeqHeader)
} }
for i := 0; i < group.gopCache.GetGopLen();i++ { 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) _ = session.AsyncWrite(item)
} }
} }
@ -219,7 +219,7 @@ func (group *Group) broadcastRTMP(msg rtmp.AVMsg) {
session.WriteRawPacket(group.httpflvGopCache.AACSeqHeader) session.WriteRawPacket(group.httpflvGopCache.AACSeqHeader)
} }
for i := 0; i < group.httpflvGopCache.GetGopLen(); i++ { 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) session.WriteRawPacket(item)
} }
} }

Loading…
Cancel
Save