change rtptime.Encoder signature and initialize time to a random value (#525)

This commit is contained in:
Alessandro Ros
2024-02-25 23:25:44 +01:00
committed by GitHub
parent f040e20ac4
commit ce46aee084
3 changed files with 60 additions and 19 deletions

View File

@@ -45,7 +45,11 @@ func main() {
}
// setup timestamp generator
rtpTime := rtptime.NewEncoder(forma.ClockRate(), 0)
rtpTime := &rtptime.Encoder{ClockRate: forma.ClockRate()}
err = rtpTime.Initialize()
if err != nil {
panic(err)
}
start := time.Now()
// setup a ticker to sleep between frames
@@ -89,7 +93,7 @@ func main() {
}
// get current timestamp
ts := rtpTime.Encode(time.Now().Sub(start))
ts := rtpTime.Encode(time.Since(start))
// write packets to the server
for _, pkt := range pkts {

View File

@@ -1,6 +1,7 @@
package rtptime
import (
"crypto/rand"
"time"
)
@@ -12,23 +13,47 @@ func divCeil(n, d uint64) uint64 {
return v
}
// Encoder is a RTP timestamp encoder.
type Encoder struct {
clockRate time.Duration
initialTimestamp time.Duration
func randUint32() (uint32, error) {
var b [4]byte
_, err := rand.Read(b[:])
if err != nil {
return 0, err
}
return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]), nil
}
// NewEncoder allocates an Encoder.
func NewEncoder(clockRate int, initialTimestamp uint32) *Encoder {
return &Encoder{
clockRate: time.Duration(clockRate),
// ((2^32) * 1000000000) is less than 2^63
initialTimestamp: time.Duration(divCeil(uint64(initialTimestamp)*uint64(time.Second), uint64(clockRate))),
// Encoder is a RTP timestamp encoder.
type Encoder struct {
// Clock rate.
ClockRate int
// (optional) initial timestamp.
// It defaults to a random value.
InitialTimestamp *uint32
clockRateTD time.Duration
initialTimestampTD time.Duration
}
// Initialize initializes an Encoder.
func (e *Encoder) Initialize() error {
e.clockRateTD = time.Duration(e.ClockRate)
if e.InitialTimestamp == nil {
v, err := randUint32()
if err != nil {
return err
}
e.InitialTimestamp = &v
}
e.initialTimestampTD = time.Duration(divCeil(uint64(*e.InitialTimestamp)*uint64(time.Second), uint64(e.ClockRate)))
return nil
}
// Encode encodes a timestamp.
func (e *Encoder) Encode(ts time.Duration) uint32 {
ts = e.initialTimestamp + ts
return uint32(multiplyAndDivide(ts, e.clockRate, time.Second))
ts += e.initialTimestampTD
return uint32(multiplyAndDivide(ts, e.clockRateTD, time.Second))
}

View File

@@ -7,8 +7,17 @@ import (
"github.com/stretchr/testify/require"
)
func uint32Ptr(v uint32) *uint32 {
return &v
}
func TestEncoder(t *testing.T) {
e := NewEncoder(90000, 12345)
e := &Encoder{
ClockRate: 90000,
InitialTimestamp: uint32Ptr(12345),
}
err := e.Initialize()
require.NoError(t, err)
ts := e.Encode(0)
require.Equal(t, uint32(12345), ts)
@@ -18,10 +27,13 @@ func TestEncoder(t *testing.T) {
}
func BenchmarkEncoder(b *testing.B) {
e := &Encoder{
ClockRate: 90000,
InitialTimestamp: uint32Ptr(12345),
}
e.Initialize() //nolint:errcheck
for i := 0; i < b.N; i++ {
func() {
d := NewEncoder(90000, 0)
d.Encode(200 * time.Second)
}()
e.Encode(200 * time.Second)
}
}