mirror of
https://github.com/jech/galene.git
synced 2024-11-25 10:05:58 +01:00
Take next packet index into account when sending NACKs.
This avoids sending NACKs for packets in the future.
This commit is contained in:
parent
67a821ea75
commit
4a8e48d146
3 changed files with 38 additions and 21 deletions
|
@ -1,6 +1,7 @@
|
||||||
package packetcache
|
package packetcache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/bits"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ type Cache struct {
|
||||||
lost uint32
|
lost uint32
|
||||||
totalLost uint32
|
totalLost uint32
|
||||||
// bitmap
|
// bitmap
|
||||||
|
bitmapValid bool
|
||||||
first uint16
|
first uint16
|
||||||
bitmap uint32
|
bitmap uint32
|
||||||
// buffered keyframe
|
// buffered keyframe
|
||||||
|
@ -56,9 +58,10 @@ func seqnoInvalid(seqno, reference uint16) bool {
|
||||||
|
|
||||||
// Set a bit in the bitmap, shifting first if necessary.
|
// Set a bit in the bitmap, shifting first if necessary.
|
||||||
func (cache *Cache) set(seqno uint16) {
|
func (cache *Cache) set(seqno uint16) {
|
||||||
if cache.bitmap == 0 || seqnoInvalid(seqno, cache.first) {
|
if !cache.bitmapValid || seqnoInvalid(seqno, cache.first) {
|
||||||
cache.first = seqno
|
cache.first = seqno
|
||||||
cache.bitmap = 1
|
cache.bitmap = 1
|
||||||
|
cache.bitmapValid = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,14 +69,18 @@ func (cache *Cache) set(seqno uint16) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if seqno-cache.first < 32 {
|
if seqno-cache.first >= 32 {
|
||||||
cache.bitmap |= (1 << uint16(seqno-cache.first))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
shift := seqno - cache.first - 31
|
shift := seqno - cache.first - 31
|
||||||
cache.bitmap >>= shift
|
cache.bitmap >>= shift
|
||||||
cache.first += shift
|
cache.first += shift
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache.bitmap & 1) == 1 {
|
||||||
|
ones := bits.TrailingZeros32(^cache.bitmap)
|
||||||
|
cache.bitmap >>= ones
|
||||||
|
cache.first += uint16(ones)
|
||||||
|
}
|
||||||
|
|
||||||
cache.bitmap |= (1 << uint16(seqno-cache.first))
|
cache.bitmap |= (1 << uint16(seqno-cache.first))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -262,25 +269,34 @@ func (cache *Cache) ResizeCond(capacity int) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift 17 bits out of the bitmap. Return a boolean indicating if any
|
// Shift up to 17 bits out of the bitmap. Return a boolean indicating if
|
||||||
// were 0, the index of the first 0 bit, and a bitmap indicating any
|
// any were 0, the index of the first 0 bit, and a bitmap indicating any
|
||||||
// 0 bits after the first one.
|
// 0 bits after the first one.
|
||||||
func (cache *Cache) BitmapGet() (bool, uint16, uint16) {
|
func (cache *Cache) BitmapGet(next uint16) (bool, uint16, uint16) {
|
||||||
cache.mu.Lock()
|
cache.mu.Lock()
|
||||||
defer cache.mu.Unlock()
|
defer cache.mu.Unlock()
|
||||||
|
|
||||||
first := cache.first
|
first := cache.first
|
||||||
bitmap := (^cache.bitmap) & 0x1FFFF
|
count := next - first
|
||||||
cache.bitmap >>= 17
|
if (count&0x8000) != 0 || count == 0 {
|
||||||
cache.first += 17
|
// next is in the past
|
||||||
|
return false, first, 0
|
||||||
|
}
|
||||||
|
if count > 17 {
|
||||||
|
count = 17
|
||||||
|
}
|
||||||
|
bitmap := (^cache.bitmap) & ^((^uint32(0)) << count)
|
||||||
|
cache.bitmap >>= count
|
||||||
|
cache.first += count
|
||||||
|
|
||||||
if bitmap == 0 {
|
if bitmap == 0 {
|
||||||
return false, first, 0
|
return false, first, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
for bitmap&1 == 0 {
|
if (bitmap & 1) == 0 {
|
||||||
bitmap >>= 1
|
count := bits.TrailingZeros32(bitmap)
|
||||||
first++
|
bitmap >>= count
|
||||||
|
first += uint16(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, first, uint16(bitmap >> 1)
|
return true, first, uint16(bitmap >> 1)
|
||||||
|
|
|
@ -264,7 +264,7 @@ func TestBitmapGet(t *testing.T) {
|
||||||
|
|
||||||
pos := uint16(42)
|
pos := uint16(42)
|
||||||
for cache.bitmap != 0 {
|
for cache.bitmap != 0 {
|
||||||
found, first, bitmap := cache.BitmapGet()
|
found, first, bitmap := cache.BitmapGet(42 + 65)
|
||||||
if first < pos || first >= pos+64 {
|
if first < pos || first >= pos+64 {
|
||||||
t.Errorf("First is %v, pos is %v", first, pos)
|
t.Errorf("First is %v, pos is %v", first, pos)
|
||||||
}
|
}
|
||||||
|
@ -304,7 +304,7 @@ func TestBitmapPacket(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
found, first, bitmap := cache.BitmapGet()
|
found, first, bitmap := cache.BitmapGet(42 + 65)
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
t.Fatalf("Didn't find any 0 bits")
|
t.Fatalf("Didn't find any 0 bits")
|
||||||
|
|
|
@ -61,7 +61,8 @@ func readLoop(conn *rtpUpConnection, track *rtpUpTrack) {
|
||||||
packet.SequenceNumber, packet.Timestamp, kf, buf[:bytes],
|
packet.SequenceNumber, packet.Timestamp, kf, buf[:bytes],
|
||||||
)
|
)
|
||||||
if packet.SequenceNumber-first > 24 {
|
if packet.SequenceNumber-first > 24 {
|
||||||
found, first, bitmap := track.cache.BitmapGet()
|
found, first, bitmap :=
|
||||||
|
track.cache.BitmapGet(packet.SequenceNumber - 4)
|
||||||
if found {
|
if found {
|
||||||
err := conn.sendNACK(track, first, bitmap)
|
err := conn.sendNACK(track, first, bitmap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue