mirror of
https://github.com/pion/webrtc.git
synced 2025-10-05 15:16:52 +08:00

Many corner cases would cause samplebuilder to fail and return invalid results. This refactoring is more reliable in all cases. Fixed bug in H264 writer by reusing the packet object in H264 writer.
83 lines
1.7 KiB
Go
83 lines
1.7 KiB
Go
// Package samplebuilder provides functionality to reconstruct media frames from RTP packets.
|
|
package samplebuilder
|
|
|
|
import "math"
|
|
|
|
type sampleSequenceLocation struct {
|
|
// head is the first packet in a sequence
|
|
head uint16
|
|
// tail is always set to one after the final sequence number,
|
|
// so if head == tail then the sequence is empty
|
|
tail uint16
|
|
}
|
|
|
|
func (l sampleSequenceLocation) empty() bool {
|
|
return l.head == l.tail
|
|
}
|
|
|
|
func (l sampleSequenceLocation) hasData() bool {
|
|
return l.head != l.tail
|
|
}
|
|
|
|
func (l sampleSequenceLocation) count() uint16 {
|
|
return seqnumDistance(l.head, l.tail)
|
|
}
|
|
|
|
const (
|
|
slCompareVoid = iota
|
|
slCompareBefore
|
|
slCompareInside
|
|
slCompareAfter
|
|
)
|
|
|
|
func minUint32(x, y uint32) uint32 {
|
|
if x < y {
|
|
return x
|
|
}
|
|
return y
|
|
}
|
|
|
|
// Distance between two seqnums
|
|
func seqnumDistance32(x, y uint32) uint32 {
|
|
diff := int32(x - y)
|
|
if diff < 0 {
|
|
return uint32(-diff)
|
|
}
|
|
|
|
return uint32(diff)
|
|
}
|
|
|
|
func (l sampleSequenceLocation) compare(pos uint16) int {
|
|
if l.empty() {
|
|
return slCompareVoid
|
|
}
|
|
|
|
head32 := uint32(l.head)
|
|
count32 := uint32(l.count())
|
|
tail32 := head32 + count32
|
|
|
|
// pos32 is possibly two values, the normal value or a wrap
|
|
// around the start value, figure out which it is...
|
|
|
|
pos32Normal := uint32(pos)
|
|
pos32Wrap := uint32(pos) + math.MaxUint16 + 1
|
|
|
|
distNormal := minUint32(seqnumDistance32(head32, pos32Normal), seqnumDistance32(tail32, pos32Normal))
|
|
distWrap := minUint32(seqnumDistance32(head32, pos32Wrap), seqnumDistance32(tail32, pos32Wrap))
|
|
|
|
pos32 := pos32Normal
|
|
if distWrap < distNormal {
|
|
pos32 = pos32Wrap
|
|
}
|
|
|
|
if pos32 < head32 {
|
|
return slCompareBefore
|
|
}
|
|
|
|
if pos32 >= tail32 {
|
|
return slCompareAfter
|
|
}
|
|
|
|
return slCompareInside
|
|
}
|