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

@ -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))
}

@ -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)
}
}

Loading…
Cancel
Save