rtptimedec: increase threshold of negative differences

This commit is contained in:
aler9
2022-10-26 16:53:27 +02:00
parent 7d8e3cf5bc
commit 87e9036976
2 changed files with 20 additions and 20 deletions

View File

@@ -5,14 +5,14 @@ import (
"time" "time"
) )
const negativeThreshold = 0xFFFFFFF const negativeThreshold = 0xFFFFFFFF / 2
// Decoder is a RTP timestamp decoder. // Decoder is a RTP timestamp decoder.
type Decoder struct { type Decoder struct {
clockRate time.Duration clockRate time.Duration
initialized bool initialized bool
tsOverall time.Duration overall time.Duration
tsPrev uint32 prev uint32
} }
// New allocates a Decoder. // New allocates a Decoder.
@@ -26,25 +26,25 @@ func New(clockRate int) *Decoder {
func (d *Decoder) Decode(ts uint32) time.Duration { func (d *Decoder) Decode(ts uint32) time.Duration {
if !d.initialized { if !d.initialized {
d.initialized = true d.initialized = true
d.tsPrev = ts d.prev = ts
return 0 return 0
} }
diff := ts - d.tsPrev diff := ts - d.prev
// negative difference // negative difference
if diff > negativeThreshold { if diff > negativeThreshold {
diff = d.tsPrev - ts diff = d.prev - ts
d.tsPrev = ts d.prev = ts
d.tsOverall -= time.Duration(diff) d.overall -= time.Duration(diff)
} else { } else {
d.tsPrev = ts d.prev = ts
d.tsOverall += time.Duration(diff) d.overall += time.Duration(diff)
} }
// avoid an int64 overflow and preserve resolution by splitting division into two parts: // avoid an int64 overflow and keep resolution by splitting division into two parts:
// first add the integer part, then the decimal part. // first add the integer part, then the decimal part.
secs := d.tsOverall / d.clockRate secs := d.overall / d.clockRate
dec := d.tsOverall % d.clockRate dec := d.overall % d.clockRate
return secs*time.Second + dec*time.Second/d.clockRate return secs*time.Second + dec*time.Second/d.clockRate
} }

View File

@@ -30,13 +30,13 @@ func TestNegativeDiff(t *testing.T) {
func TestOverflow(t *testing.T) { func TestOverflow(t *testing.T) {
d := New(90000) d := New(90000)
i := uint32(4294877296) i := uint32(0xFFFFFFFF - 90000 + 1)
secs := time.Duration(0) secs := time.Duration(0)
pts := d.Decode(i) pts := d.Decode(i)
require.Equal(t, time.Duration(0), pts) require.Equal(t, time.Duration(0), pts)
const stride = 150 const stride = 1500
lim := uint32(uint64(4294967296 - (stride * 90000))) lim := uint32(uint64(0xFFFFFFFF + 1 - (stride * 90000)))
for n := 0; n < 100; n++ { for n := 0; n < 100; n++ {
// overflow // overflow
@@ -59,19 +59,19 @@ func TestOverflow(t *testing.T) {
func TestOverflowAndBack(t *testing.T) { func TestOverflowAndBack(t *testing.T) {
d := New(90000) d := New(90000)
pts := d.Decode(4294877296) pts := d.Decode(0xFFFFFFFF - 90000 + 1)
require.Equal(t, time.Duration(0), pts) require.Equal(t, time.Duration(0), pts)
pts = d.Decode(90000) pts = d.Decode(90000)
require.Equal(t, 2*time.Second, pts) require.Equal(t, 2*time.Second, pts)
pts = d.Decode(4294877296) pts = d.Decode(0xFFFFFFFF - 90000 + 1)
require.Equal(t, time.Duration(0), pts) require.Equal(t, time.Duration(0), pts)
pts = d.Decode(4294877296 - 90000) pts = d.Decode(0xFFFFFFFF - 90000 + 1 - 90000)
require.Equal(t, -1*time.Second, pts) require.Equal(t, -1*time.Second, pts)
pts = d.Decode(4294877296) pts = d.Decode(0xFFFFFFFF - 90000 + 1)
require.Equal(t, time.Duration(0), pts) require.Equal(t, time.Duration(0), pts)
pts = d.Decode(90000) pts = d.Decode(90000)