mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 07:06:58 +08:00
@@ -943,7 +943,7 @@ func (c *Client) do(req *base.Request, skipResponse bool, allowFrames bool) (*ba
|
|||||||
c.session = sx.Session
|
c.session = sx.Session
|
||||||
|
|
||||||
if sx.Timeout != nil && *sx.Timeout > 0 {
|
if sx.Timeout != nil && *sx.Timeout > 0 {
|
||||||
c.keepalivePeriod = time.Duration(float64(*sx.Timeout)*0.8) * time.Second
|
c.keepalivePeriod = time.Duration(((*sx.Timeout)*10)/8) * time.Second
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,6 +7,14 @@ import (
|
|||||||
|
|
||||||
const negativeThreshold = 0xFFFFFFFF / 2
|
const negativeThreshold = 0xFFFFFFFF / 2
|
||||||
|
|
||||||
|
// avoid an int64 overflow and preserve resolution by splitting division into two parts:
|
||||||
|
// first add the integer part, then the decimal part.
|
||||||
|
func multiplyAndDivide(v, m, d time.Duration) time.Duration {
|
||||||
|
secs := v / d
|
||||||
|
dec := v % d
|
||||||
|
return (secs*m + dec*m/d)
|
||||||
|
}
|
||||||
|
|
||||||
// Decoder is a RTP timestamp decoder.
|
// Decoder is a RTP timestamp decoder.
|
||||||
type Decoder struct {
|
type Decoder struct {
|
||||||
clockRate time.Duration
|
clockRate time.Duration
|
||||||
@@ -42,9 +50,5 @@ func (d *Decoder) Decode(ts uint32) time.Duration {
|
|||||||
d.overall += time.Duration(diff)
|
d.overall += time.Duration(diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
// avoid an int64 overflow and preserve resolution by splitting division into two parts:
|
return multiplyAndDivide(d.overall, time.Second, d.clockRate)
|
||||||
// first add the integer part, then the decimal part.
|
|
||||||
secs := d.overall / d.clockRate
|
|
||||||
dec := d.overall % d.clockRate
|
|
||||||
return secs*time.Second + dec*time.Second/d.clockRate
|
|
||||||
}
|
}
|
||||||
|
@@ -1,25 +1,34 @@
|
|||||||
package rtptime
|
package rtptime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func divCeil(n, d uint64) uint64 {
|
||||||
|
v := n / d
|
||||||
|
if (n % d) != 0 {
|
||||||
|
v++
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
// Encoder is a RTP timestamp encoder.
|
// Encoder is a RTP timestamp encoder.
|
||||||
type Encoder struct {
|
type Encoder struct {
|
||||||
clockRate float64
|
clockRate time.Duration
|
||||||
initialTimestamp time.Duration
|
initialTimestamp time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEncoder allocates an Encoder.
|
// NewEncoder allocates an Encoder.
|
||||||
func NewEncoder(clockRate int, initialTimestamp uint32) *Encoder {
|
func NewEncoder(clockRate int, initialTimestamp uint32) *Encoder {
|
||||||
return &Encoder{
|
return &Encoder{
|
||||||
clockRate: float64(clockRate),
|
clockRate: time.Duration(clockRate),
|
||||||
initialTimestamp: time.Duration(math.Ceil(float64(initialTimestamp) * float64(time.Second) / float64(clockRate))),
|
// ((2^32) * 1000000000) is less than 2^63
|
||||||
|
initialTimestamp: time.Duration(divCeil(uint64(initialTimestamp)*uint64(time.Second), uint64(clockRate))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode encodes a timestamp.
|
// Encode encodes a timestamp.
|
||||||
func (e *Encoder) Encode(ts time.Duration) uint32 {
|
func (e *Encoder) Encode(ts time.Duration) uint32 {
|
||||||
return uint32((e.initialTimestamp + ts).Seconds() * e.clockRate)
|
ts = e.initialTimestamp + ts
|
||||||
|
return uint32(multiplyAndDivide(ts, e.clockRate, time.Second))
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,9 @@ func TestEncoder(t *testing.T) {
|
|||||||
|
|
||||||
ts := e.Encode(0)
|
ts := e.Encode(0)
|
||||||
require.Equal(t, uint32(12345), ts)
|
require.Equal(t, uint32(12345), ts)
|
||||||
|
|
||||||
|
ts = e.Encode(3 * time.Second / 2)
|
||||||
|
require.Equal(t, uint32(12345+135000), ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkEncoder(b *testing.B) {
|
func BenchmarkEncoder(b *testing.B) {
|
||||||
|
Reference in New Issue
Block a user