mirror of
https://github.com/aler9/gortsplib
synced 2025-10-04 14:52:46 +08:00
change rtptime.Encoder signature and initialize time to a random value (#525)
This commit is contained in:
@@ -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 {
|
||||
|
@@ -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))
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user