mirror of
https://github.com/Monibuca/engine.git
synced 2025-10-16 13:41:27 +08:00
🐛 FIX: 乱序重排需要克隆数据
This commit is contained in:
@@ -1,21 +1,28 @@
|
||||
package util
|
||||
|
||||
// RTPReorder RTP包乱序重排
|
||||
type RTPReorder[T any] struct {
|
||||
lastSeq uint16 //最新收到的rtp包序号
|
||||
queue []*T // 缓存队列,0号元素位置代表lastReq+1,永远保持为空
|
||||
type CloneType[T any] interface {
|
||||
Clone() T
|
||||
comparable
|
||||
}
|
||||
|
||||
func (p *RTPReorder[T]) Push(seq uint16, v *T) *T {
|
||||
const queueLen = 20
|
||||
|
||||
// RTPReorder RTP包乱序重排
|
||||
type RTPReorder[T CloneType[T]] struct {
|
||||
lastSeq uint16 //最新收到的rtp包序号
|
||||
queue []T // 缓存队列,0号元素位置代表lastReq+1,永远保持为空
|
||||
}
|
||||
|
||||
func (p *RTPReorder[T]) Push(seq uint16, v T) (result T) {
|
||||
// 初始化
|
||||
if len(p.queue) == 0 {
|
||||
p.lastSeq = seq
|
||||
p.queue = make([]*T, 20)
|
||||
p.queue = make([]T, 20)
|
||||
return v
|
||||
}
|
||||
if seq < p.lastSeq && p.lastSeq-seq < 0x8000 {
|
||||
// 旧的包直接丢弃
|
||||
return nil
|
||||
return
|
||||
}
|
||||
delta := seq - p.lastSeq
|
||||
if delta == 1 {
|
||||
@@ -26,7 +33,6 @@ func (p *RTPReorder[T]) Push(seq uint16, v *T) *T {
|
||||
}
|
||||
if seq > p.lastSeq {
|
||||
//delta必然大于1
|
||||
queueLen := uint16(len(p.queue))
|
||||
if queueLen < delta {
|
||||
//超过缓存最大范围,无法挽回,只能造成丢包(序号断裂)
|
||||
for {
|
||||
@@ -35,31 +41,34 @@ func (p *RTPReorder[T]) Push(seq uint16, v *T) *T {
|
||||
p.pop()
|
||||
// 可以放得进去了
|
||||
if delta == queueLen-1 {
|
||||
p.queue[queueLen-1] = v
|
||||
p.queue[queueLen-1] = v.Clone()
|
||||
v = p.queue[0]
|
||||
p.queue[0] = nil
|
||||
p.queue[0] = result
|
||||
return v
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 出现后面的包先到达,缓存起来
|
||||
p.queue[delta-1] = v
|
||||
return nil
|
||||
p.queue[delta-1] = v.Clone()
|
||||
return
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
func (p *RTPReorder[T]) pop() {
|
||||
func (p *RTPReorder[T]) pop() (result T) {
|
||||
copy(p.queue, p.queue[1:]) //整体数据向前移动一位,保持0号元素代表lastSeq+1
|
||||
p.queue[queueLen-1] = result
|
||||
return p.queue[0]
|
||||
}
|
||||
|
||||
// Pop 从缓存中取出一个包,需要连续调用直到返回nil
|
||||
func (p *RTPReorder[T]) Pop() (next *T) {
|
||||
func (p *RTPReorder[T]) Pop() (result T) {
|
||||
if len(p.queue) == 0 {
|
||||
return
|
||||
}
|
||||
if next = p.queue[0]; next != nil {
|
||||
if next := p.queue[0]; next != result {
|
||||
result = next
|
||||
p.lastSeq++
|
||||
p.pop()
|
||||
}
|
||||
|
Reference in New Issue
Block a user